diff --git a/measprocess/geospatial.py b/measprocess/geospatial.py index 4a3b30b3a1fc0aee42883f576e1ca53d790b5aae..b3c93a5e3c04565e292d2398a32b820a483d2a7d 100644 --- a/measprocess/geospatial.py +++ b/measprocess/geospatial.py @@ -1,6 +1,6 @@ import overpy import geopandas as gpd -from shapely.geometry import LineString, Polygon, box +from shapely.geometry import LineString, Polygon, Point, box from scipy.spatial.distance import cdist import numpy as np import warnings @@ -156,4 +156,37 @@ def crop_geoseries_by_bounds(original_geoseries : gpd.GeoSeries, filter_geoserie bound_box = gpd.GeoDataFrame(geometry = gpd.GeoSeries(bound_box)).set_crs("EPSG:4326") # create geodataframe for overlay filtered_series = (gpd.overlay(gpd.GeoDataFrame(geometry = original_geoseries),bound_box, how='intersection')).geometry - return filtered_series \ No newline at end of file + return filtered_series + +def interpolate_series_at_distance(street_series : gpd.GeoSeries, distance : int = 2) -> gpd.GeoSeries: + ''' + Interpolates along the geoseries streets_series to get nodes at a distance 'distance' apart. + Make sure to pass data in Cartesian coordinates (e.g. use street_series.to_crs('EPSG:31287') for Austria). + + :param street_series: geopandas geoseries + :param distance: integer determining the spacing between interpolation points, default=2 + + :return: geopandas geoseries overlapping with original geoseries containing more frequent nodes + ''' + if street_series.crs == "EPSG:4326": + raise ValueError("Make sure to pass data in Cartesian coordinates (e.g. use street_series.to_crs('EPSG:31287') for Austria)") + + if distance <= 0: + raise ValueError("Distance has to be a positive number.") + + lines = [] + for linestring in street_series: + list_points = [] # list to hold all the point coords + current_dist = distance # set the current distance to place the point + line_length = linestring.length # get the total length of the line (not number of points, but actual length) + list_points.append(Point(list( linestring.coords[0]))) # append the starting coordinate to the list + while current_dist < line_length: # while the current cumulative distance is less than the total length of the line + list_points.append(linestring.interpolate(current_dist)) # use interpolate and increase the current distance + current_dist += distance + list_points.append(Point(list( linestring.coords[-1]))) # append end coordinate to the list + line = LineString(list_points) + lines.append(line) + + interpolated_street_series = gpd.GeoSeries(lines) + return interpolated_street_series + diff --git a/measprocess/plotting.py b/measprocess/plotting.py index c84953b10aa60134f717a81a4a41eccd1a2a29a2..7c5a8272943100343980a87b68b3f45675ddbd52 100644 --- a/measprocess/plotting.py +++ b/measprocess/plotting.py @@ -34,3 +34,15 @@ def plot_series_osm(gps_series : gpd.GeoSeries, c_series : np.ndarray = None, zo plt.savefig(save_path, bbox_inches="tight") if show: plt.show() + +def plot_street_nodes(street_series : gpd.GeoSeries, axs, marker : str = 'o', color : str = 'blue'): + ''' + Plots the street_series with nodes along each way. + + :param street_series: geopandas series of LineStrings + :param axs: denotes the axis on which to plot + :param marker: marker for the nodes + :param color: color of the plotted lines and nodes + ''' + for linestring in street_series: + axs.plot(np.array(linestring)[:,0],np.array(linestring)[:,1],marker = marker, color = color) \ No newline at end of file