...

Source file src/github.com/golang/geo/s2/example_test.go

Documentation: github.com/golang/geo/s2

     1  // Copyright 2018 Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package s2_test
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/golang/geo/s1"
    21  	"github.com/golang/geo/s2"
    22  )
    23  
    24  func ExampleRect_DistanceToLatLng() {
    25  	r := s2.RectFromLatLng(s2.LatLngFromDegrees(-1, -1)).AddPoint(s2.LatLngFromDegrees(1, 1))
    26  
    27  	printDist := func(lat, lng float64) {
    28  		fmt.Printf("%f\n", r.DistanceToLatLng(s2.LatLngFromDegrees(lat, lng))/s1.Degree)
    29  	}
    30  
    31  	fmt.Println("Distances next to the rectangle.")
    32  	printDist(-2, 0)
    33  	printDist(0, -2)
    34  	printDist(2, 0)
    35  	printDist(0, 2)
    36  
    37  	fmt.Println("Distances beyond the corners of the rectangle.")
    38  	printDist(-2, -2)
    39  	printDist(-2, 2)
    40  	printDist(2, 2)
    41  	printDist(2, -2)
    42  
    43  	fmt.Println("Distance within the rectangle.")
    44  	printDist(0, 0)
    45  	printDist(0.5, 0)
    46  	printDist(0, 0.5)
    47  	printDist(-0.5, 0)
    48  	printDist(0, -0.5)
    49  
    50  	// Output:
    51  	// Distances next to the rectangle.
    52  	// 1.000000
    53  	// 1.000000
    54  	// 1.000000
    55  	// 1.000000
    56  	// Distances beyond the corners of the rectangle.
    57  	// 1.413962
    58  	// 1.413962
    59  	// 1.413962
    60  	// 1.413962
    61  	// Distance within the rectangle.
    62  	// 0.000000
    63  	// 0.000000
    64  	// 0.000000
    65  	// 0.000000
    66  	// 0.000000
    67  }
    68  
    69  func ExamplePolygonFromOrientedLoops() {
    70  	// Let's define three loops, in format World Geodetic System 1984,
    71  	// the format that geoJSON uses. The third loop is a hole in the second,
    72  	// the first loop is remote from the others. Loops 1 and 2 are counter-clockwise,
    73  	// while loop 3 is clockwise.
    74  	l1 := [][]float64{
    75  		{102.0, 2.0},
    76  		{103.0, 2.0},
    77  		{103.0, 3.0},
    78  		{102.0, 3.0},
    79  	}
    80  	l2 := [][]float64{
    81  		{100.0, 0.0},
    82  		{101.0, 0.0},
    83  		{101.0, 1.0},
    84  		{100.0, 1.0},
    85  	}
    86  	l3 := [][]float64{
    87  		{100.2, 0.2},
    88  		{100.2, 0.8},
    89  		{100.8, 0.8},
    90  		{100.8, 0.2},
    91  	}
    92  	toLoop := func(points [][]float64) *s2.Loop {
    93  		var pts []s2.Point
    94  		for _, pt := range points {
    95  			pts = append(pts, s2.PointFromLatLng(s2.LatLngFromDegrees(pt[1], pt[0])))
    96  		}
    97  		return s2.LoopFromPoints(pts)
    98  	}
    99  	// We can combine all loops into a single polygon:
   100  	p := s2.PolygonFromOrientedLoops([]*s2.Loop{toLoop(l1), toLoop(l2), toLoop(l3)})
   101  
   102  	for i, loop := range p.Loops() {
   103  		fmt.Printf("loop %d is hole: %t\n", i, loop.IsHole())
   104  	}
   105  	fmt.Printf("Combined area: %.7f\n", p.Area())
   106  
   107  	// Note how the area of the polygon is the area of l1 + l2 - invert(l3), because l3 is a hole:
   108  	p12 := s2.PolygonFromOrientedLoops([]*s2.Loop{toLoop(l1), toLoop(l2)})
   109  	p3 := s2.PolygonFromOrientedLoops([]*s2.Loop{toLoop(l3)})
   110  	p3.Invert()
   111  	fmt.Printf("l1+l2 = %.7f, inv(l3) = %.7f; l1+l2 - inv(l3) = %.7f\n", p12.Area(), p3.Area(), p12.Area()-p3.Area())
   112  	// Output:
   113  	// loop 0 is hole: false
   114  	// loop 1 is hole: false
   115  	// loop 2 is hole: true
   116  	// Combined area: 0.0004993
   117  	// l1+l2 = 0.0006089, inv(l3) = 0.0001097; l1+l2 - inv(l3) = 0.0004993
   118  }
   119  
   120  func ExampleEdgeQuery_FindEdges_findClosestEdges() {
   121  	// Let's start with one or more Polylines that we wish to compare against.
   122  	polylines := []s2.Polyline{
   123  		// This is an iteration = 3 Koch snowflake centered at the
   124  		// center of the continental US.
   125  		s2.Polyline{
   126  			s2.PointFromLatLng(s2.LatLngFromDegrees(47.5467, -103.6035)),
   127  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.9214, -103.7320)),
   128  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.1527, -105.8000)),
   129  			s2.PointFromLatLng(s2.LatLngFromDegrees(44.2866, -103.8538)),
   130  			s2.PointFromLatLng(s2.LatLngFromDegrees(42.6450, -103.9695)),
   131  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.8743, -105.9314)),
   132  			s2.PointFromLatLng(s2.LatLngFromDegrees(42.7141, -107.8226)),
   133  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.0743, -107.8377)),
   134  			s2.PointFromLatLng(s2.LatLngFromDegrees(40.2486, -109.6869)),
   135  			s2.PointFromLatLng(s2.LatLngFromDegrees(39.4333, -107.8521)),
   136  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.7936, -107.8658)),
   137  			s2.PointFromLatLng(s2.LatLngFromDegrees(38.5849, -106.0503)),
   138  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.7058, -104.2841)),
   139  			s2.PointFromLatLng(s2.LatLngFromDegrees(36.0638, -104.3793)),
   140  			s2.PointFromLatLng(s2.LatLngFromDegrees(35.3062, -106.1585)),
   141  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.4284, -104.4703)),
   142  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.8024, -104.5573)),
   143  			s2.PointFromLatLng(s2.LatLngFromDegrees(33.5273, -102.8163)),
   144  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.6053, -101.1982)),
   145  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.2313, -101.0361)),
   146  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.9120, -99.2189)),
   147  			s2.PointFromLatLng(s2.LatLngFromDegrees(33.9382, -97.6134)),
   148  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.3185, -97.8489)),
   149  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.9481, -96.0510)),
   150  			s2.PointFromLatLng(s2.LatLngFromDegrees(31.9449, -94.5321)),
   151  			s2.PointFromLatLng(s2.LatLngFromDegrees(33.5521, -94.2263)),
   152  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.1285, -92.3780)),
   153  			s2.PointFromLatLng(s2.LatLngFromDegrees(35.1678, -93.9070)),
   154  			s2.PointFromLatLng(s2.LatLngFromDegrees(36.7893, -93.5734)),
   155  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.3529, -91.6381)),
   156  			s2.PointFromLatLng(s2.LatLngFromDegrees(36.2777, -90.1050)),
   157  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.8824, -89.6824)),
   158  			s2.PointFromLatLng(s2.LatLngFromDegrees(38.3764, -87.7108)),
   159  			s2.PointFromLatLng(s2.LatLngFromDegrees(39.4869, -89.2407)),
   160  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.0883, -88.7784)),
   161  			s2.PointFromLatLng(s2.LatLngFromDegrees(40.5829, -90.8289)),
   162  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.6608, -92.4765)),
   163  			s2.PointFromLatLng(s2.LatLngFromDegrees(43.2777, -92.0749)),
   164  			s2.PointFromLatLng(s2.LatLngFromDegrees(43.7961, -89.9408)),
   165  			s2.PointFromLatLng(s2.LatLngFromDegrees(44.8865, -91.6533)),
   166  			s2.PointFromLatLng(s2.LatLngFromDegrees(46.4844, -91.2100)),
   167  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.9512, -93.4327)),
   168  			s2.PointFromLatLng(s2.LatLngFromDegrees(46.9863, -95.2792)),
   169  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.3722, -95.6237)),
   170  			s2.PointFromLatLng(s2.LatLngFromDegrees(44.7496, -97.7776)),
   171  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.7189, -99.6629)),
   172  			s2.PointFromLatLng(s2.LatLngFromDegrees(47.3422, -99.4244)),
   173  			s2.PointFromLatLng(s2.LatLngFromDegrees(46.6523, -101.6056)),
   174  		},
   175  	}
   176  
   177  	// We will use a point that we wish to find the edges which are closest to it.
   178  	point := s2.PointFromLatLng(s2.LatLngFromDegrees(37.7, -122.5))
   179  
   180  	// Load them into a ShapeIndex.
   181  	index := s2.NewShapeIndex()
   182  	for _, l := range polylines {
   183  		index.Add(&l)
   184  	}
   185  
   186  	// Create a ClosestEdgeQuery and specify that we want the 7 closest.
   187  	//
   188  	// Note that if you were to request all results, and compare to the results
   189  	// of a FurthestEdgeQuery, the results will not be a complete reversal. This
   190  	// is because the distances being reported are to the closest end of a given
   191  	// edge, while the Furthest query is reporting distances to the farthest end
   192  	// of a given edge.
   193  	q := s2.NewClosestEdgeQuery(index, s2.NewClosestEdgeQueryOptions().MaxResults(7))
   194  	target := s2.NewMinDistanceToPointTarget(point)
   195  
   196  	for _, result := range q.FindEdges(target) {
   197  		polylineIndex := result.ShapeID()
   198  		edgeIndex := result.EdgeID()
   199  		distance := result.Distance()
   200  		fmt.Printf("Polyline %d, Edge %d is %0.4f degrees from Point (%0.6f, %0.6f, %0.6f)\n",
   201  			polylineIndex, edgeIndex,
   202  			distance.Angle().Degrees(), point.X, point.Y, point.Z)
   203  	}
   204  	// Output:
   205  	// Polyline 0, Edge 7 is 10.2718 degrees from Point (-0.425124, -0.667311, 0.611527)
   206  	// Polyline 0, Edge 8 is 10.2718 degrees from Point (-0.425124, -0.667311, 0.611527)
   207  	// Polyline 0, Edge 9 is 11.5362 degrees from Point (-0.425124, -0.667311, 0.611527)
   208  	// Polyline 0, Edge 10 is 11.5602 degrees from Point (-0.425124, -0.667311, 0.611527)
   209  	// Polyline 0, Edge 6 is 11.8071 degrees from Point (-0.425124, -0.667311, 0.611527)
   210  	// Polyline 0, Edge 5 is 12.2577 degrees from Point (-0.425124, -0.667311, 0.611527)
   211  	// Polyline 0, Edge 11 is 12.9502 degrees from Point (-0.425124, -0.667311, 0.611527)
   212  
   213  }
   214  
   215  func ExampleEdgeQuery_FindEdges_findFurthestEdges() {
   216  	// Let's start with one or more Polylines that we wish to compare against.
   217  	polylines := []s2.Polyline{
   218  		// This is an iteration = 3 Koch snowflake centered at the
   219  		// center of the continental US.
   220  		s2.Polyline{
   221  			s2.PointFromLatLng(s2.LatLngFromDegrees(47.5467, -103.6035)),
   222  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.9214, -103.7320)),
   223  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.1527, -105.8000)),
   224  			s2.PointFromLatLng(s2.LatLngFromDegrees(44.2866, -103.8538)),
   225  			s2.PointFromLatLng(s2.LatLngFromDegrees(42.6450, -103.9695)),
   226  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.8743, -105.9314)),
   227  			s2.PointFromLatLng(s2.LatLngFromDegrees(42.7141, -107.8226)),
   228  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.0743, -107.8377)),
   229  			s2.PointFromLatLng(s2.LatLngFromDegrees(40.2486, -109.6869)),
   230  			s2.PointFromLatLng(s2.LatLngFromDegrees(39.4333, -107.8521)),
   231  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.7936, -107.8658)),
   232  			s2.PointFromLatLng(s2.LatLngFromDegrees(38.5849, -106.0503)),
   233  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.7058, -104.2841)),
   234  			s2.PointFromLatLng(s2.LatLngFromDegrees(36.0638, -104.3793)),
   235  			s2.PointFromLatLng(s2.LatLngFromDegrees(35.3062, -106.1585)),
   236  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.4284, -104.4703)),
   237  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.8024, -104.5573)),
   238  			s2.PointFromLatLng(s2.LatLngFromDegrees(33.5273, -102.8163)),
   239  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.6053, -101.1982)),
   240  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.2313, -101.0361)),
   241  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.9120, -99.2189)),
   242  			s2.PointFromLatLng(s2.LatLngFromDegrees(33.9382, -97.6134)),
   243  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.3185, -97.8489)),
   244  			s2.PointFromLatLng(s2.LatLngFromDegrees(32.9481, -96.0510)),
   245  			s2.PointFromLatLng(s2.LatLngFromDegrees(31.9449, -94.5321)),
   246  			s2.PointFromLatLng(s2.LatLngFromDegrees(33.5521, -94.2263)),
   247  			s2.PointFromLatLng(s2.LatLngFromDegrees(34.1285, -92.3780)),
   248  			s2.PointFromLatLng(s2.LatLngFromDegrees(35.1678, -93.9070)),
   249  			s2.PointFromLatLng(s2.LatLngFromDegrees(36.7893, -93.5734)),
   250  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.3529, -91.6381)),
   251  			s2.PointFromLatLng(s2.LatLngFromDegrees(36.2777, -90.1050)),
   252  			s2.PointFromLatLng(s2.LatLngFromDegrees(37.8824, -89.6824)),
   253  			s2.PointFromLatLng(s2.LatLngFromDegrees(38.3764, -87.7108)),
   254  			s2.PointFromLatLng(s2.LatLngFromDegrees(39.4869, -89.2407)),
   255  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.0883, -88.7784)),
   256  			s2.PointFromLatLng(s2.LatLngFromDegrees(40.5829, -90.8289)),
   257  			s2.PointFromLatLng(s2.LatLngFromDegrees(41.6608, -92.4765)),
   258  			s2.PointFromLatLng(s2.LatLngFromDegrees(43.2777, -92.0749)),
   259  			s2.PointFromLatLng(s2.LatLngFromDegrees(43.7961, -89.9408)),
   260  			s2.PointFromLatLng(s2.LatLngFromDegrees(44.8865, -91.6533)),
   261  			s2.PointFromLatLng(s2.LatLngFromDegrees(46.4844, -91.2100)),
   262  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.9512, -93.4327)),
   263  			s2.PointFromLatLng(s2.LatLngFromDegrees(46.9863, -95.2792)),
   264  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.3722, -95.6237)),
   265  			s2.PointFromLatLng(s2.LatLngFromDegrees(44.7496, -97.7776)),
   266  			s2.PointFromLatLng(s2.LatLngFromDegrees(45.7189, -99.6629)),
   267  			s2.PointFromLatLng(s2.LatLngFromDegrees(47.3422, -99.4244)),
   268  			s2.PointFromLatLng(s2.LatLngFromDegrees(46.6523, -101.6056)),
   269  		},
   270  	}
   271  
   272  	// We will use a point that we want to find the edges which are furthest from it.
   273  	point := s2.PointFromLatLng(s2.LatLngFromDegrees(37.7, -122.5))
   274  
   275  	// Load them into a ShapeIndex
   276  	index := s2.NewShapeIndex()
   277  	for _, l := range polylines {
   278  		index.Add(&l)
   279  	}
   280  
   281  	// Create a FurthestEdgeQuery and specify that we want the 3 furthest.
   282  	q := s2.NewFurthestEdgeQuery(index, s2.NewFurthestEdgeQueryOptions().MaxResults(3))
   283  	target := s2.NewMaxDistanceToPointTarget(point)
   284  
   285  	for _, result := range q.FindEdges(target) {
   286  		polylineIndex := result.ShapeID()
   287  		edgeIndex := result.EdgeID()
   288  		distance := result.Distance()
   289  		fmt.Printf("Polyline %d, Edge %d is %0.3f degrees from Point (%0.6f, %0.6f, %0.6f)\n",
   290  			polylineIndex, edgeIndex,
   291  			distance.Angle().Degrees(), point.X, point.Y, point.Z)
   292  	}
   293  	// Output:
   294  	// Polyline 0, Edge 31 is 27.245 degrees from Point (-0.425124, -0.667311, 0.611527)
   295  	// Polyline 0, Edge 32 is 27.245 degrees from Point (-0.425124, -0.667311, 0.611527)
   296  	// Polyline 0, Edge 33 is 26.115 degrees from Point (-0.425124, -0.667311, 0.611527)
   297  
   298  }
   299  

View as plain text