def clickablemap(center=[48.790153, 2.327395], zoom=13, layout=ipywidgets.Layout(width='100%', height='500px')): # look at: http://leaflet.github.io/Leaflet.draw/docs/examples/basic.html import json from ipyleaflet import (Map, Rectangle, Polygon, TileLayer, ImageOverlay, DrawControl, GeoJSON) #%matplotlib inline # %matplotlib notebook # google tileserver # https://stackoverflow.com/questions/9394190/leaflet-map-api-with-google-satellite-layer mosaicsTilesURL = 'https://mt1.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}' # Hybrid: s,h; Satellite: s; Streets: m; Terrain: p; # Map Settings # Define colors colors = {'blue': "#009da5"} # Define initial map center lat/long #center = [48.790153, 2.327395] # Define initial map zoom level #zoom = 13 # Create the map m = Map(center=center, zoom=zoom, scroll_wheel_zoom=True, layout=layout) # using custom basemap m.clear_layers() m.add_layer(TileLayer(url=mosaicsTilesURL)) # Define the draw tool type options polygon = {'shapeOptions': {'color': colors['blue']}} rectangle = {'shapeOptions': {'color': colors['blue']}} ## Create the draw controls ## @see https://github.com/ellisonbg/ipyleaflet/blob/master/ipyleaflet/leaflet.py#L293 #dc = DrawControl( # polygon = polygon, # rectangle = rectangle #) dc = DrawControl( polygon={'shapeOptions': { 'color': '#0000FF' }}, polyline={'shapeOptions': { 'color': '#0000FF' }}, circle={'shapeOptions': { 'color': '#0000FF' }}, rectangle={'shapeOptions': { 'color': '#0000FF' }}, ) # Initialize an action counter variable m.actionCount = 0 m.AOIs = [] # Register the draw controls handler def handle_draw(self, action, geo_json): # Increment the action counter #global actionCount m.actionCount += 1 # Remove the `style` property from the GeoJSON geo_json['properties'] = {} # Convert geo_json output to a string and prettify (indent & replace ' with ") geojsonStr = json.dumps(geo_json, indent=2).replace("'", '"') m.AOIs.append(json.loads(geojsonStr)) # Attach the draw handler to the draw controls `on_draw` event dc.on_draw(handle_draw) m.add_control(dc) # add a custom function to create and add a Rectangle layer # (LESS USEFUL THAN add_geojson) def add_rect(*args, **kwargs): r = Rectangle(*args, **kwargs) return m.add_layer(r) m.add_rectangle = add_rect # add a custom function to create and add a Polygon layer def add_geojson(*args, **kwargs): # ugly workaround to call without data=aoi if 'data' not in kwargs: kwargs['data'] = args[0] args2 = [i for i in args[1:-1]] else: args2 = args r = GeoJSON(*args2, **kwargs) return m.add_layer(r) m.add_GeoJSON = add_geojson # Display return m
def overlaymap(aoiY, imagesurls, zoom=13, layout=ipywidgets.Layout(width='100%', height='500px')): import json import numpy as np from ipyleaflet import ( Map, Rectangle, Polygon, TileLayer, ImageOverlay, DrawControl, ) ## handle the case of imageurls not a list if type(imagesurls) != list: imagesurls = [imagesurls] number_of_images = len(imagesurls) ## handle both kinds of calls with aoi, or aoi['coordinates'] if 'coordinates' in aoiY: aoiY = aoiY['coordinates'][0] # create the Map object # google tileserver # https://stackoverflow.com/questions/9394190/leaflet-map-api-with-google-satellite-layer mosaicsTilesURL = 'https://mt1.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}' # Hybrid: s,h; Satellite: s; Streets: m; Terrain: p; m = Map( center=aoiY[0][::-1], zoom=zoom, scroll_wheel_zoom=True, layout=layout, ) # using custom basemap m.clear_layers() m.add_layer(TileLayer(url=mosaicsTilesURL, opacity=1.00)) #vlayer = VideoOverlay(videoUrl, videoBounds ) #m.add_layer(vlayer) ### this shows an animated gif #m.add_layer(layer) # display map (this show) #display(m) ############## ADD INTERACTIVE LAYER from ipywidgets import interact, interactive, fixed, interact_manual import ipywidgets as widgets # meke sure that the images have unique names imagesurls = [ '%s?%05d' % (i, np.random.randint(10000)) for i in imagesurls ] # draw bounding polygon y = [a[::-1] for a in aoiY] p = Polygon(locations=y, weight=2, fill_opacity=0.25) m.add_layer(p) # create image layer = ImageOverlay(url='%s' % (imagesurls[0]), bounds=[ list(np.max(aoiY, axis=0)[::-1]), list(np.min(aoiY, axis=0)[::-1]) ]) m.add_layer(layer) # callback fro flipping images def showim(i): if (i < len(imagesurls)): # ----- FLICKERS ---- # layer.url='%s'%(imagesurls[i]) # layer.visible = False # layer.visible = True # ALTERNATIVE: add a new layer layer = ImageOverlay(url='%s' % (imagesurls[i]), bounds=[ list(np.max(aoiY, axis=0)[::-1]), list(np.min(aoiY, axis=0)[::-1]) ]) m.add_layer(layer) # remove old ones if len(m.layers) > 30: # image buffer for l in (m.layers[1:-1]): m.remove_layer(l) # build the UI #interact(showim,i=len(imagesurls)-1) #interact(showim, i=widgets.IntSlider(min=0,max=len(imagesurls),step=1,value=0)); play = widgets.Play( interval=200, #ms value=0, min=0, max=len(imagesurls) - 1, step=1, description="Press play", disabled=False, ) slider = widgets.IntSlider(min=0, max=len(imagesurls) - 1, description='Frame:') label = widgets.Label(value="") def on_value_change(change): label.value = imagesurls[change['new']] showim(change['new']) slider.observe(on_value_change, 'value') b1 = widgets.Button(description='fw', layout=widgets.Layout(width='auto')) b2 = widgets.Button(description='bw', layout=widgets.Layout(width='auto')) b3 = widgets.Button(description='hide', layout=widgets.Layout(width='auto')) b4 = widgets.Button(description='hidePoly', layout=widgets.Layout(width='auto')) def clickfw(b): slider.value = slider.value + 1 def clickbw(b): slider.value = slider.value - 1 def clickhide(b): if layer.visible: layer.visible = False else: layer.visible = True def clickhidePoly(b): if p.visible: p.visible = False else: p.visible = True b1.on_click(clickfw) b2.on_click(clickbw) b3.on_click(clickhide) b4.on_click(clickhidePoly) # add a custom function to create and add a Polygon layer def add_geojson(*args, **kwargs): # ugly workaround to call without data=aoi if 'data' not in kwargs: kwargs['data'] = args[0] args2 = [i for i in args[1:-1]] else: args2 = args r = GeoJSON(*args2, **kwargs) return m.add_layer(r) m.add_GeoJSON = add_geojson widgets.jslink((play, 'value'), (slider, 'value')) if number_of_images > 1: return widgets.VBox( [widgets.HBox([play, b2, b1, b3, b4, slider, label]), m]) else: return widgets.VBox([widgets.HBox([b3, b4, label]), m])