def test_run_from_location_name_without_additional_nodes( default_output_pois_columns, default_output_network_columns ): location_name = "roanne" network_initialized = OsmGt.roads_from_location(location_name, "pedestrian") graph_computed = network_initialized.get_graph() network_gdf = network_initialized.get_gdf() shared_asserts( None, network_gdf, default_output_pois_columns, default_output_network_columns, graph_computed, ) network_topology_gdfs = network_initialized.topology_checker() assert { "lines_unchanged", "lines_added", "lines_split", "nodes_added", "intersections_added", } == set(network_topology_gdfs.keys()) for title, topology_gdf in network_topology_gdfs.items(): if title in ["nodes_added", "lines_added"]: assert topology_gdf.shape[0] == 0 else: assert topology_gdf.shape[0] > 0 assert topology_gdf.shape[-1] == 5
def test_get_pois_from_an_unexisting_location(): location_name = "dsfsdfsdf" with pytest.raises(ErrorOsmGtCore) as excinfo: _ = OsmGt.pois_from_location(location_name) assert "Location not found!" == str(excinfo.value)
def test_isochrone_from_distances(location_point, isochrone_distance_values, isochrones_polygons_output_default_columns, isochrones_lines_output_default_columns): ( isochrones_polygons, isochrones_lines, ) = OsmGt.isochrone_distances_from_nodes([location_point], isochrone_distance_values, 3, mode="vehicle") # polygons assert isochrones_polygons.shape[0] > 0 assert set(isochrones_polygons["iso_name"].to_list()) == {5.0, 10.0, 20.0} assert isochrones_polygons_output_default_columns.issubset( set(isochrones_polygons.columns.to_list())) assert "__dissolve__" not in isochrones_polygons.columns.to_list() # lines assert isochrones_lines.shape[0] > 0 assert set(isochrones_lines["iso_name"].to_list()) == {5.0, 10.0, 20.0} assert isochrones_lines_output_default_columns.issubset( set(isochrones_lines.columns.to_list())) assert "__dissolve__" not in isochrones_lines.columns.to_list() isochrones_dissolved = isochrones_polygons["geometry"].unary_union # check if isochrones_dissolved is a polygon else it means that isochrones are disconnected! assert isochrones_dissolved.geom_type == "Polygon" assert isochrones_lines["geometry"].unary_union.within( Polygon( isochrones_dissolved.exterior ) # there are (very small gaps between isochrones... so get exterior) )
def test_if_shortest_path_from_location_with_an_outside_node_on_pairs( start_and_end_nodes, start_and_end_nodes_3): with pytest.raises(AdditionalNodesOutsideWorkingArea) as excinfo: _ = OsmGt.shortest_path_from_location( "roanne", [start_and_end_nodes, start_and_end_nodes_3], mode="pedestrian") assert ( "These following points are outside the working area: POINT (-74.00411 40.722584)" == str(excinfo.value))
def test_run_from_bbox_func_usa( bbox_values_2, default_output_pois_columns, default_output_network_columns ): pois_initialized = OsmGt.pois_from_bbox(bbox_values_2) pois_study_area = pois_initialized.study_area assert pois_study_area.geom_type == "Polygon" pois_gdf = pois_initialized.get_gdf() network_initialized = OsmGt.roads_from_bbox( bbox_values_2, additional_nodes=pois_gdf ) network_study_area = network_initialized.study_area assert network_study_area.geom_type == "Polygon" graph_computed = network_initialized.get_graph() network_gdf = network_initialized.get_gdf() shared_asserts( None, network_gdf, default_output_pois_columns, default_output_network_columns, graph_computed, ) network_topology_gdfs = network_initialized.topology_checker() assert { "lines_unchanged", "lines_added", "lines_split", "nodes_added", "intersections_added", } == set(network_topology_gdfs.keys()) for title, topology_gdf in network_topology_gdfs.items(): if title in ["nodes_added", "lines_added"]: assert topology_gdf.shape[0] > 0 else: assert topology_gdf.shape[0] > 0 assert topology_gdf.shape[-1] == 5
def test_if_shortest_path_from_location_with_duplicated_nodes_pairs( start_and_end_nodes, shortest_path_output_default_columns): shortest_paths = OsmGt.shortest_path_from_location( "Roanne", [start_and_end_nodes, start_and_end_nodes], mode="pedestrian", ) assert set(shortest_paths.columns.to_list() ) == shortest_path_output_default_columns assert len(shortest_paths["osm_ids"]) > 0 assert shortest_paths.shape[0] == 1
def test_if_shortest_path_from_bbox_with_an_outside_nodes_pairs( bbox_values_3, start_and_end_nodes, start_and_end_nodes_2): with pytest.raises(AdditionalNodesOutsideWorkingArea) as excinfo: _ = OsmGt.shortest_path_from_bbox( bbox_values_3, [start_and_end_nodes, start_and_end_nodes_2], mode="pedestrian", ) assert ( "These following points are outside the working area: POINT (-74.00411 40.722584), POINT (-74.00020499999999 40.721494)" == str(excinfo.value))
def compute_path(self): output_paths = [] nodes_path = [ { "position": int(row["position"]), "geometry": row["geometry"] } for _, row in self._input_nodes_data.iterrows() ] if self._is_loop: loop_position = len(nodes_path) - 1 loop_geometry = nodes_path[0]["geometry"] nodes_path.append( { "position": loop_position, "geometry": loop_geometry } ) nodes_path_ordered = sorted(nodes_path, key=itemgetter('position'), reverse=False) paths_to_compute = list(zip(nodes_path_ordered, nodes_path_ordered[1:])) path_ordered = { str(enum): (start_node["geometry"], end_node["geometry"]) for enum, (start_node, end_node) in enumerate(paths_to_compute) } output_gdf = OsmGt.shortest_path_from_bbox( self._bbox_to_use, list(path_ordered.values()), self._mode, ) for order, path_coord in path_ordered.items(): source_node_wkt = path_coord[0].wkt target_node_wkt = path_coord[-1].wkt geom_data = output_gdf.loc[ (output_gdf["source_node"] == source_node_wkt) & (output_gdf["target_node"] == target_node_wkt) ].iloc[0]["geometry"].coords if self._elevation_mode: geom_data = self.get_elevation(geom_data) output_paths.append({ "source_node": source_node_wkt, "target_node": target_node_wkt, "path_step": order, "geometry": geom_data }) return output_paths
def test_if_shortest_path_from_bbox_with_duplicated_nodes_pairs( bbox_values_3, start_and_end_nodes, shortest_path_output_default_columns): shortest_paths = OsmGt.shortest_path_from_bbox( bbox_values_3, [start_and_end_nodes, start_and_end_nodes], mode="pedestrian", ) assert set(shortest_paths.columns.to_list() ) == shortest_path_output_default_columns assert len(shortest_paths["osm_ids"]) > 0 assert len(shortest_paths["osm_urls"]) > 0 assert shortest_paths.shape[0] == 1
def test_run_from_location_name_with_additional_nodes( default_output_pois_columns, default_output_network_columns ): location_name = "roanne" pois_initialized = OsmGt.pois_from_location(location_name) pois_study_area = pois_initialized.study_area assert pois_study_area.geom_type == "Polygon" pois_gdf = pois_initialized.get_gdf() network_initialized = OsmGt.roads_from_location( location_name, "pedestrian", pois_gdf ) study_area = network_initialized.study_area assert study_area.geom_type == "Polygon" graph_computed = network_initialized.get_graph() network_gdf = network_initialized.get_gdf() shared_asserts( pois_gdf, network_gdf, default_output_pois_columns, default_output_network_columns, graph_computed, ) network_topology_gdfs = network_initialized.topology_checker() assert { "lines_unchanged", "lines_added", "lines_split", "nodes_added", "intersections_added", } == set(network_topology_gdfs.keys()) for topology_gdf in network_topology_gdfs.values(): assert topology_gdf.shape[0] > 0 assert topology_gdf.shape[1] == 5
def test_isochrones_from_times( location_point, isochrone_values, isochrones_polygons_output_default_columns, isochrones_lines_output_default_columns, ): output_data = OsmGt.isochrone_times_from_nodes([location_point], list(isochrone_values), 3, mode="pedestrian") isochrones_polygons, isochrones_lines = output_data # polygons assert isochrones_polygons.shape[0] == 4 assert set(isochrones_polygons["iso_name"].to_list()) == isochrone_values assert isochrones_polygons_output_default_columns.issubset( set(isochrones_polygons.columns.to_list())) assert "__dissolve__" not in isochrones_polygons.columns.to_list() # check if output geom are correctly built geometries = isochrones_polygons["geometry"].to_list() geometries_area_sorted = sorted(list([(geom.area, geom) for geom in geometries]), reverse=True) geometries_area_sorted = [ feature[-1] for feature in geometries_area_sorted ] geometries_parent_and_child = [ (x[0], x[-1]) for x in list(zip(geometries_area_sorted, geometries_area_sorted[1:])) ] for parent, child in geometries_parent_and_child: assert not child.within(parent) # lines assert isochrones_lines.shape[0] > 0 assert set(isochrones_lines["iso_name"].to_list()) == isochrone_values assert isochrones_lines_output_default_columns.issubset( set(isochrones_lines.columns.to_list())) assert "__dissolve__" not in isochrones_lines.columns.to_list() isochrones_dissolved = isochrones_polygons["geometry"].unary_union # check if isochrones_dissolved is a polygon else it means that isochrones are disconnected! assert isochrones_dissolved.geom_type == "Polygon" assert isochrones_lines["geometry"].unary_union.within( Polygon( isochrones_dissolved.exterior ) # there are (very small gaps between isochrones... so get exterior) )