python-3.xipyleaflet

lazy pop up image loading for ipyleaflet


I have a lot of images from different locations. I want to show them on a ipyleaflet map in a jupyter notebook.

Each image should have a marker, on click of the marker the image should be shown. Since there are a lot of images i want the contents of the popup to be loaded in a lazy manner (as in, picture will only be loaded into memory when the marker is clicked and after it should be deleted again).

There must be some callback function i could hijack to load the image into memory only on click, but i cannot find it by the life of me. Hope to find some suggestions here. The on_click method accepts a callback, but does not have access to the Marker object itself, such that i cannot change the popup itself. Overwriting the `:

class LazyMarker(Marker):
    def __init__(self, image_path, **kwargs):
        self._image_path = image_path
        super(LazyMarker, self).__init__(**kwargs)
    
    def _handle_mouse_events(self, _, content, buffers):
        self.popup = HTML()
        self.popup.value = "lazy image loading test:" + load_image_function(self.path)
        
        # rest of the original function
        event_type = content.get('type', '')
        if event_type == 'click':
            self._click_callbacks(**content)
        if event_type == 'dblclick':
            self._dblclick_callbacks(**content)
        [...]

seems also not to work. I'm very grateful for some suggestions! Thanks!


Solution

  • Answering my own question like here: https://github.com/jupyter-widgets/ipyleaflet/issues/1092

    m=Map(..)
    
    def callback_with_popup_creation(fname):
      def f(**kwargs):
        marker_center = kwargs['coordinates'] 
        html = HTML()
        html.value="<img class=\"awesome image\" src=\"" + str(img_file_relative) + "\">"
        popup = Popup(
          location=marker_center,
          child=html
        )
        m.add_layer(popup)
      return f
    
    for fname, lat, lon in data:
      marker = Marker(location = (lat, lon))   
      marker.on_click(callback(fname))
    

    hopefully that helps anyone with a similar issue.