I'm trying to make event callback work in ipyleaflet.CircleMarker. I also need to add CircleMarker.popup to see info of marker that I have clicked:
from ipywidgets import HTML
from ipyleaflet import Map, basemaps, CircleMarker#, Popup
address_collection =\
{0: {'address': 'Liepyno g. 9, Vilnius', 'lon': 25.256049572760737, 'lat': 54.6979514},
1: {'address': 'Paribio g. 25b, Vilnius', 'lon': 25.251277349999988, 'lat': 54.70223025},
2: {'address': 'Linkmenų g. 34, Vilnius', 'lon': 25.272923689938533, 'lat': 54.7098726},
4: {'address': 'Giedraičių g. 60B, Vilnius', 'lon': 25.279606048256667, 'lat': 54.70612675},
7: {'address': 'Pulko g. 2, Vilnius', 'lon': 25.287723473310106, 'lat': 54.7193275},
8: {'address': 'Kareivių g. 7, Vilnius', 'lon': 25.296566713988096, 'lat': 54.71738295},
9: {'address': 'Trinapolio g. 9e, Vilnius', 'lon': 25.28816380095093, 'lat': 54.7250439},
10: {'address': 'Kazio Ulvydo g. 11, Vilnius', 'lon': 25.276568280969475, 'lat': 54.7186202},
11: {'address': 'Apkasų g. 21, Vilnius', 'lon': 25.288784589489467, 'lat': 54.70532835},
12: {'address': 'Kazliškių g. 19, Vilnius', 'lon': 25.29201085, 'lat': 54.6980964}}
def marker_callback(marker, i):
def callback(*args, **kwargs):
#kwargs: {'event': 'interaction', 'type': 'click', 'coordinates': [..., ...]}
#i: index of marker
if kwargs['type'] == 'click':
if marker.fill_color in ('blue', 'red'): marker.fill_color = 'green'
elif marker.fill_color == 'green': marker.fill_color = 'red'
elif kwargs['type'] == 'dblclick':
if marker.color != 'blue': marker.fill_color = 'blue'
return callback
route_map = Map(center=(54.71,25.276843), zoom=13, basemap=basemaps.OpenStreetMap.Mapnik)
for i, address_record in address_collection.items():
location = (address_record['lat'], address_record['lon'])
marker = CircleMarker(radius=8, location=location,
weight=2, color='black', fill_color='blue', fill_opacity=0.3)
marker.popup=HTML(f'{address_record["address"]}<br>index: {i}')
marker.on_click(marker_callback(marker, i))
marker.on_dblclick(marker_callback(marker, i))
route_map.add_layer(marker)
route_map
If I don't use marker.popup my color change event works as expected. Otherwise it works too, only TraitError is raised in a background:
TraitError Traceback (most recent call last)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\ipywidgets\widgets\widget.py:766, in Widget._handle_msg(self, msg)
764 if 'buffer_paths' in data:
765 _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 766 self.set_state(state)
768 # Handle a state request.
769 elif method == 'request_state':
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\ipywidgets\widgets\widget.py:648, in Widget.set_state(self, sync_data)
645 if name in self.keys:
646 from_json = self.trait_metadata(name, 'from_json',
647 self._trait_from_json)
--> 648 self.set_trait(name, from_json(sync_data[name], self))
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:1738, in HasTraits.set_trait(self, name, value)
1736 raise TraitError(f"Class {cls.__name__} does not have a trait named {name}")
1737 else:
-> 1738 getattr(cls, name).set(self, value)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:703, in TraitType.set(self, obj, value)
702 def set(self, obj, value):
--> 703 new_value = self._validate(obj, value)
704 try:
705 old_value = obj._trait_values[self.name]
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:735, in TraitType._validate(self, obj, value)
733 return value
734 if hasattr(self, "validate"):
--> 735 value = self.validate(obj, value)
736 if obj._cross_validation_lock is False:
737 value = self._cross_validate(obj, value)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:2417, in Float.validate(self, obj, value)
2415 value = float(value)
2416 if not isinstance(value, float):
-> 2417 self.error(obj, value)
2418 return _validate_bounds(self, obj, value)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:841, in TraitType.error(self, obj, value, error, info)
835 else:
836 e = "The '{}' trait expected {}, not {}.".format(
837 self.name,
838 self.info(),
839 describe("the", value),
840 )
--> 841 raise TraitError(e)
TraitError: The 'east' trait of a Map instance expected a float, not the NoneType None.
---------------------------------------------------------------------------
TraitError Traceback (most recent call last)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\ipywidgets\widgets\widget.py:766, in Widget._handle_msg(self, msg)
764 if 'buffer_paths' in data:
765 _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 766 self.set_state(state)
768 # Handle a state request.
769 elif method == 'request_state':
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\ipywidgets\widgets\widget.py:648, in Widget.set_state(self, sync_data)
645 if name in self.keys:
646 from_json = self.trait_metadata(name, 'from_json',
647 self._trait_from_json)
--> 648 self.set_trait(name, from_json(sync_data[name], self))
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:1738, in HasTraits.set_trait(self, name, value)
1736 raise TraitError(f"Class {cls.__name__} does not have a trait named {name}")
1737 else:
-> 1738 getattr(cls, name).set(self, value)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:703, in TraitType.set(self, obj, value)
702 def set(self, obj, value):
--> 703 new_value = self._validate(obj, value)
704 try:
705 old_value = obj._trait_values[self.name]
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:735, in TraitType._validate(self, obj, value)
733 return value
734 if hasattr(self, "validate"):
--> 735 value = self.validate(obj, value)
736 if obj._cross_validation_lock is False:
737 value = self._cross_validate(obj, value)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:2417, in Float.validate(self, obj, value)
2415 value = float(value)
2416 if not isinstance(value, float):
-> 2417 self.error(obj, value)
2418 return _validate_bounds(self, obj, value)
File ~\PycharmProjects\courier_colab\venv\lib\site-packages\traitlets\traitlets.py:841, in TraitType.error(self, obj, value, error, info)
835 else:
836 e = "The '{}' trait expected {}, not {}.".format(
837 self.name,
838 self.info(),
839 describe("the", value),
840 )
--> 841 raise TraitError(e)
TraitError: The 'east' trait of a Map instance expected a float, not the NoneType None.
How to suppress this kind of errors? Is it a bug in ipyleaflet or do I need to implement Popup in a different manner?
