def way_to_polygon( osmmap: Map, way: Way, transform: Callable[[float, float, Optional[float]], Union[Tuple[float, float], Tuple[float, float, float]]] ) -> Optional[Polygon]: nodes = osmmap.get_nodes_for_way(way.id) polygon_array = [] for node in nodes: polygon_array.append(transform(node.lon, node.lat, None)) if polygon_array[len(polygon_array) - 1] == polygon_array[0] and len(polygon_array) > 2: p = Polygon(polygon_array) if p.exterior.is_ccw: p = Polygon(reversed(polygon_array)) p.osm_tags = way.tags return p raise WayToPolygonError("Could not convert way to polygon: " + way.id)
def relation_to_polygon( osmmap: Map, relation: Relation, transform: Callable[[float, float, Optional[float]], Union[Tuple[float, float], Tuple[float, float, float]]] ) -> Optional[Polygon]: outer_way_refs = [] outer_way_all_nodes = {} outer_way_start_nodes = {} outer_way_end_nodes = {} inner_way_refs = [] inner_way_all_nodes = {} inner_way_start_node = {} inner_way_end_node = {} for member in relation.members: if member.type == MemberTypes.WAY: way_nodes = osmmap.get_nodes_for_way(member.ref) if len(way_nodes) == 0: continue if member.role == "inner": inner_way_all_nodes[member.ref] = way_nodes inner_way_start_node[member.ref] = way_nodes[0] inner_way_end_node[member.ref] = way_nodes[ len(inner_way_all_nodes[member.ref]) - 1] inner_way_refs.append(member.ref) elif member.role == "outer": outer_way_all_nodes[member.ref] = way_nodes outer_way_start_nodes[member.ref] = way_nodes[0] outer_way_end_nodes[member.ref] = way_nodes[ len(outer_way_all_nodes[member.ref]) - 1] outer_way_refs.append(member.ref) # now piece together the outer way incomplete_way_refs, outer_ways_nodes = Convert.piece_together_ways( outer_way_refs, outer_way_all_nodes, outer_way_start_nodes, outer_way_end_nodes) # fail completely if there are if len(incomplete_way_refs) > 0: for member in relation.members: if member.type == MemberTypes.WAY: test_way_nodes = osmmap.get_nodes_for_way(member.ref) if member.role == "outer": print("Relation Members for id: " + str(member.ref), test_way_nodes) print("Relation Id: " + str(relation.id)) print( "Failed to piece together exterior way. This is bad! FIX THIS!" ) print(incomplete_way_refs) return None if 0 == len(outer_ways_nodes) or len(outer_ways_nodes) > 1: print("Did not expect " + str(len(outer_ways_nodes)) + " exterior ways! This is bad! FIX THIS!") print("Relation Id: " + str(relation.id)) print(incomplete_way_refs) return None # create exterior of polygon exterior = [] for node in outer_ways_nodes[0]: exterior.append(transform(node.lon, node.lat, None)) # now piece together the inner way incomplete_way_refs, inner_ways_nodes = Convert.piece_together_ways( inner_way_refs, inner_way_all_nodes, inner_way_start_node, inner_way_end_node) if len(incomplete_way_refs) > 0: print( "Failed to piece together interior way. Continuing as normal, but something might look wrong..." ) print(incomplete_way_refs) interiors = [] for inner_way_nodes in inner_ways_nodes: interior_coordinates = [] for node in inner_way_nodes: interior_coordinates.append(transform(node.lon, node.lat, None)) interior_polygon = Polygon(interior_coordinates) if not interior_polygon.exterior.is_ccw: interior_coordinates = list(reversed(interior_coordinates)) interiors.append(interior_coordinates) polygon = Polygon(exterior, interiors) if polygon.exterior.is_ccw: polygon = Polygon(reversed(exterior), interiors) polygon.osm_tags = relation.tags return polygon