jupyter-widgets / ipyleaflet

A Jupyter - Leaflet.js bridge
https://ipyleaflet.readthedocs.io
MIT License
1.49k stars 363 forks source link

DivIcon transparent background #798

Closed giswqs closed 1 year ago

giswqs commented 3 years ago

The DivIcon has a white background. Is it possible to make it transparent? Thanks.

Relevant issue: https://github.com/jupyter-widgets/ipyleaflet/issues/792 @deeplook

from ipyleaflet import Marker, DivIcon, Map

center = (52.204793, 360.121558)

m = Map(center=center, zoom=10)
icon = DivIcon(html='foo bar', bg_pos=[0, 0], icon_size=[150, 150])
mark = Marker(location=center, icon=icon)
m.add_layer(mark);

m

deeplook commented 3 years ago

I'm using these two cells for now as a workaround:

%%html
<style>
.leaflet-div-icon { background-color: transparent; border-color: transparent }
</style>
from ipyleaflet import DivIcon, Map, Marker

m = Map(center=(0, 0), zoom=1)
w, h = 32, 32
html = f'<img src="https://simpleicons.org/icons/apple.svg" width="{w}" height="{h}"/>'
icon = DivIcon(html=html, bg_pos=(0, 0), icon_size=[w, h])
apple_loc = (37.3351901, -122.0114123)
mark = Marker(location=apple_loc, icon=icon, draggable=True)
m.add_layer(mark)
m
Screenshot 2021-07-01 at 10 55 41
giswqs commented 3 years ago

@deeplook Thank you for sharing the workaround. The html magic command will only work in Jupyter notebook. To integrate this into leafmap, we need a workaround that works in a Python script.

martinRenou commented 3 years ago

You could maybe import from IPython.display import HTML and display it using from IPython.display import display. But that's a hacky solution. It would be nicer using a real ipyleaflet solution.

deeplook commented 3 years ago

Works too! Here's a EM Soccer Finals 2021 Supporter Map (after some Twitter postings by others), ca. 25 LOC.

Screenshot 2021-07-11 at 17 49 29
giswqs commented 2 years ago

@deeplook Do you have the sample code for this? I am trying to integrate this into geemap for labeling features. https://github.com/giswqs/geemap/issues/815

deeplook commented 2 years ago

@giswqs It took some time to undust it, but yes! Here it is cell by cell. I hope it's useful:

import requests
from ipyleaflet import basemaps, DivIcon, GeoJSON, Map, Marker
from IPython.display import HTML
from shapely.geometry import shape
# Workaround for cleaning the icon background (must be on a separate cell):
HTML("""<style>
.leaflet-div-icon { background-color: transparent; border-color: transparent }
</style>""")
m = Map(center=([53.33, 7.25]), zoom=3.5, basemap=basemaps.CartoDB.Positron)

url = "https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json"
data = requests.get(url).json()
data2 = {feat["id"]: feat["geometry"] for feat in data["features"]}

w, h = 32, 32
url_base = "https://upload.wikimedia.org/wikipedia/en"
for cc3 in 'GBR ALB EST LTU LVA UKR BLR CHE AUT SVN SVK SRB BGR CZE BIH NOR ISL GRC HRV MKD MDA SWE ESP DEU DNK BEL LUX NLD FRA ITA ROU POL HUN PRT FIN IRL'.split():
    geometry = data2[cc3]
    sh = shape(geometry)
    lat, lon = (61.81, 9.05) if cc3 == "NOR" else (sh.centroid.y, sh.centroid.x)
    url = (url_base + "/b/be/Flag_of_England.svg") if cc3 == "GBR" else (url_base + "/0/03/Flag_of_Italy.svg")
    html = f'<img src="{url}" width="{w}" height="{h}"/>'
    icon = DivIcon(html=html, bg_pos=(0, 0), icon_size=[w, h])
    m.add_layer(Marker(location=(lat, lon), icon=icon, draggable=False))
    m += GeoJSON(data=geometry, style={"fill": None})

m.layout.height = "550px"
m
giswqs commented 2 years ago

@deeplook Great! Thanks for sharing. I will try it out.

deeplook commented 2 years ago

My pleasure!

giswqs commented 2 years ago

This has been implemented in leafmap. See notebook example https://leafmap.org/notebooks/36_add_labels

add_labels

martinRenou commented 2 years ago

If you don't mind, we could keep this issue open until this is properly implemented in ipyleaflet 😊