From 23cc02e05dcec50cbd8619aae2ff27e1cc4056ca Mon Sep 17 00:00:00 2001 From: amauryval Date: Mon, 30 May 2022 22:20:17 +0200 Subject: [PATCH 1/2] upd (graph) build graph during data processing --- osmgt/compoments/roads.py | 47 +++++++++++++++++------------- osmgt/geometry/network_topology.py | 29 ++++++++++++++++-- osmgt/network/gt_helper.py | 3 +- setup.py | 2 +- tests/test_geometry.py | 4 +-- 5 files changed, 56 insertions(+), 29 deletions(-) diff --git a/osmgt/compoments/roads.py b/osmgt/compoments/roads.py index 58b1fcb..68c564b 100644 --- a/osmgt/compoments/roads.py +++ b/osmgt/compoments/roads.py @@ -35,6 +35,7 @@ class AdditionalNodesOutsideWorkingArea(Exception): class OsmGtRoads(OsmGtCore): __slots__ = ( "_mode", + "_graph", "_output_data", "_OUTPUT_EXPECTED_GEOM_TYPE" ) @@ -44,6 +45,7 @@ def __init__(self) -> None: super().__init__() self._mode = None + self._graph = None def from_location( self, @@ -63,7 +65,7 @@ def from_location( query = self._get_query_from_mode(mode) request = self._from_location_name_query_builder(self._location_id, query) raw_data = self._query_on_overpass_api(request) - self._output_data: List[NetworkFeature] = self.__build_network_topology( + self._output_data, self._graph = self.__build_network_topology( raw_data, additional_nodes, mode, interpolate_lines ) return self.get_gdf() @@ -86,28 +88,29 @@ def from_bbox( query = self._get_query_from_mode(mode) request = self._from_bbox_query_builder(self._bbox_value, query) raw_data = self._query_on_overpass_api(request) - self._output_data = self.__build_network_topology( + self._output_data, self._graph = self.__build_network_topology( raw_data, additional_nodes, mode, interpolate_lines ) def get_graph(self): - self.logger.info("Prepare graph") - self._check_network_output_data() - - graph = GraphHelpers( - self.logger, is_directed=network_queries[self._mode]["directed_graph"] - ) - - # graph.add_edges(self._output_data) # BULK mode - for feature in self._output_data: - graph.add_edge( - feature.start_coords, - feature.end_coords, - feature.topo_uuid, - feature.length - ) - self.logger.info("Graph ok") - return graph + return self._graph + # self.logger.info("Prepare graph") + # self._check_network_output_data() + # + # graph = GraphHelpers( + # self.logger, is_directed=network_queries[self._mode]["directed_graph"] + # ) + # + # # graph.add_edges(self._output_data) # BULK mode + # for feature in self._output_data: + # graph.add_edge( + # feature.start_coords, + # feature.end_coords, + # feature.topo_uuid, + # feature.length + # ) + # self.logger.info("Graph ok") + # return graph def _check_network_output_data(self): @@ -145,7 +148,8 @@ def __build_network_topology( additional_nodes = additional_nodes_filtered.to_dict("records") raw_data_restructured = self.__rebuild_network_data(raw_data) - raw_data_topology_rebuild = NetworkTopology( + + raw_data_topology_rebuild, graph = NetworkTopology( self.logger, raw_data_restructured, additional_nodes, @@ -153,9 +157,10 @@ def __build_network_topology( self._ID_OSM_FIELD, mode, interpolate_lines, + network_queries[self._mode]["directed_graph"] ).run() - return raw_data_topology_rebuild + return raw_data_topology_rebuild, graph def __rebuild_network_data(self, raw_data: List[Dict]) -> List[Dict]: self.logger.info("Rebuild network data") diff --git a/osmgt/geometry/network_topology.py b/osmgt/geometry/network_topology.py index 6d83709..039ae0f 100644 --- a/osmgt/geometry/network_topology.py +++ b/osmgt/geometry/network_topology.py @@ -28,11 +28,13 @@ from osmgt.helpers.global_values import forward_tag from osmgt.helpers.global_values import backward_tag +from osmgt.network.gt_helper import GraphHelpers class NetworkTopologyError(Exception): pass + class NetworkFeature: __slots__ = ( "geometry", @@ -92,6 +94,7 @@ class NetworkTopology: "__connections_added", "_output", "logger", + "_graph", "__tree_index", "__node_by_nearest_lines" ) @@ -135,6 +138,7 @@ def __init__( original_field_id: str, mode_post_processing: str, improve_line_output: bool = False, + directed_graph: bool = True, ) -> None: """ @@ -143,6 +147,8 @@ def __init__( :type additional_nodes: list of dict :type uuid_field: str :type mode_post_processing: str + :type improve_line_output: bool + :type directed_graph: bool """ self.logger = logger self.logger.info("Network cleaning...") @@ -167,7 +173,11 @@ def __init__( self.__connections_added: Dict = {} self._output: List[NetworkFeature] = [] - def run(self) -> List[NetworkFeature]: + self._graph = GraphHelpers( + self.logger, is_directed=directed_graph + ) + + def run(self) -> Tuple[List[NetworkFeature], GraphHelpers]: self._prepare_data() # ugly footway processing... @@ -185,7 +195,7 @@ def run(self) -> List[NetworkFeature]: for feature in self._network_data.values(): self.build_lines(feature) - return self._output + return self._output, self._graph # def prepare_footway_nodes(self) -> None: # import itertools @@ -308,6 +318,14 @@ def mode_processing(self, input_feature: Dict) -> List[NetworkFeature]: return new_elements + def add_graph_edge(self, feature: NetworkFeature): + self._graph.add_edge( + feature.start_coords, + feature.end_coords, + feature.topo_uuid, + feature.length + ) + def _direction_processing( self, input_feature: Dict, direction: Optional[str] = None ) -> List[NetworkFeature]: @@ -357,14 +375,19 @@ def __proceed_direction_geom( else: uuid = f"{input_feature[self.__FIELD_ID]}{idx}" + feature_built = self._build_network_feature(input_feature, new_linestring, uuid) + return feature_built - return NetworkFeature( + def _build_network_feature(self, input_feature: Dict, new_linestring: LineString, uuid: str): + feature = NetworkFeature( id_value=input_feature["id"], geometry=new_linestring, oneway=input_feature["oneway"] if "oneway" in input_feature else None, topology=input_feature["topology"], topo_uuid=uuid, ) + self.add_graph_edge(feature) + return feature def _split_line(self, feature: Dict, interpolation_level: int) -> List: new_line_coords = interpolate_curve_based_on_original_points( diff --git a/osmgt/network/gt_helper.py b/osmgt/network/gt_helper.py index fb03602..0a049cb 100644 --- a/osmgt/network/gt_helper.py +++ b/osmgt/network/gt_helper.py @@ -9,7 +9,6 @@ import collections -from osmgt.geometry.network_topology import NetworkFeature class ErrorGraphHelpers(ValueError): @@ -164,7 +163,7 @@ def add_edge( return None - def add_edges(self, edges: List[NetworkFeature]): + def add_edges(self, edges: List): graph_vertices = self.add_edge_list(map(lambda x: [x.start_coords, x.end_coords, x.length], edges), hashed=True, eprops=[self.edge_weights]) self.vertices_content = {graph_vertices[i]: self.vertex(i) for i in range(self.num_vertices())} diff --git a/setup.py b/setup.py index 84bb05b..2bddf3f 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ author="amauryval", author_email='amauryval@gmail.com', url="https://github.com/amauryval/osmgt", - version='0.8.12', + version='0.9.0', description="A library to play with OSM roads (and POIs) data using graph tool network library", entry_points={}, install_requires=requirements, diff --git a/tests/test_geometry.py b/tests/test_geometry.py index 8f41037..65ea59c 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -4,7 +4,7 @@ def test_connect_lines(some_line_features, some_point_features): - raw_data_topology_rebuild = NetworkTopology( + raw_data_topology_rebuild, _ = NetworkTopology( OsmGtCore().logger, some_line_features, some_point_features, @@ -54,7 +54,7 @@ def test_connect_lines(some_line_features, some_point_features): assert set([feature.geometry.geom_type for feature in raw_data_topology_rebuild]) == {"LineString"} def test_connect_lines_interpolate_lines(some_line_features, some_point_features): - raw_data_topology_rebuild = NetworkTopology( + raw_data_topology_rebuild, _ = NetworkTopology( OsmGtCore().logger, some_line_features, some_point_features, From a0b3969343dde2989449bf79625ae22f19324483 Mon Sep 17 00:00:00 2001 From: amauryval Date: Sat, 17 Sep 2022 11:18:47 +0200 Subject: [PATCH 2/2] upd (tests) remove data changed --- tests/test_isochrone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_isochrone.py b/tests/test_isochrone.py index 1bd0aae..680fdc4 100644 --- a/tests/test_isochrone.py +++ b/tests/test_isochrone.py @@ -17,7 +17,7 @@ def test_isochrones_from_times( isochrones_polygons, isochrones_lines = output_data # polygons - assert isochrones_polygons.shape[0] == 4 + assert isochrones_polygons.shape[0] == 6 assert set(isochrones_polygons["iso_name"].to_list()) == isochrone_values assert isochrones_polygons_output_default_columns.issubset( set(isochrones_polygons.columns.to_list())