Convert a Pandas or Polars DataFrame with a WKT geometry column to a GeoJSON FeatureCollection dict.
Parameters:
-
df
(DataFrame | DataFrame)
–
Input DataFrame. The geometry column must contain WKT strings in WGS84 (EPSG:4326).
GeoPandas GeoDataFrames are not supported; use :meth:Map.from_geodataframe instead.
-
geometry_col
(str, default:
'geometry'
)
–
Name of the column that contains WKT geometry strings. Defaults to "geometry".
Returns:
-
dict
–
A GeoJSON FeatureCollection dict ready for :meth:Map.add_geojson.
Raises:
-
TypeError
–
If df is not a recognised Pandas or Polars DataFrame.
-
ValueError
–
If geometry_col is not present in the DataFrame columns.
-
ValueError
–
If the DataFrame is empty (zero rows).
-
ValueError
–
If a WKT string in the geometry column cannot be parsed.
Warns:
-
UserWarning
–
When a row contains a None or empty geometry value; that row is skipped.
Examples:
>>> import pandas as pd
>>> df = pd.DataFrame({"geometry": ["POINT (4.9 52.37)"], "name": ["Amsterdam"]})
>>> fc = dataframe_to_geojson(df)
>>> fc["type"]
'FeatureCollection'
>>> len(fc["features"])
1
Source code in mapyta/dataframe.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 | def dataframe_to_geojson(df: Any, geometry_col: str = "geometry") -> dict: # noqa: ANN401
"""Convert a Pandas or Polars DataFrame with a WKT geometry column to a GeoJSON FeatureCollection dict.
Parameters
----------
df : pandas.DataFrame | polars.DataFrame
Input DataFrame. The geometry column must contain WKT strings in WGS84 (EPSG:4326).
GeoPandas GeoDataFrames are not supported; use :meth:`Map.from_geodataframe` instead.
geometry_col : str
Name of the column that contains WKT geometry strings. Defaults to ``"geometry"``.
Returns
-------
dict
A GeoJSON FeatureCollection dict ready for :meth:`Map.add_geojson`.
Raises
------
TypeError
If ``df`` is not a recognised Pandas or Polars DataFrame.
ValueError
If ``geometry_col`` is not present in the DataFrame columns.
ValueError
If the DataFrame is empty (zero rows).
ValueError
If a WKT string in the geometry column cannot be parsed.
Warns
-----
UserWarning
When a row contains a ``None`` or empty geometry value; that row is skipped.
Examples
--------
>>> import pandas as pd
>>> df = pd.DataFrame({"geometry": ["POINT (4.9 52.37)"], "name": ["Amsterdam"]})
>>> fc = dataframe_to_geojson(df)
>>> fc["type"]
'FeatureCollection'
>>> len(fc["features"])
1
"""
# --- Detect library and extract columns ---
if hasattr(df, "to_dicts"):
# Polars: columns is a list of strings
columns = df.columns
elif hasattr(df, "to_dict"):
# Pandas: columns is an Index, convert for consistent membership testing
columns = list(df.columns)
else:
raise TypeError(f"df must be a pandas or polars DataFrame, got {type(df).__name__!r}")
# --- Validate geometry column ---
if geometry_col not in columns:
raise ValueError(f"geometry column {geometry_col!r} not found. Available columns: {list(columns)}")
# --- Validate non-empty ---
if len(df) == 0:
raise ValueError("DataFrame is empty — nothing to add to the map.")
# --- Normalise to list[dict] ---
if hasattr(df, "to_dicts"):
records: list[dict] = df.to_dicts()
else:
records = df.to_dict(orient="records")
# --- Build GeoJSON features ---
features = []
for i, row in enumerate(records):
wkt_value = row.pop(geometry_col)
# Skip null / empty geometry rows (pandas converts None to float NaN in mixed columns)
if wkt_value is None or wkt_value == "" or (isinstance(wkt_value, float) and math.isnan(wkt_value)):
warnings.warn(f"Row {i}: geometry is null/empty — skipped.", UserWarning, stacklevel=2)
continue
# Parse WKT
try:
geom = shapely_wkt.loads(str(wkt_value))
except Exception as exc:
raise ValueError(f"Row {i}: invalid WKT {wkt_value!r} — {exc}") from exc
# Coerce numpy scalars in properties (pandas DataFrames may produce them)
props = {k: _coerce_value(v) for k, v in row.items()}
features.append({"type": "Feature", "geometry": mapping(geom), "properties": props})
return {"type": "FeatureCollection", "features": features}
|