def _merge_nodes_geometric(
    G: nx.MultiDiGraph,
    tolerance: float | dict[int, float],
) -> gpd.GeoSeries:
    """
    Geometrically merge nodes within some distance of each other.

    Parameters
    ----------
    G
        A projected graph.
    tolerance
        Nodes are buffered to this distance (in graph's geometry's units) and
        subsequent overlaps are dissolved into a single node. If scalar, then
        that single value will be used for all nodes. If dict (mapping node
        IDs to individual values), then those values will be used per node and
        any missing node IDs will not be buffered.

    Returns
    -------
    merged
        The merged overlapping polygons of the buffered nodes.
    """
    gdf_nodes = convert.graph_to_gdfs(G, edges=False)

    if isinstance(tolerance, dict):
        # create series of tolerances reindexed like nodes, then buffer, then
        # fill nulls (resulting from missing tolerances) with original points,
        # then merge overlapping geometries
        tols = pd.Series(tolerance).reindex(gdf_nodes.index)
        merged = gdf_nodes.buffer(tols).fillna(gdf_nodes["geometry"]).union_all()
    else:
        # buffer nodes then merge overlapping geometries
        merged = gdf_nodes.buffer(tolerance).union_all()

    # extract the member geometries if it's a multi-geometry
    merged = merged.geoms if hasattr(merged, "geoms") else merged
    return gpd.GeoSeries(merged, crs=G.graph["crs"])

    Geometrically merge nodes within some distance of each other.

    Parameters
    ----------
    G
        A projected graph.
    tolerance
        Nodes are buffered to this distance (in graph's geometry's units) and
        subsequent overlaps are dissolved into a single node. If scalar, then
        that single value will be used for all nodes. If dict (mapping node
        IDs to individual values), then those values will be used per node and
        any missing node IDs will not be buffered.

    Returns
    -------
    merged
        The merged overlapping polygons of the buffered nodes.
    
osmnx/simplification.py