def __neighbour_bfs(self, poly: Polygon, precision) -> List[str]: centroid = poly.centroid gh = ghh.encode(*(centroid.coords[0]), precision=precision) overlaps = [] q1 = FifoQueue() q1.push(gh) q2 = FifoQueue() visited = dict() discovered = dict() level_active = False while not q1.empty(): node = q1.pop() if node not in visited.keys(): visited[node] = True discovered[node] = True node_poly = shape(ghh.rectangle(node)["geometry"]) if node_poly.intersects(poly): overlaps.append(node) level_active = True next_level = list(ghh.neighbours(node).values()) for nbr in next_level: if nbr not in discovered.keys(): discovered[nbr] = True q2.push(nbr) if q1.empty() and level_active: level_active = False q2, q1 = q1, q2 return overlaps
def __matrix_geohashes(self, poly) -> List: precision_box = ghh.rectangle(''.join( ["0" for _ in range(self.gh_len)]))["bbox"] grid_intercept = min(abs(precision_box[0] - precision_box[2]), abs(precision_box[1] - precision_box[3])) poly_bbox = poly.bounds subsamples = set() for lon in np.arange(poly_bbox[0], poly_bbox[2] + grid_intercept, grid_intercept): for lat in np.arange(poly_bbox[1], poly_bbox[3] + grid_intercept, grid_intercept): subsamples.add(self.__gh_encode(lon, lat)) return list(subsamples)
def get_geoset( self, lat: float, lon: float, obj_type: str = "building", ) -> Union[None, List[Polygon]]: """Given a location in latitude and longitude coordinates, return all polygons in vicinity. Args: lat (float): The latitude coordinate of a location in decimal degrees. lon (float): The longitude coordinate of a location in decimal degrees. obj_type (str): The name used to construct a unique key for a Redis sorted set. This name should describe the category of polygons we are indexing in Redis. Defaults to "building". TODO: In the future we might want cache other types of polygons or be more specific w.r.t. building type. Returns: Union[None, bool]: If the query was successful, then True is returned if the location is inside a build. False if the location is not inside a building and None if the query was not successful. """ # Compute a geohash for the given location geohash = ghh.encode( lon, lat, # NOTE: Make sure first arg is lon, then lat! precision=self.geohash_precision, bits_per_char=self.geohash_bits_per_char, ) # Get the bounding box encoded by the geohash geohash_data = ghh.rectangle(geohash) geohash_bbox = geohash_data["bbox"] # Swap elements in bbox. We get elements (lon, lat), but we want (lat, lon) geohash_bbox = [ geohash_bbox[1], geohash_bbox[0], geohash_bbox[3], geohash_bbox[2], ] # Contruct the key of the sorted set in Redis that we want to access key = self.get_key(obj_type=obj_type, geohash=geohash) polygons = self._get_geoset( key=key, lat=lat, lon=lon, bbox=geohash_bbox, ) return polygons
def __gh_contains_poly(cls, gh: str, poly: Polygon): node_poly = shape(ghh.rectangle(gh)["geometry"]) return node_poly.contains(poly)
def __gh_intersects_poly(cls, gh: str, poly: Polygon): node_poly = shape(ghh.rectangle(gh)["geometry"]) return node_poly.intersects(poly)
import geohash_hilbert as ghh print("Encode: ", ghh.encode(48.668983, -4.32915)) print("Decode: ", ghh.decode('oyTsqesqzy')) #Z7fe2GaIVO print("Rectangle: ", ghh.rectangle('oyTs'))