func BenchmarkGeosPaulSmit(b *testing.B) { // Setup polygon, err := geos.NewPolygon([]geos.Coord{ {0, 1, 0}, {1, 2, 0}, {2, 1, 0}, {2, 0, 0}, {1, -1, 0}, {0, 0, 0}, {0, 1, 0}, }) if err != nil { b.Fatal(err) } point, err := geos.NewPoint(geos.Coord{X: 1, Y: 0, Z: 0}) if err != nil { b.Fatal(err) } b.ResetTimer() // Test for i := 0; i < b.N; i++ { contains, err := polygon.Contains(point) if err != nil { b.Fatal(err) } if !contains { b.Fatal("not contains") } } }
// Searches the R-Tree to find the place corresponding to the given lat,lng // First uses the R-Tree which contains only the bounding boxes of the // entities, and then refine the result using the actual geometry of the entity. func reverseGeocode(rt *rtreego.Rtree, lat, lng, precision float64) (*GeoData, error) { var results []rtreego.Spatial // First search the R-Tree rpt := rtreego.Point{lng, lat} results = rt.SearchIntersect(rpt.ToRect(precision / 2.)) if len(results) == 0 || results[0] == nil { nn := rt.NearestNeighbor(rpt) if nn == nil { return nil, ErrNoMatchFound } else { results = []rtreego.Spatial{nn} } } // Then check with the actual geometry of the entity mindist := math.MaxFloat64 var argmindist *GeoData gpt, _ := geos.NewPoint(geos.NewCoord(lng, lat)) for _, res := range results { if res == nil { break } obj, _ := res.(SpatialData) geod := obj.GetData() inside, _ := geod.Geom.Contains(gpt) if inside { return geod, nil } dist, _ := gpt.Distance(geod.Geom) if dist < mindist { mindist = dist argmindist = geod } } if mindist < precision { return argmindist, nil } return nil, ErrNoMatchFound }