Jonathan
Jonathan

Reputation: 521

Trouble Using Google Maps with Bokeh Server, want to dynamically zoom

I'd like to translate the Google Maps Bokeh app to a Bokeh Server App that allows zoom. This is the bokek app I'm attempting to modify:
https://docs.bokeh.org/en/latest/docs/user_guide/geo.html

This is my attemp to translate to a bokeh server application:

from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource, GMapOptions
from bokeh.plotting import gmap
from bokeh.models.widgets import Slider, TextInput
import random

text = TextInput(title="title", value='my sine wave')

zoom_slider = Slider(title='Zoom Level', value=11, start=0, end=20, step=1)
lat_textbox = TextInput(title='Latitude', value='30.2861')
lon_textbox = TextInput(title='Longitude', value='-97.7394')

source_gps = ColumnDataSource(data=dict(lat=[30.29, 30.20, 30.29], lon=[-97.70, -97.74, -97.78]))
source_map = ColumnDataSource(
    data=dict(map_options=[GMapOptions(lat=30.2861, lng=-97.7394, map_type="roadmap", zoom=11)]))

p = gmap("YOUR GOOGLE API CREDENTIALS HERE", 
source_map.data['map_options'][0], title="Austin")
p.circle(x="lon", y="lat", size=15, fill_color="blue", fill_alpha=0.8, source=source_gps)


def update_data(attrname, old, new):
    zoom = zoom_slider.value
    lat = float(lat_textbox.value)
    lon = float(lon_textbox.value)
    source_map.data = dict(map_options=[GMapOptions(lat=lat, lng=lon, map_type="roadmap", zoom=zoom)])
    source_gps.data = dict(lat=[30.29 + random.random() / 10 - 0.05, 30.20, 30.29],
                           lon=[-97.70 + random.random() / 10 - 0.05, -97.74, -97.78])


for w in [zoom_slider, lat_textbox, lon_textbox]:
    w.on_change('value', update_data)

# Set up layouts and add to document
inputs = column(zoom_slider, lat_textbox, lon_textbox)

curdoc().add_root(row(inputs, p, width=800))
curdoc().title = "Google Map"

I'd expect the google map to zoom according to the value of the zoom slider, but it's static. Any ideas?

UPDATED!! Thanks to bigreddot, this is the working code:

from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource, GMapOptions
from bokeh.plotting import gmap
from bokeh.models.widgets import Slider, TextInput
import random

text = TextInput(title="title", value='my sine wave')

zoom_slider = Slider(title='Zoom Level', value=11, start=0, end=20, step=1)
lat_textbox = TextInput(title='Latitude', value='30.2861')
lon_textbox = TextInput(title='Longitude', value='-97.7394')

source_gps = ColumnDataSource(data=dict(lat=[30.29, 30.20, 30.29], lon=[-97.70, -97.74, -97.78]))
initial_map_options = GMapOptions(lat=30.2861, lng=-97.7394, map_type="roadmap", zoom=11)

p = gmap("YOUR GOOGLE API CREDENTIALS HERE", 
map_options=initial_map_options, title="Austin")
p.circle(x="lon", y="lat", size=15, fill_color="blue", fill_alpha=0.8, source=source_gps)


def update_data(attrname, old, new):
    zoom = zoom_slider.value
    lat = float(lat_textbox.value)
    lon = float(lon_textbox.value)
    source_gps.data = dict(lat=[30.29 + random.random() / 10 - 0.05, 30.20, 30.29],
                       lon=[-97.70 + random.random() / 10 - 0.05, -97.74, -97.78])
    p.map_options = GMapOptions(lat=lat, lng=lon, map_type="roadmap", zoom=zoom)


for w in [zoom_slider, lat_textbox, lon_textbox]:
    w.on_change('value', update_data)

# Set up layouts and add to document
inputs = column(zoom_slider, lat_textbox, lon_textbox)

curdoc().add_root(row(inputs, p, width=800))
curdoc().title = "Google Map"

Upvotes: 1

Views: 322

Answers (1)

bigreddot
bigreddot

Reputation: 34618

The map options, i.e. the zoom level, are a property of the plot, not of the data source. If you want to update the map options you need to do something like:

p.map_options = new_map_options

somewhere in your update function.

Upvotes: 1

Related Questions