Skip to content

OSMWayLoader

srai.loaders.OSMWayLoader(
    network_type,
    contain_within_area=False,
    preprocess=True,
    wide=True,
    metadata=False,
    osm_way_tags=constants.OSM_WAY_TAGS,
)

Bases: Loader

OSMWayLoader downloads road infrastructure from OSM.

OSMWayLoader loader is a wrapper for the osmnx.graph_from_polygon() and osmnx.graph_to_gdfs() that simplifies obtaining the road infrastructure data from OpenStreetMap. As the OSM data is often noisy, it can also take an opinionated approach to preprocessing it, with standardisation in mind - e.g. unification of units, discarding non-wiki values and rounding them.

PARAMETER DESCRIPTION
network_type

Type of the network to download.

TYPE: Union[NetworkType, str]

contain_within_area

defaults to False Whether to remove the roads that have one of their nodes outside of the given area.

TYPE: bool DEFAULT: False

preprocess

defaults to True Whether to preprocess the data.

TYPE: bool DEFAULT: True

wide

defaults to True Whether to return the roads in wide format.

TYPE: bool DEFAULT: True

metadata

defaults to False Whether to return metadata for roads.

TYPE: bool DEFAULT: False

osm_way_tags

defaults to constants.OSM_WAY_TAGS Dict of tags to take into consideration during computing.

TYPE: List[str] DEFAULT: constants.OSM_WAY_TAGS

Source code in srai/loaders/osm_way_loader/osm_way_loader.py
def __init__(
    self,
    network_type: Union[OSMNetworkType, str],
    contain_within_area: bool = False,
    preprocess: bool = True,
    wide: bool = True,
    metadata: bool = False,
    osm_way_tags: dict[str, list[str]] = constants.OSM_WAY_TAGS,
) -> None:
    """
    Init OSMWayLoader.

    Args:
        network_type (Union[NetworkType, str]):
            Type of the network to download.
        contain_within_area (bool): defaults to False
            Whether to remove the roads that have one of their nodes outside of the given area.
        preprocess (bool): defaults to True
            Whether to preprocess the data.
        wide (bool): defaults to True
            Whether to return the roads in wide format.
        metadata (bool): defaults to False
            Whether to return metadata for roads.
        osm_way_tags (List[str]): defaults to constants.OSM_WAY_TAGS
            Dict of tags to take into consideration during computing.
    """
    import_optional_dependencies(dependency_group="osm", modules=["osmnx"])

    self.network_type = network_type
    self.contain_within_area = contain_within_area
    self.preprocess = preprocess
    self.wide = wide
    self.metadata = metadata
    self.osm_keys = list(osm_way_tags.keys())
    self.osm_tags_flat = (
        seq(osm_way_tags.items())
        .flat_map(lambda x: [f"{x[0]}-{v}" if x[0] not in ("oneway") else x[0] for v in x[1]])
        .distinct()
        .to_list()
    )

load(area)

Load road infrastructure for a given GeoDataFrame.

PARAMETER DESCRIPTION
area

(Multi)Polygons for which to download road infrastructure data.

TYPE: gpd.GeoDataFrame

RAISES DESCRIPTION
ValueError

If provided GeoDataFrame has no crs defined.

ValueError

If provided GeoDataFrame is empty.

TypeError

If provided geometries are not of type Polygon or MultiPolygon.

LoadedDataIsEmptyException

If none of the supplied area polygons contains any road infrastructure data.

RETURNS DESCRIPTION
tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]

Tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]: Road infrastructure as (intersections, roads)

Source code in srai/loaders/osm_way_loader/osm_way_loader.py
def load(self, area: gpd.GeoDataFrame) -> tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]:
    """
    Load road infrastructure for a given GeoDataFrame.

    Args:
        area (gpd.GeoDataFrame): (Multi)Polygons for which to download road infrastructure data.

    Raises:
        ValueError: If provided GeoDataFrame has no crs defined.
        ValueError: If provided GeoDataFrame is empty.
        TypeError: If provided geometries are not of type Polygon or MultiPolygon.
        LoadedDataIsEmptyException: If none of the supplied area polygons contains
            any road infrastructure data.

    Returns:
        Tuple[gpd.GeoDataFrame, gpd.GeoDataFrame]: Road infrastructure as (intersections, roads)
    """
    import osmnx as ox

    ox.settings.useful_tags_way = constants.OSMNX_WAY_KEYS
    ox.settings.timeout = constants.OSMNX_TIMEOUT

    if area.empty:
        raise ValueError("Provided `area` GeoDataFrame is empty.")

    gdf_wgs84 = area.to_crs(crs=WGS84_CRS)

    gdf_nodes_raw, gdf_edges_raw = self._graph_from_gdf(gdf_wgs84)
    if gdf_edges_raw.empty or gdf_edges_raw.empty:
        raise LoadedDataIsEmptyException(
            "It can happen when there is no road infrastructure in the given area."
        )

    gdf_edges = self._explode_cols(gdf_edges_raw)

    if self.preprocess:
        gdf_edges = self._preprocess(gdf_edges)

    if self.wide:
        gdf_edges = self._to_wide(gdf_edges_raw, gdf_edges)

    gdf_edges = self._unify_index_and_columns_names(gdf_edges)

    return gdf_nodes_raw, gdf_edges