diff --git a/ohsome/helper.py b/ohsome/helper.py index 57dc257..a34e4f9 100644 --- a/ohsome/helper.py +++ b/ohsome/helper.py @@ -182,9 +182,9 @@ def format_bboxes( ) elif isinstance(bboxes, str): return bboxes - elif isinstance(bboxes, gpd.GeoDataFrame): + elif isinstance(bboxes, gpd.GeoDataFrame) or isinstance(bboxes, gpd.GeoSeries): raise OhsomeException( - message="Use the 'bpolys' parameter to specify the boundaries using a geopandas.GeoDataFrame." + message="Use the 'bpolys' parameter to specify the boundaries using a geopandas object." ) elif isinstance(bboxes, pd.DataFrame): try: @@ -204,29 +204,34 @@ def format_bboxes( def format_bpolys( - bpolys: Union[gpd.GeoDataFrame, shapely.Polygon, shapely.MultiPolygon, str] + bpolys: Union[ + gpd.GeoDataFrame, gpd.GeoSeries, shapely.Polygon, shapely.MultiPolygon, str + ] ) -> str: """ Formats bpolys parameter to comply with ohsome API :param - bpolys: Polygons given as geopandas.GeoDataFrame or string formatted as GeoJSON FeatureCollection. + bpolys: Polygons given as geopandas.GeoDataFrame, geopandas.GeoSeries, Shapely.Polygon or GeoJSON FeatureCollection as string. :return: """ - if isinstance(bpolys, gpd.GeoDataFrame) or isinstance(bpolys, gpd.GeoSeries): - return bpolys.to_json(na="drop") + if isinstance(bpolys, gpd.GeoDataFrame): + return bpolys.to_json(na="drop", show_bbox=False, drop_id=False, to_wgs84=True) + elif isinstance(bpolys, gpd.GeoSeries): + return format_bpolys(bpolys.to_frame("geometry")) elif isinstance(bpolys, shapely.Polygon) or isinstance( bpolys, shapely.MultiPolygon ): - return format_bpolys(gpd.GeoDataFrame(geometry=[bpolys])) + return format_bpolys(gpd.GeoDataFrame(geometry=[bpolys], crs="EPSG:4326")) elif isinstance(bpolys, str): try: - return format_bpolys(gpd.GeoDataFrame.from_features(json.loads(bpolys))) + return format_bpolys( + gpd.GeoDataFrame.from_features(json.loads(bpolys), crs="EPSG:4326") + ) except Exception as e: raise OhsomeException(message="Invalid geojson.") from e else: raise OhsomeException( - message="bpolys must be a geojson string, a shapely polygonal object or a geopandas " - "object" + message="bpolys must be a geojson string, a shapely polygonal object or a geopandas object" ) diff --git a/ohsome/test/cassettes/test_client/test_format_bpolys.yaml b/ohsome/test/cassettes/test_client/test_format_bpolys.yaml deleted file mode 100644 index a44dbed..0000000 --- a/ohsome/test/cassettes/test_client/test_format_bpolys.yaml +++ /dev/null @@ -1,59 +0,0 @@ -interactions: -- request: - body: bpolys=%7B%22type%22%3A+%22FeatureCollection%22%2C+%22features%22%3A+%5B%7B%22id%22%3A+%220%22%2C+%22type%22%3A+%22Feature%22%2C+%22properties%22%3A+%7B%22id%22%3A+%220%22%7D%2C+%22geometry%22%3A+%7B%22type%22%3A+%22Polygon%22%2C+%22coordinates%22%3A+%5B%5B%5B8.695077896118164%2C+49.408711468953854%5D%2C+%5B8.699712753295898%2C+49.408711468953854%5D%2C+%5B8.699712753295898%2C+49.41155955732304%5D%2C+%5B8.695077896118164%2C+49.41155955732304%5D%2C+%5B8.695077896118164%2C+49.408711468953854%5D%5D%5D%7D%7D%2C+%7B%22id%22%3A+%221%22%2C+%22type%22%3A+%22Feature%22%2C+%22properties%22%3A+%7B%22id%22%3A+%221%22%7D%2C+%22geometry%22%3A+%7B%22type%22%3A+%22Polygon%22%2C+%22coordinates%22%3A+%5B%5B%5B8.677010536193848%2C+49.41370947536709%5D%2C+%5B8.682074546813965%2C+49.41370947536709%5D%2C+%5B8.682074546813965%2C+49.416641030041134%5D%2C+%5B8.677010536193848%2C+49.416641030041134%5D%2C+%5B8.677010536193848%2C+49.41370947536709%5D%5D%5D%7D%7D%5D%7D&time=2018-01-01&filter=amenity%3Drestaurant+and+type%3Anode - headers: - Accept: - - '*/*' - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '1013' - Content-Type: - - application/x-www-form-urlencoded - user-agent: - - ohsome-py/0.3.0 - method: POST - uri: https://api.ohsome.org/v1/elements/count - response: - body: - string: "{\n \"attribution\" : {\n \"url\" : \"https://ohsome.org/copyrights\",\n - \ \"text\" : \"\xA9 OpenStreetMap contributors\"\n },\n \"apiVersion\" - : \"1.10.1\",\n \"result\" : [ {\n \"timestamp\" : \"2018-01-01T00:00:00Z\",\n - \ \"value\" : 2.0\n } ]\n}" - headers: - Access-Control-Allow-Credentials: - - 'true' - Access-Control-Allow-Headers: - - Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization - Access-Control-Allow-Methods: - - POST, GET - Access-Control-Allow-Origin: - - '*' - Access-Control-Max-Age: - - '3600' - Cache-Control: - - no-transform, public, max-age=31556926 - Connection: - - Keep-Alive - Content-Encoding: - - gzip - Content-Type: - - application/json - Date: - - Wed, 06 Dec 2023 08:19:18 GMT - Keep-Alive: - - timeout=5, max=100 - Server: - - Apache - Strict-Transport-Security: - - max-age=63072000; includeSubdomains; - Transfer-Encoding: - - chunked - vary: - - accept-encoding - status: - code: 200 - message: '' -version: 1 diff --git a/ohsome/test/test_client.py b/ohsome/test/test_client.py index 77f53bf..25488a3 100644 --- a/ohsome/test/test_client.py +++ b/ohsome/test/test_client.py @@ -181,20 +181,6 @@ def test_format_bcircles_geodataframe_geometry_error(base_client): del client -@pytest.mark.vcr -def test_format_bpolys(base_client): - """ - Test whether a GeoDataFrame obejct is formatted correctly for ohsome api. - :return: - """ - bpolys = gpd.read_file(f"{script_path}/data/polygons.geojson") - time = "2018-01-01" - fltr = "amenity=restaurant and type:node" - - client = base_client - client.elements.count.post(bpolys=bpolys, time=time, filter=fltr) - - @pytest.mark.vcr def test_format_bboxes_dataframe(base_client): """ @@ -254,7 +240,7 @@ def test_format_bboxes_geodataframe(base_client): assert ( "Use the 'bpolys' parameter to specify the boundaries using a " - "geopandas.GeoDataFrame." in e_info.value.message + "geopandas object." in e_info.value.message ) diff --git a/ohsome/test/test_helper.py b/ohsome/test/test_helper.py index bcbd531..1732a15 100644 --- a/ohsome/test/test_helper.py +++ b/ohsome/test/test_helper.py @@ -7,6 +7,7 @@ import logging import os +import geopandas as gpd import numpy as np import pandas as pd import pytest @@ -225,13 +226,38 @@ def test_format_bpolys(): == "bolys must be a geojson string, a shapely polygonal object or a geopandas object" ) - with open(f"{script_path}/data/polygons.geojson") as geojson: - json_str = geojson.read() - assert json.loads(format_bpolys(json_str)) == json.loads(json_str) + geojson = json.dumps( + { + "type": "FeatureCollection", + "features": [ + { + "id": "0", + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0], [0.0, 0.0]] + ], + }, + } + ], + } + ) + + assert format_bpolys(geojson) == geojson polygon = Polygon(((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0))) - assert format_bpolys(polygon) == ( - '{"type": "FeatureCollection", "features": [{"id": "0", "type": "Feature", ' - '"properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[0.0, ' - "0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0], [0.0, 0.0]]]}}]}" + assert format_bpolys(polygon) == geojson + + series = gpd.GeoSeries( + data=[polygon], + crs="EPSG:4326", + ) + assert format_bpolys(series) == geojson + + df = gpd.GeoDataFrame( + geometry=[polygon], + crs="EPSG:4326", ) + assert format_bpolys(df) == geojson