def _build_relation_geometry(
    members: list[dict[str, Any]],
    way_geoms: dict[int, LineString | Polygon],
) -> Polygon | MultiPolygon:
    """
    Build a relation's geometry from its constituent member ways' geometries.

    OSM represents simple polygons as closed ways (see `_build_way_geometry`),
    but it uses relations to represent multipolygons (with or without holes)
    and polygons with holes. For the former, the relation contains multiple
    members with role "outer". For the latter, the relation contains at least
    one member with role "outer" representing the shell(s), and at least one
    member with role "inner" representing the hole(s). For documentation, see
    https://wiki.openstreetmap.org/wiki/Relation:multipolygon

    Parameters
    ----------
    members
        The members constituting the relation.
    way_geoms
        Keyed by OSM way ID with values of their geometries.

    Returns
    -------
    geometry
        The relation's geometry.
    """
    inner_linestrings = []
    outer_linestrings = []
    inner_polygons = []
    outer_polygons = []

    # sort member geometries by member role and geometry type
    for member in members:
        if member["type"] == "way":
            geom = way_geoms[member["ref"]]
            role = member["role"]
            if role == "outer" and geom.geom_type == "LineString":
                outer_linestrings.append(geom)
            elif role == "outer" and geom.geom_type == "Polygon":
                outer_polygons.append(geom)
            elif role == "inner" and geom.geom_type == "LineString":
                inner_linestrings.append(geom)
            elif role == "inner" and geom.geom_type == "Polygon":
                inner_polygons.append(geom)

    # merge/polygonize outer linestring fragments then add to outer polygons
    merged_outer_linestrings = linemerge(outer_linestrings)
    if merged_outer_linestrings.geom_type == "LineString":
        merged_outer_linestrings = MultiLineString([merged_outer_linestrings])
    for merged_outer_linestring in merged_outer_linestrings.geoms:
        outer_polygons += polygonize(merged_outer_linestring)

    # merge/polygonize inner linestring fragments then add to inner polygons
    merged_inner_linestrings = linemerge(inner_linestrings)
    if merged_inner_linestrings.geom_type == "LineString":
        merged_inner_linestrings = MultiLineString([merged_inner_linestrings])
    for merged_inner_linestring in merged_inner_linestrings.geoms:
        inner_polygons += polygonize(merged_inner_linestring)

    # remove holes from polygons, if any, then retun
    return _remove_polygon_holes(outer_polygons, inner_polygons)

    Build a relation's geometry from its constituent member ways' geometries.

    OSM represents simple polygons as closed ways (see `_build_way_geometry`),
    but it uses relations to represent multipolygons (with or without holes)
    and polygons with holes. For the former, the relation contains multiple
    members with role "outer". For the latter, the relation contains at least
    one member with role "outer" representing the shell(s), and at least one
    member with role "inner" representing the hole(s). For documentation, see
    https://wiki.openstreetmap.org/wiki/Relation:multipolygon

    Parameters
    ----------
    members
        The members constituting the relation.
    way_geoms
        Keyed by OSM way ID with values of their geometries.

    Returns
    -------
    geometry
        The relation's geometry.
    
osmnx/features.py