Popup parameter of ipyleaflet CircleMarker triggers TraitError

88 views Asked by At

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

enter image description here

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?

0

There are 0 answers