def test_placekey_to_hex_boundary(self): """ Test placekey to geo boundary conversion """ key = '@5vg-7gq-tvz' h3_integer = pk.placekey_to_h3_int(key) self.assertTupleEqual( pk.placekey_to_hex_boundary(key, geo_json=True), h3_int.h3_to_geo_boundary(h3_integer, geo_json=True), "placekey boundary equal to H3 boundary (geo_json=True)") self.assertTupleEqual( pk.placekey_to_hex_boundary(key, geo_json=False), h3_int.h3_to_geo_boundary(h3_integer, geo_json=False), "placekey boundary equal to H3 boundary (geo_json=False)")
def placekey_to_hex_boundary(placekey, geo_json=False): """ Given a Placekey, return the coordinates of the boundary of the hexagon. :param placekey: Placekey (string) :param geo_json: If True return the coordinates in GeoJSON format: (long, lat)-tuples and with the first and last tuples identical, and in counter-clockwise orientation. If False (default) tuples will be (lat, long), the last tuple will not equal the first, and the orientation will be clockwise. :return: Tuple of tuples ((float, float),...). """ h3_integer = placekey_to_h3_int(placekey) return h3_int.h3_to_geo_boundary(h3_integer, geo_json=geo_json)
def polygon_to_placekeys(poly, include_touching=False, geo_json=False): """ Given a shapely Polygon, return Placekeys contained in or intersecting the boundary of the polygon. :param poly: shapely Polygon object :param include_touching: If True Placekeys whose hexagon boundary only touches that of the input polygon are included in the set of boundary Placekeys. Default is False. :param geo_json: If True assume coordinates in `poly` are in GeoJSON format: (long, lat)-tuples and with the first and last tuples identical, and in counter-clockwise orientation. If False (default) assumes tuples will be (lat, long). :return: A dictionary with keys 'interior' and 'boundary' whose values are tuples of Placekeys that are contained in poly or which intersect the boundary of poly respectively. """ if geo_json: poly = transform(lambda x, y: (y, x), poly) buffer_size = 2e-3 buffered_poly = poly.buffer(buffer_size) candidate_hexes = h3_int.polyfill(mapping(buffered_poly), 10) tree = STRtree([poly]) interior_hexes = [] boundary_hexes = [] for h in list(candidate_hexes): hex_poly = Polygon(h3_int.h3_to_geo_boundary(h)) if len(tree.query(hex_poly)) > 0: if poly.contains(hex_poly): interior_hexes.append(h) elif poly.intersects(hex_poly): if include_touching: boundary_hexes.append(h) elif not include_touching and not poly.touches(hex_poly): boundary_hexes.append(h) return { 'interior': tuple(h3_int_to_placekey(h) for h in interior_hexes), 'boundary': tuple(h3_int_to_placekey(h) for h in boundary_hexes) }