diff --git a/README.md b/README.md index 2278292..347524d 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,16 @@ fig = Plot( fig.savefig("map.jpg") ``` +You can also plot exported OSM XML files e.g. from openstreetmap.org: + +```python +from prettymapp.osm import get_osm_geometries_from_xml + +df = get_osm_geometries_from_xml(filepath="Berlin.osm") +aoi_bounds = df.total_bounds +... +``` + To customize the map appearance, use the additional arguments of the [`Plot`](plotting.py#L36) class (e.g. `shape`, `contour_width` etc.). Check the preconfigured [styles](prettymapp/settings.py#L35) and webapp [examples](streamlit-prettymapp/examples.json) for inspiration. diff --git a/prettymapp/osm.py b/prettymapp/osm.py index 15c0f8b..55b7c45 100644 --- a/prettymapp/osm.py +++ b/prettymapp/osm.py @@ -1,4 +1,7 @@ -from osmnx.features import features_from_polygon +from typing import Union +from pathlib import Path + +from osmnx.features import features_from_polygon, features_from_xml from osmnx import settings from geopandas import clip, GeoDataFrame from shapely.geometry import Polygon @@ -11,6 +14,9 @@ def get_osm_tags(): + """ + Get relevant OSM tags for use with prettymapp + """ tags: dict = {} for d in LC_SETTINGS.values(): # type: ignore for k, v in d.items(): # type: ignore @@ -21,11 +27,14 @@ def get_osm_tags(): return tags -def cleanup_osm_df(df: GeoDataFrame, aoi: Polygon) -> GeoDataFrame: +def cleanup_osm_df(df: GeoDataFrame, aoi: Union[Polygon, None] = None) -> GeoDataFrame: + """ + Cleanup of queried osm geometries to relevant level for use with prettymapp + """ df = df.droplevel(level=0) df = df[~df.geometry.geom_type.isin(["Point", "MultiPoint"])] - - df = clip(df, aoi) + if aoi is not None: + df = clip(df, aoi) df = explode_multigeometries(df) df["landcover_class"] = None @@ -52,7 +61,29 @@ def cleanup_osm_df(df: GeoDataFrame, aoi: Polygon) -> GeoDataFrame: def get_osm_geometries(aoi: Polygon) -> GeoDataFrame: + """ + Query OSM features within a polygon geometry. + + Args: + aoi: Polygon geometry query boundary. + """ tags = get_osm_tags() df = features_from_polygon(polygon=aoi, tags=tags) df = cleanup_osm_df(df, aoi) return df + + +def get_osm_geometries_from_xml( + filepath: Union[str, Path], aoi: Union[Polygon, None] = None +) -> GeoDataFrame: + """ + Query OSM features in an OSM-formatted XML file. + + Args: + filepath: path to file containing OSM XML data + aoi: Optional geographic boundary to filter elements + """ + tags = get_osm_tags() + df = features_from_xml(filepath, polygon=aoi, tags=tags) + df = cleanup_osm_df(df, aoi) + return df diff --git a/prettymapp/tests/mock_data/osm_export_xml.osm b/prettymapp/tests/mock_data/osm_export_xml.osm new file mode 100644 index 0000000..7b2a478 --- /dev/null +++ b/prettymapp/tests/mock_data/osm_export_xml.osm @@ -0,0 +1,1034 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/prettymapp/tests/test_osm.py b/prettymapp/tests/test_osm.py new file mode 100644 index 0000000..8300167 --- /dev/null +++ b/prettymapp/tests/test_osm.py @@ -0,0 +1,43 @@ +from prettymapp.osm import get_osm_tags, get_osm_geometries_from_xml + + +def test_get_osm_tags(): + tags = get_osm_tags() + assert tags == { + "building": True, + "landuse": [ + "construction", + "commercial", + "forest", + "grass", + "vineyard", + "orchard", + "village_green", + ], + "natural": ["water", "bay", "island", "wood"], + "place": ["sea"], + "leisure": ["swimming_pool", "park", "pitch", "garden", "golf_course"], + "highway": [ + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "cycleway", + "residential", + "service", + "unclassified", + "footway", + "motorway_link", + "pedestrian", + ], + "railway": True, + "amenity": ["parking"], + "man_made": ["pier"], + } + + +def test_get_osm_geometries_from_xml(): + filepath = "./mock_data/osm_export_xml.osm" + df = get_osm_geometries_from_xml(filepath) + assert df.shape == (18, 3)