`import leafmap.leafmap as leafmap` is unable to `add_gdf` if "style" column is present
patel-zeel opened this issue · 4 comments
Environment Information
- leafmap version: 0.38.6
- Python version: 3.10.12
- Operating System: Ubuntu 20.04.6 LTS
Description
When GeoPandas loads a GeoJSON with "style" present in "properties" of the GeoJSON features, by default, all elements in "style" column are in str format. This works fine with import leafmap.foliumap as leafmap
but fails with import leafmap.leafmap as leafmap
. Here is the MWE:
show_what_fails = True
if show_what_fails:
import leafmap.leafmap as leafmap
else:
import leafmap.foliumap as leafmap
collection = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[80.778174, 26.654166],
[80.778882, 26.65477],
[80.778657, 26.654981],
[80.777949, 26.654377],
[80.778174, 26.654166]
]
]
},
"properties": {
"name": "Example",
"style": {
"color": "red",
},
}
}]
}
# Create a GeoDataFrame from collection
gdf = gpd.GeoDataFrame.from_features(collection)
print(type(gdf.iloc[0].style)) # This is a dict
# Save it to a file
gdf.to_file("/tmp/tmp.geojson", driver="GeoJSON")
# Load back from file
gdf = gpd.read_file("/tmp/tmp.geojson")
print(type(gdf.iloc[0].style)) # This is a str
m = leafmap.Map()
m.add_gdf(gdf)
m
This is an issue with ipyleaflet rather than leafmap. After saving the file as GeoJSON, the style becomes a string. iypleaflet tries to copy the style, which is supposed to be a dict.
{'type': 'FeatureCollection',
'features': [{'id': '0',
'type': 'Feature',
'properties': {'name': 'Example', 'style': '{ "color": "red" }'},
'geometry': {'type': 'Polygon',
'coordinates': (((80.778174, 26.654166),
(80.778882, 26.65477),
(80.778657, 26.654981),
(80.777949, 26.654377),
(80.778174, 26.654166)),)},
'bbox': (80.777949, 26.654166, 80.778882, 26.654981)}],
'bbox': (80.777949, 26.654166, 80.778882, 26.654981)}
`File ~/miniconda3/envs/geo/lib/python3.12/site-packages/ipyleaflet/leaflet.py:1736, in GeoJSON._apply_style(self, feature, style_callback)
1734 properties = feature["properties"]
1735 if "style" in properties:
-> 1736 style = properties["style"].copy()
1737 style.update(style_callback(feature))
1738 properties["style"] = style
AttributeError: 'str' object has no attribute 'copy'`
True, Prof. @giswqs. I also checked GeoJSON standard documentation, and it seems that the usage of "style" was not thought of in the design. For that reason, it converts only geometry
column to shapely
objects but treats everything else as str
, except basic datatypes such as int
, float
, bool
etc. So, ideally major user of "style" attribute (ipyleaflet) should fix this issue and not GeoPandas. If ipyleaflet
solves this, it should automatically get solved in leafmap
.
I will raise the issue with ipyleaflet
.
No worries. I am fixing it.
Thank you, Prof. @giswqs. Do you think fixing this inside ipyleaflet
would also be helpful for a larger community? I am thinking of raising an issue there as well.