Commit e7257966 authored by Lukas Eller's avatar Lukas Eller

Added type hints for all existing functions. Plus included a plotting_osm function.

parent 231f1851
from .preprocess import link_dataframes from .preprocess import link_dataframes
from .geospatial import get_geoseries_streets, get_geoseries_blockages from .geospatial import get_geoseries_streets, get_geoseries_blockages
from .geospatial import project_onto_streets from .geospatial import project_onto_streets
from .plotting import plot_series_osm
...@@ -6,7 +6,7 @@ import numpy as np ...@@ -6,7 +6,7 @@ import numpy as np
import warnings import warnings
import time import time
def make_overpy_request(request_body, retries): def make_overpy_request(request_body : str, retries : int):
for _ in range(retries): for _ in range(retries):
try: try:
api = overpy.Overpass() api = overpy.Overpass()
...@@ -19,7 +19,7 @@ def make_overpy_request(request_body, retries): ...@@ -19,7 +19,7 @@ def make_overpy_request(request_body, retries):
else: else:
return result return result
def get_geoseries_streets(measurement_coords, retries=5): def get_geoseries_streets(measurement_coords : gpd.GeoSeries, retries : int = 5) -> gpd.GeoSeries:
''' '''
Obtain the street shapes in the area spanned by the measurement_coords. Obtain the street shapes in the area spanned by the measurement_coords.
...@@ -31,8 +31,8 @@ def get_geoseries_streets(measurement_coords, retries=5): ...@@ -31,8 +31,8 @@ def get_geoseries_streets(measurement_coords, retries=5):
if measurement_coords.crs != "EPSG:4326": if measurement_coords.crs != "EPSG:4326":
raise ValueError("Make sure to pass data with EPSG:4326 projection") raise ValueError("Make sure to pass data with EPSG:4326 projection")
long, lat = measurement_coords.x, measurement_coords.y #Find total bounds: (lat_min, long_min, lat_max, long_max)
bounds = (lat.min(), long.min(), lat.max(), long.max()) bounds = tuple(measurement_coords.total_bounds[[1, 0, 3, 2]])
result = make_overpy_request( result = make_overpy_request(
f""" f"""
...@@ -55,7 +55,7 @@ def get_geoseries_streets(measurement_coords, retries=5): ...@@ -55,7 +55,7 @@ def get_geoseries_streets(measurement_coords, retries=5):
return street_series return street_series
def get_geoseries_blockages(measurement_coords, retries=5): def get_geoseries_blockages(measurement_coords : gpd.GeoSeries, retries : int = 5) -> gpd.GeoSeries:
''' '''
Obtain the blockage shapes in the area spanned by the measurement_coords. Obtain the blockage shapes in the area spanned by the measurement_coords.
...@@ -67,8 +67,8 @@ def get_geoseries_blockages(measurement_coords, retries=5): ...@@ -67,8 +67,8 @@ def get_geoseries_blockages(measurement_coords, retries=5):
if measurement_coords.crs != "EPSG:4326": if measurement_coords.crs != "EPSG:4326":
raise ValueError("Make sure to pass data with EPSG:4326 projection") raise ValueError("Make sure to pass data with EPSG:4326 projection")
long, lat = measurement_coords.x, measurement_coords.y #Find total bounds: (lat_min, long_min, lat_max, long_max)
bounds = (lat.min(), long.min(), lat.max(), long.max()) bounds = tuple(measurement_coords.total_bounds[[1, 0, 3, 2]])
result = make_overpy_request( result = make_overpy_request(
f""" f"""
...@@ -92,9 +92,9 @@ def get_geoseries_blockages(measurement_coords, retries=5): ...@@ -92,9 +92,9 @@ def get_geoseries_blockages(measurement_coords, retries=5):
return blockages return blockages
def project_onto_streets(point_series, street_series, epsg="EPSG:31287", plot=False): def project_onto_streets(point_series : gpd.GeoSeries, street_series : gpd.GeoSeries, epsg : str ="EPSG:31287", plot : bool =False) -> (gpd.GeoSeries, gpd.GeoSeries):
''' '''
Todo: Muss noch angepasst werden! Todo: Not completed
''' '''
if point_series.crs != epsg or street_series.crs != epsg: if point_series.crs != epsg or street_series.crs != epsg:
......
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt
def plot_series_osm(gps_series : gpd.GeoSeries, c_series : np.ndarray = None, zoom_level : int = 10, scatter_size : int = 10, fig_size : (int, int) = (12, 10), save_path=None, show=True):
'''
Plot a series of gps locations onto a OSM map
:param gps_series: geopandas series of the gps value in EPSG:4326 to plot
:param c_series: series of values to be interpreted as colors in the scatterplot
:param zoom_level: zoom level for resolution of OSM tiles
:param fig_size: the figure size of the generated plot
:param save_path: if not none then the plot will be saved under this path
'''
if gps_series.crs != "EPSG:4326":
raise ValueError("Make sure to pass data with EPSG:4326 projection")
request = cimgt.OSM()
extent = gps_series.total_bounds[[0, 2, 1, 3]]
plt.figure(figsize=fig_size)
ax = plt.axes(projection=request.crs)
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
ax.set_extent(extent)
ax.add_image(request, zoom_level)
if c_series is not None:
ax.scatter(gps_series.x, gps_series.y, c=c_series, transform=ccrs.PlateCarree(), s=scatter_size)
else:
ax.scatter(gps_series.x, gps_series.y, transform=ccrs.PlateCarree(), s=scatter_size)
if save_path is not None:
plt.savefig(save_path, bbox_inches="tight")
if show:
plt.show()
...@@ -2,3 +2,4 @@ pandas>=1.2.1 ...@@ -2,3 +2,4 @@ pandas>=1.2.1
pytest>=6.2.2 pytest>=6.2.2
overpy>=0.4 overpy>=0.4
geopandas>=0.8.1 geopandas>=0.8.1
cartopy>=0.18.0
...@@ -10,7 +10,7 @@ README = (HERE / "README.md").read_text() ...@@ -10,7 +10,7 @@ README = (HERE / "README.md").read_text()
# This call to setup() does all the work # This call to setup() does all the work
setup( setup(
name="measprocess", name="measprocess",
version="0.5.11", version="0.5.12",
description="Collection of measurement processing tools", description="Collection of measurement processing tools",
long_description=README, long_description=README,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
...@@ -23,5 +23,5 @@ setup( ...@@ -23,5 +23,5 @@ setup(
], ],
packages=["measprocess"], packages=["measprocess"],
include_package_data=True, include_package_data=True,
install_requires=["pandas", "matplotlib", "geopandas", "overpy", "shapely", "numpy", "tqdm"], install_requires=["pandas", "matplotlib", "geopandas", "overpy", "shapely", "numpy", "tqdm", "cartopy"],
) )
This diff is collapsed.
...@@ -71,3 +71,6 @@ class TestOSMAPI(unittest.TestCase): ...@@ -71,3 +71,6 @@ class TestOSMAPI(unittest.TestCase):
self.assertTrue( self.assertTrue(
blockage_series.distance(projected[0]).mean() < 1000 blockage_series.distance(projected[0]).mean() < 1000
) )
if __name__ == '__main__':
unittest.main()
import unittest
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
from context import measprocess as mpc
class TestPlottingOSM(unittest.TestCase):
def setUp(self):
complete_dataset = pd.read_csv("tests/example_files/gps_test/gps.csv", index_col=0)
gps_series = complete_dataset[['Lon.', 'Lat.']].values
self._gps_series = gpd.GeoSeries(
(Point(lon, lat) for lon, lat in gps_series)
)
def test_basic(self):
#Check if no exception comes up
series = self._gps_series.set_crs("EPSG:4326")
mpc.plotting.plot_series_osm(series, show=False)
def test_exception_epsg(self):
with self.assertRaises(ValueError):
series = self._gps_series#.set_crs("EPSG:4326")
mpc.plotting.plot_series_osm(series, show=False)
if __name__ == '__main__':
unittest.main()
...@@ -70,3 +70,6 @@ class TestProjections(unittest.TestCase): ...@@ -70,3 +70,6 @@ class TestProjections(unittest.TestCase):
deviation.values - np.array([10, 1, np.sqrt(10**2+10**2)]) deviation.values - np.array([10, 1, np.sqrt(10**2+10**2)])
) < 1e-1 ) < 1e-1
) )
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment