From de5ddc65cd1db8b6867754a8a8884c3baeb0a1cb Mon Sep 17 00:00:00 2001 From: DefinitelyNotJosh1 Date: Mon, 7 Sep 2026 18:08:56 -0700 Subject: [PATCH] Fix bounds for multi-member and wrapped GeometryCollections --- folium/utilities.py | 16 ++++------------ tests/test_features.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/folium/utilities.py b/folium/utilities.py index 6a12e4bfbf..d6f40580b1 100644 --- a/folium/utilities.py +++ b/folium/utilities.py @@ -280,19 +280,11 @@ def iter_coords(obj: Any) -> Iterator[tuple[float, ...]]: if isinstance(obj, (tuple, list)): coords = obj elif "features" in obj: - coords = [ - geom["geometry"]["coordinates"] - for geom in obj["features"] - if geom["geometry"] - ] + coords = obj["features"] elif "geometry" in obj: - coords = obj["geometry"]["coordinates"] if obj["geometry"] else [] - elif ( - "geometries" in obj - and obj["geometries"][0] - and "coordinates" in obj["geometries"][0] - ): - coords = obj["geometries"][0]["coordinates"] + coords = [obj["geometry"]] if obj["geometry"] else [] + elif "geometries" in obj: + coords = obj["geometries"] else: coords = obj.get("coordinates", obj) for coord in coords: diff --git a/tests/test_features.py b/tests/test_features.py index 10a5ec6494..41498cabe1 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -388,6 +388,41 @@ def test_geometry_collection_get_bounds(): assert folium.GeoJson(geojson_data).get_bounds() == [[0, -3], [4, 2]] +@pytest.mark.parametrize("container", ["geometry", "feature", "feature_collection"]) +@pytest.mark.parametrize("collection", ["multiple", "nested", "empty"]) +def test_geometry_collection_bounds_all_members(container, collection): + geometries = [ + {"type": "Point", "coordinates": [2, 1]}, + {"type": "LineString", "coordinates": [[-3, 4], [40, 30]]}, + ] + expected = [[1, -3], [30, 40]] + if collection == "nested": + geometries = [ + {"type": "GeometryCollection", "geometries": []}, + {"type": "GeometryCollection", "geometries": geometries}, + ] + elif collection == "empty": + geometries = [] + expected = [[None, None], [None, None]] + + data = {"type": "GeometryCollection", "geometries": geometries} + if container != "geometry": + data = {"type": "Feature", "properties": {}, "geometry": data} + if container == "feature_collection": + data = { + "type": "FeatureCollection", + "features": [ + {"type": "Feature", "properties": {}, "geometry": None}, + data, + ], + } + + m = folium.Map() + layer = folium.GeoJson(data).add_to(m) + assert layer.get_bounds() == expected + assert m.get_bounds() == expected + + def test_choropleth_get_by_key(): geojson_data = { "id": "0",