def _create_gdf(
    response_jsons: Iterable[dict[str, Any]],
    polygon: Polygon | MultiPolygon,
    tags: dict[str, bool | str | list[str]],
) -> gpd.GeoDataFrame:
    """
    Convert Overpass API JSON responses to a GeoDataFrame of features.

    Parameters
    ----------
    response_jsons
        Iterable of Overpass API JSON responses.
    polygon
        Spatial boundaries to optionally filter the final GeoDataFrame.
    tags
        Query tags to optionally filter the final GeoDataFrame.

    Returns
    -------
    gdf
        GeoDataFrame of features with tags and geometry columns.
    """
    # consume response_jsons generator to download data from server
    elements = []
    response_count = 0
    for response_json in response_jsons:
        response_count += 1
        if not settings.cache_only_mode:
            elements.extend(response_json["elements"])

    msg = f"Retrieved {len(elements):,} elements from API in {response_count} request(s)"
    utils.log(msg, level=lg.INFO)
    if settings.cache_only_mode:
        msg = "Interrupted because `settings.cache_only_mode=True`."
        raise CacheOnlyInterruptError(msg)

    # convert the elements into a GeoDataFrame of features
    gdf = (
        gpd.GeoDataFrame(
            data=_process_features(elements, set(tags.keys())),
            geometry="geometry",
            crs=settings.default_crs,
        )
        .set_index(["element", "id"])
        .sort_index()
    )
    return _filter_features(gdf, polygon, tags)

    Convert Overpass API JSON responses to a GeoDataFrame of features.

    Parameters
    ----------
    response_jsons
        Iterable of Overpass API JSON responses.
    polygon
        Spatial boundaries to optionally filter the final GeoDataFrame.
    tags
        Query tags to optionally filter the final GeoDataFrame.

    Returns
    -------
    gdf
        GeoDataFrame of features with tags and geometry columns.
    
osmnx/features.py