gmaps icon indicating copy to clipboard operation
gmaps copied to clipboard

Ability to add layers after the map is rendered

Open mhamilton723 opened this issue 8 years ago • 3 comments

Hey, Great codebase, however I am struggling to figure out how to update the layers of a gmap figure in a way that the displayed widget will re-render. Is this currently possible?

mhamilton723 avatar Oct 09 '17 22:10 mhamilton723

Thanks for raising this!

At the moment, you cannot add layers after the figure has been rendered (sorry -- that could have been documented better). The ability to add / remove layers after the map has been rendered would be great.

One possible workaround is to embed the map in a container widget (like an HBox) and just rerender a new map inside the HBox:


import ipywidgets as widgets

import gmaps
gmaps.configure(api_key='stuff')

class UpdatingMap(object):
    def __init__(self):
        self.layers = []
        self.map_kwargs = {
            'layout': {'width': '600px', 'height': '400px'}
        }
        self.container = widgets.HBox(
            [gmaps.Map(layers=self.layers, **self.map_kwargs)], 
        )
        
    def add_layer(self, layer):
        self.layers.append(layer)
        self.container.children = [
            gmaps.Map(layers=self.layers, **self.map_kwargs)
        ]
        
    def display(self):
        return self.container

You can then use:

fig = UpdatingMap()
fig.display()

If you now write:

fig.add_layer(gmaps.traffic_layer())

... the map updates (or rather, it's replaced by an entirely new map).

Obviously, you need to migrate any state that you want to keep from the old map to the new map. At the moment, this is possible for some things but not others. For instance, there is no way to get the current zoom and center of a map.


Anyone interested in implementing this correctly needs to:

  • in the PlainmapView class (https://github.com/pbugnion/gmaps/blob/master/js/src/Map.js#L45), add a listener for a change in the layers traitlet in the model. When this changes, the view list layerViews needs to be re-updated from the model.
  • At the moment, the view list does not know how to remove layers. For this to work, we need to add a removeFromMapView for every layer. In most cases, this probably just amounts to setting this.map to null.

pbugnion avatar Oct 10 '17 05:10 pbugnion

Thanks for the fast and thorough response, one this i would really like to do is add data to an existing heatmap layer and have it re-render. Is this also not possible currently?

mhamilton723 avatar Oct 10 '17 19:10 mhamilton723

Dynamically updating the data underlying the heatmap is a slightly different issue. I've reraised this in issue #188.

pbugnion avatar Oct 11 '17 06:10 pbugnion