Пример #1
0
//newTilePolygon creates the geos polygon for a given tile.
func newTilePolygon(level, x, y int) (*geos.Geometry, error) {

	latDeg := raster.Y2Lat(level, y)
	lonDeg := raster.X2Lon(level, x)
	lat2Deg := raster.Y2Lat(level, y+1)
	lon2Deg := raster.X2Lon(level, x+1)

	return geos.NewPolygon(
		[]geos.Coord{
			geos.NewCoord(lonDeg, latDeg),
			geos.NewCoord(lon2Deg, latDeg),
			geos.NewCoord(lon2Deg, lat2Deg),
			geos.NewCoord(lonDeg, lat2Deg),
			geos.NewCoord(lonDeg, latDeg),
		})
}
Пример #2
0
// 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
}