Skip to content

Commit ca9da08

Browse files
authored
Update geojson_layer function (#1049)
* Update geojson_layer function * Update layer name
1 parent c062e31 commit ca9da08

File tree

1 file changed

+84
-41
lines changed

1 file changed

+84
-41
lines changed

leafmap/leafmap.py

+84-41
Original file line numberDiff line numberDiff line change
@@ -6290,106 +6290,149 @@ def right_change(change):
62906290

62916291

62926292
def geojson_layer(
6293-
in_geojson: Union[str, dict],
6294-
layer_name: str = "Untitled",
6293+
in_geojson: Union[str, Dict],
6294+
layer_name: Optional[str] = "GeoJSON",
62956295
style: Optional[dict] = {},
62966296
hover_style: Optional[dict] = {},
62976297
style_callback: Optional[Callable] = None,
62986298
fill_colors: Optional[list[str]] = None,
62996299
encoding: Optional[str] = "utf-8",
6300+
**kwargs,
63006301
) -> None:
63016302
"""Adds a GeoJSON file to the map.
63026303
63036304
Args:
6304-
in_geojson (str | dict): The file path or http URL to the input GeoJSON
6305-
or a dictionary containing the geojson.
6306-
layer_name (str, optional): The layer name to be used.. Defaults to "Untitled".
6307-
style (dict, optional): A dictionary specifying the style to be used. Defaults to {}.
6305+
in_geojson (str | dict): The file path or http URL to the input
6306+
GeoJSON or a dictionary containing the geojson.
6307+
layer_name (str, optional): The layer name to be used.. Defaults to
6308+
"GeoJSON".
6309+
style (dict, optional): A dictionary specifying the style to be used.
6310+
Defaults to {}.
63086311
hover_style (dict, optional): Hover style dictionary. Defaults to {}.
6309-
style_callback (function, optional): Styling function that is called for
6310-
each feature, and should return the feature style. This styling
6311-
function takes the feature as argument. Defaults to None.
6312-
fill_colors (list, optional): The random colors to use for filling polygons.
6313-
Defaults to ["black"].
6314-
info_mode (str, optional): Displays the attributes by either on_hover or
6315-
on_click. Any value other than "on_hover" or "on_click" will be
6316-
treated as None. Defaults to "on_hover".
6317-
encoding (str, optional): The encoding of the GeoJSON file. Defaults to "utf-8".
6312+
style_callback (function, optional): Styling function that is called
6313+
for each feature, and should return the feature style. This
6314+
styling function takes the feature as argument. Defaults to None.
6315+
fill_colors (list, optional): The random colors to use for filling
6316+
polygons. Defaults to ["black"].
6317+
info_mode (str, optional): Displays the attributes by either on_hover
6318+
or on_click. Any value other than "on_hover" or "on_click" will
6319+
be treated as None. Defaults to "on_hover".
6320+
zoom_to_layer (bool, optional): Whether to zoom to the layer after
6321+
adding it to the map. Defaults to False.
6322+
encoding (str, optional): The encoding of the GeoJSON file. Defaults
6323+
to "utf-8".
63186324
63196325
Raises:
63206326
FileNotFoundError: The provided GeoJSON file could not be found.
63216327
"""
6328+
import shutil
63226329
import json
63236330
import random
6324-
import requests
6325-
6326-
style_callback_only = False
6331+
import geopandas as gpd
63276332

6328-
if len(style) == 0 and style_callback is not None:
6329-
style_callback_only = True
6333+
gdf = None
63306334

63316335
try:
63326336
if isinstance(in_geojson, str):
63336337
if in_geojson.startswith("http"):
6334-
in_geojson = common.github_raw_url(in_geojson)
6335-
data = requests.get(in_geojson).json()
6338+
if common.is_jupyterlite():
6339+
import pyodide # pylint: disable=E0401
6340+
6341+
output = os.path.basename(in_geojson)
6342+
6343+
output = os.path.abspath(output)
6344+
obj = pyodide.http.open_url(in_geojson)
6345+
with open(output, "w") as fd:
6346+
shutil.copyfileobj(obj, fd)
6347+
with open(output, "r") as fd:
6348+
data = json.load(fd)
6349+
else:
6350+
gdf = gpd.read_file(in_geojson, encoding=encoding)
6351+
63366352
else:
6337-
in_geojson = os.path.abspath(in_geojson)
6338-
if not os.path.exists(in_geojson):
6339-
raise FileNotFoundError(
6340-
"The provided GeoJSON file could not be found."
6341-
)
6353+
gdf = gpd.read_file(in_geojson, encoding=encoding)
63426354

6343-
with open(in_geojson, encoding=encoding) as f:
6344-
data = json.load(f)
63456355
elif isinstance(in_geojson, dict):
6346-
data = in_geojson
6356+
gdf = gpd.GeoDataFrame.from_features(in_geojson)
6357+
elif isinstance(in_geojson, gpd.GeoDataFrame):
6358+
gdf = in_geojson
63476359
else:
63486360
raise TypeError("The input geojson must be a type of str or dict.")
63496361
except Exception as e:
63506362
raise Exception(e)
63516363

6352-
if not style:
6364+
if gdf.crs is None:
6365+
print(f"Warning: The dataset does not have a CRS defined. Assuming EPSG:4326.")
6366+
gdf.crs = "EPSG:4326"
6367+
elif gdf.crs != "EPSG:4326":
6368+
gdf = gdf.to_crs("EPSG:4326")
6369+
data = gdf.__geo_interface__
6370+
6371+
try:
6372+
first_feature = data["features"][0]
6373+
if isinstance(first_feature["properties"].get("style"), str):
6374+
# Loop through the features and update the style
6375+
for feature in data["features"]:
6376+
fstyle = feature["properties"].get("style")
6377+
if isinstance(fstyle, str):
6378+
feature["properties"]["style"] = json.loads(fstyle)
6379+
except Exception as e:
6380+
print(e)
6381+
pass
6382+
6383+
geom_type = gdf.reset_index().geom_type[0]
6384+
6385+
if style is None and (style_callback is None):
63536386
style = {
63546387
# "stroke": True,
6355-
"color": "#000000",
6356-
"weight": 1,
6388+
"color": "#3388ff",
6389+
"weight": 2,
63576390
"opacity": 1,
6358-
# "fill": True,
6359-
# "fillColor": "#ffffff",
6360-
"fillOpacity": 0.1,
6391+
"fill": True,
6392+
"fillColor": "#3388ff",
6393+
"fillOpacity": 0.2,
63616394
# "dashArray": "9"
63626395
# "clickable": True,
63636396
}
6397+
6398+
if geom_type in ["LineString", "MultiLineString"]:
6399+
style["fill"] = False
6400+
63646401
elif "weight" not in style:
63656402
style["weight"] = 1
63666403

63676404
if not hover_style:
6368-
hover_style = {"weight": style["weight"] + 1, "fillOpacity": 0.5}
6405+
hover_style = {
6406+
"weight": style["weight"] + 2,
6407+
"fillOpacity": 0,
6408+
"color": "yellow",
6409+
}
63696410

63706411
def random_color(feature):
63716412
return {
63726413
"color": "black",
63736414
"fillColor": random.choice(fill_colors),
63746415
}
63756416

6376-
if style_callback is None:
6417+
if fill_colors is not None:
63776418
style_callback = random_color
63786419

6379-
if style_callback_only:
6420+
if style_callback is None:
63806421
geojson = ipyleaflet.GeoJSON(
63816422
data=data,
6423+
style=style,
63826424
hover_style=hover_style,
6383-
style_callback=style_callback,
63846425
name=layer_name,
6426+
**kwargs,
63856427
)
63866428
else:
63876429
geojson = ipyleaflet.GeoJSON(
63886430
data=data,
63896431
style=style,
63906432
hover_style=hover_style,
6391-
style_callback=style_callback,
63926433
name=layer_name,
6434+
style_callback=style_callback,
6435+
**kwargs,
63936436
)
63946437

63956438
return geojson

0 commit comments

Comments
 (0)