diff --git a/src/GOSTnets/core.py b/src/GOSTnets/core.py index 567f7ee..506fa75 100644 --- a/src/GOSTnets/core.py +++ b/src/GOSTnets/core.py @@ -3615,7 +3615,7 @@ def project_gdf(gdf, to_crs=None, to_latlong=False): # otherwise, automatically project the gdf to UTM else: - if ox.CRS.from_user_input(gdf.crs).is_projected: + if ox.projection.is_projected(gdf.crs): raise ValueError("Geometry must be unprojected to calculate UTM zone") # calculate longitude of centroid of union of all geometries in gdf @@ -3766,7 +3766,7 @@ def find_kne(point, lines, near_idx): """ # getting the distances between the point and the lines - dists = np.array(list(map(lambda line: line.distance(point), lines))) + dists = np.array(lines.distance(point)) kne_pos = dists.argsort()[0] kne = lines.iloc[kne_pos] kne_idx = near_idx[kne_pos] @@ -3865,6 +3865,10 @@ def update_nodes( The updated nodes GeoDataFrame. """ + ### NOTES + # node_highway_pp and node_highway_poi are not both needed, they are + # used conditionally depending on the ptype, so the parameters should be updated + # create gdf of new nodes (projected PAPs) if ptype == "pp": new_nodes = gpd.GeoDataFrame(new_points, columns=["geometry"], crs=measure_crs) @@ -3918,6 +3922,12 @@ def update_edges(edges, new_lines, replace=True, nodes_meter=None, pois_meter=No kne_idx refers to 'fid in Rtree'/'label'/'loc', not positional iloc """ + ### NOTES + # line_pps_dict is never defined, where did it come from? + # same for 'itertools', 'measure_crs', 'pois', 'poi_key_col', 'oneway_tag', + # 'road_col', 'edge_highway', 'factor', 'u_tag', 'v_tag', 'nodes_id_dict', + # 'threshold', and maybe additional variables... DID THIS FUNCTION EVER WORK? + # for interpolation (split by pp): replicate old line if replace: # create a flattened gdf with all line segs and corresponding kne_idx diff --git a/tests/test_core.py b/tests/test_core.py index 70234e9..ea0a1b8 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -391,6 +391,13 @@ def test_project_gdf(): projected_gdf = core.project_gdf(gdf, to_crs="epsg:32633", to_latlong=False) # check the output assert projected_gdf.crs == "epsg:32633" + # with invalid CRS + gdf_invalid = gpd.GeoDataFrame({"geometry": [Point(0, 0), Point(1, 1)]}, crs=None) + with pytest.raises(ValueError): + core.project_gdf(gdf_invalid, to_crs="epsg:32633", to_latlong=False) + # with no "to_crs" parameter + utm_gdf = core.project_gdf(gdf, to_latlong=False) + assert "utm" in utm_gdf.crs.to_string() def test_euclidean_distance(): @@ -857,3 +864,42 @@ def test_clip(): assert G_clip.nodes(data=True) != G.nodes(data=True) assert G_clip.edges(data=True) != G.edges(data=True) assert G_clip.number_of_nodes() < G.number_of_nodes() + + +def test_find_kne(): + """Test the find_kne function.""" + # define a point + point = Point(0.5, 0.6) + # define some lines + line1 = LineString([(0, 0), (1, 1)]) + line2 = LineString([(1, 1), (2, 2)]) + line3 = LineString([(2, 2), (3, 3)]) + # put lines in a geodataframe + gdf = gpd.GeoDataFrame({"geometry": [line1, line2, line3]}) + # call function + kne_idx, kne = core.find_kne(point, gdf, [0, 1, 2]) + assert isinstance(kne_idx, int) + assert isinstance(kne, pd.Series) + assert kne_idx == 0 + + +def test_get_pp(): + """Test the get_pp function.""" + # define a point + point = Point(0.5, 0.6) + # define the line + line = LineString([(0, 0), (1, 1)]) + # call the function + pp = core.get_pp(point, line) + assert isinstance(pp, Point) + assert pp.x == 0.55 + assert pp.y == 0.55 + + +def test_split_line_error(): + """Test the split_line function error handling.""" + # define line + line = LineString([(0, 0), (1, 1)]) + # call function + with pytest.raises(TypeError): + core.split_line(line, "invalid") diff --git a/tests/test_core_integrative.py b/tests/test_core_integrative.py index 1e2b664..0b48117 100644 --- a/tests/test_core_integrative.py +++ b/tests/test_core_integrative.py @@ -80,3 +80,17 @@ def test_edges_nodes_df_to_graph_03(self): G = core.edges_and_nodes_gdf_to_graph(nodes_df, edges_df, largest_G=True) # assert that the function returned a nx graph this time assert isinstance(G, nx.Graph) + + def test_edges_nodes_df_to_graph_04(self): + # read csv files as dfs + nodes_df = pd.read_csv(self.fpath_nodes) + edges_df = pd.read_csv(self.fpath_edges) + # switch stnode and endnode to floats + edges_df["stnode"] = edges_df["stnode"].astype(float) + edges_df["endnode"] = edges_df["endnode"].astype(float) + # call function with adding missing reflected edges and the oneway tag + G = core.edges_and_nodes_gdf_to_graph( + nodes_df, edges_df, add_missing_reflected_edges=True, oneway_tag="one_way" + ) + # assert that the function returned a nx graph this time + assert isinstance(G, nx.Graph)