diff --git a/measprocess/data_extractor.py b/measprocess/data_extractor.py index f6c6996b688b74d8c519b0bdd0f778814cc2e525..295f2a3a674fb1e7a493613481c849ed68733007 100644 --- a/measprocess/data_extractor.py +++ b/measprocess/data_extractor.py @@ -19,6 +19,8 @@ def fetch_rtr_details(open_test_uuids: List[str]) -> List[dict]: """ Fetch test details from RTR-Opendata for a list of open_test_uuids. These open_test_uuids can for instance be obtained via data_extractor.fetch_rtr_overview() + Detailed information about the API endpoint and the meaning of returned parameters is available under: + https://www.netztest.at/en/OpenDataSpecification.html. :param open_test_uuids: List of open_test_uuids for which test details will be fetched @@ -55,20 +57,29 @@ def fetch_rtr_overview( raw_params: List[Tuple[str, str]] = [], ) -> pd.DataFrame: """ - #Todo work on documentation! --> cat_technology, also filter not nan filters, test raw parameters + Queries the RTR-Netztest API according to the passed filters. + Detailed information about the API endpoint and the meaning of returned parameters is available under: + https://www.netztest.at/en/OpenDataSpecification.html. + Comprehensive results for each test can be obtained by passing the + open_test_uuids of the fetched measurements to fetch_rtr_details. - raw params are a list of parameters that will be concateneated and passed to the request + :param time_min: Lower bound for time-filter. Passed Datetime objects will be interpreted as UTC. + :param time_max: Upper bound for time-filter. Passed Datetime objects will be interpreted as UTC. - An examplary raw filter would be "cat_technology=4G" - Detailed information about the possible filters is available under: https://www.netztest.at/en/OpenDataSpecification.html + :gps_boundaries: GeoSeries in EPSG:4326 of the boundaries to filter for. + :cat_technology: CatTechnology to filter for. Examples are 3G and 4G. + + :max_results: Upper limit of measurements to fetch. + + :raw_params: Passed raw parameter tuples will be appended to the request url as key, value pairs. + + :return: A pandas dataframe consisting of all the fetched measurements. """ url = f"{BASE_URL}/{SUBDOMAIN_OVERVIEW}" request_params = MultiDict() - """ - Build request params - """ + #Build the request parameters if gps_boundaries is not None: if gps_boundaries.crs != "EPSG:4326": diff --git a/measprocess/geospatial.py b/measprocess/geospatial.py index 58ff7e3d130e27078f01eb8aec56046ae630e8e1..b01f931f3499997aa9f88d98d9756a7bd714695b 100644 --- a/measprocess/geospatial.py +++ b/measprocess/geospatial.py @@ -118,14 +118,32 @@ def project_onto_streets( plot: bool = False, ) -> (gpd.GeoSeries, gpd.GeoSeries): """ - Todo: Not completed + Projects each point from the point_series onto the closest element of + street_series according to a normal projection. For that, both + series will be transformed into a 2D projection (default EPSG:31287). + + :param point_series: GeoSeries of all points to project onto streets. + :param street_series: GeoSeries of linestrings representing the streets. + :param epsg: EPSG projection to use during the projection operation. + :param plot: Boolean to indiceate whether the result of the operation shall be plotted. + + :return: A tuple of two GeoSeries containing the result of the operation as well as the deviation introduced. """ - if point_series.crs != epsg or street_series.crs != epsg: + if epsg == "EPSG:4326": raise ValueError( - "GeoSeries does not match value set by epsg argument (Default EPSG:31287)" + "Projection cannot be conducted using geographical coordinates such as EPSG:4326. Select 2D projection instead." ) + if point_series.crs is None or street_series.crs is None: + raise ValueError( + "CRS needs to be set explicitly for passed Geoseries: Use .set_crs()." + ) + + point_original_crs, street_original_crs = point_series.crs, street_series.crs + point_series = point_series.to_crs(epsg) + street_series = street_series.to_crs(epsg) + projected = [] for point in point_series: street_ind = street_series.distance(point).argmin() @@ -161,6 +179,11 @@ def project_onto_streets( ax2.legend() plt.show() + #Reset Street and Point Series CRS + street_series.to_crs(street_original_crs) + point_series.to_crs(point_original_crs) + projected.to_crs(point_original_crs) + return projected, deviation_projection diff --git a/tests/projection_test.py b/tests/projection_test.py index 21bd5efe93ae7b1a2e38a727091cc6349f8825ee..375671254fdd1c2836b5672e451eb37e43435d68 100644 --- a/tests/projection_test.py +++ b/tests/projection_test.py @@ -31,11 +31,12 @@ class TestProjections(unittest.TestCase): def test_other_projection(self): mpc.geospatial.project_onto_streets( - self._point_series.set_crs("EPSG:3416"), - self._street_series.set_crs("EPSG:3416"), - epsg="EPSG:3416" + self._point_series.set_crs("EPSG:4326"), + self._street_series.set_crs("EPSG:4326"), + epsg="EPSG:31287" ) + def test_exception_epsg(self): with self.assertRaises(ValueError): mpc.geospatial.project_onto_streets( @@ -44,10 +45,11 @@ class TestProjections(unittest.TestCase): epsg="EPSG:31287" ) + with self.assertRaises(ValueError): mpc.geospatial.project_onto_streets( - self._point_series.set_crs("EPSG:31287"), - self._street_series.set_crs("EPSG:31287"), - epsg="EPSG:3416" + self._point_series.set_crs("EPSG:4326"), + self._street_series.set_crs("EPSG:4326"), + epsg="EPSG:4326" ) def test_basic_projection(self):