Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppose styling of feature group objects by rendering feature group before generating js #147

Merged
merged 5 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions examples/pages/geojson_styles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import folium
import geopandas as gpd
import shapely
import streamlit as st

from streamlit_folium import st_folium

st.title("GeoJSON Styling")

START_LOCATION = [37.7934347109497, -122.399077892527]
START_ZOOM = 18

wkt = (
"POLYGON ((-122.399077892527 37.7934347109497, -122.398922660838 "
"37.7934544916178, -122.398980265018 37.7937266504805, -122.399133972495 "
"37.7937070646238, -122.399077892527 37.7934347109497))"
)
polygon_ = shapely.wkt.loads(wkt)
gdf = gpd.GeoDataFrame(geometry=[polygon_]).set_crs(epsg=4326)

style_parcels = {"fillColor": "red", "fillOpacity": 0.2}

polygon_folium = folium.GeoJson(data=gdf, style_function=lambda x: style_parcels)

map = folium.Map(
location=START_LOCATION, zoom_start=START_ZOOM, tiles="OpenStreetMap", max_zoom=21
)
fg = folium.FeatureGroup(name="Parcels")
fg = fg.add_child(polygon_folium)

st_folium(
map,
width=800,
height=450,
feature_group_to_add=fg,
debug=True,
)
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
streamlit>=1.13.0
folium>=0.13
jinja2
branca
branca
geopandas
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setuptools.setup(
name="streamlit_folium",
version="0.15.0",
version="0.15.1",
author="Randy Zwitch",
author_email="[email protected]",
description="Render Folium objects in Streamlit",
Expand Down
17 changes: 17 additions & 0 deletions streamlit_folium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import branca
import folium
import folium.plugins
import streamlit as st
import streamlit.components.v1 as components
from jinja2 import UndefinedError

Expand Down Expand Up @@ -153,6 +154,7 @@ def _get_feature_group_string(
) -> str:
feature_group_to_add._id = "feature_group"
feature_group_to_add.add_to(map)
feature_group_to_add.render()
feature_group_string = generate_leaflet_string(
feature_group_to_add, base_id="feature_group"
)
Expand Down Expand Up @@ -180,6 +182,7 @@ def st_folium(
feature_group_to_add: folium.FeatureGroup | None = None,
return_on_hover: bool = False,
use_container_width: bool = False,
debug: bool = False,
):
"""Display a Folium object in Streamlit, returning data as user interacts
with app.
Expand Down Expand Up @@ -218,6 +221,9 @@ def st_folium(
use_container_width: bool
If True, set the width of the map to the width of the current container.
This overrides the `width` parameter.
debug: bool
If True, print out the html and javascript code used to render the map with
st.code
Returns
-------
dict
Expand Down Expand Up @@ -298,6 +304,17 @@ def bounds_to_dict(bounds_list: List[List[float]]) -> Dict[str, Dict[str, float]
map=folium_map,
)

if debug:
with st.expander("Show generated code"):
st.info("HTML:")
st.code(html)
st.info("Main Map Leaflet js:")
st.code(leaflet)

if feature_group_string is not None:
st.info("Feature group js:")
st.code(feature_group_string)

component_value = _component_func(
script=leaflet,
html=html,
Expand Down
3 changes: 2 additions & 1 deletion tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ streamlit>1.11.1
pytest>=7.1.2
folium>=0.13
pytest-playwright
pytest-rerunfailures
pytest-rerunfailures
geopandas
8 changes: 8 additions & 0 deletions tests/test_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
page.get_by_role("link", name="simple popup").click()
page.get_by_role("link", name="simple popup").click()

expect(page.get_by_text("Popup: None")).to_be_visible()

Check failure on line 189 in tests/test_frontend.py

View workflow job for this annotation

GitHub Actions / build (3.10)

test_return_on_hover[chromium] AssertionError: Locator expected to be visible Actual value: None Call log: LocatorAssertions.to_be_visible with timeout 5000ms waiting for get_by_text("Popup: None")
expect(page.get_by_text("Tooltip: None")).to_be_visible()

page.get_by_text("Return on hover?").click()
Expand All @@ -209,9 +209,9 @@
page.set_viewport_size({"width": 500, "height": 3000})

initial_bbox = (
page.frame_locator("div:nth-child(2) > iframe")

Check failure on line 212 in tests/test_frontend.py

View workflow job for this annotation

GitHub Actions / build (3.8)

test_responsiveness[chromium] playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded. =========================== logs =========================== waiting for frame_locator("div:nth-child(2) > iframe").locator("#map_div") ============================================================

Check failure on line 212 in tests/test_frontend.py

View workflow job for this annotation

GitHub Actions / build (3.9)

test_responsiveness[chromium] playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded. =========================== logs =========================== waiting for frame_locator("div:nth-child(2) > iframe").locator("#map_div") ============================================================
.locator("#map_div")
.bounding_box()

Check failure on line 214 in tests/test_frontend.py

View workflow job for this annotation

GitHub Actions / build (3.11)

test_responsiveness[chromium] playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded. =========================== logs =========================== waiting for frame_locator("div:nth-child(2) > iframe").locator("#map_div") ============================================================

Check failure on line 214 in tests/test_frontend.py

View workflow job for this annotation

GitHub Actions / build (3.11)

test_responsiveness[chromium] playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded. =========================== logs =========================== waiting for frame_locator("div:nth-child(2) > iframe").locator("#map_div") ============================================================
)

page.set_viewport_size({"width": 1000, "height": 3000})
Expand All @@ -234,3 +234,11 @@
assert new_bbox["width"] > initial_bbox["width"] + 300

page.set_viewport_size({"width": 2000, "height": 2000})


def test_geojson_styles(page: Page):
page.get_by_role("link", name="geojson styles").click()
page.get_by_role("link", name="geojson styles").click()

page.get_by_text("Show generated code").click()
expect(page.get_by_text('"fillOpacity"')).to_be_visible()
Loading