def __get_img_overlay(self, img_path): # We need to create an ImageOverlay for each image to show, # and set the appropriate bounds based on the image size if not os.path.exists(img_path): print(labels_str.warn_img_path_not_exits + img_path) im = cv2.imread(img_path) h, w, _ = im.shape max_v = 100 offset_h = -25 offset_w = -25 hh = max_v - offset_h*2 ww = max_v - offset_w*2 if h > w: ww = int(w * hh / h) offset_w = (max_v - ww) / 2 elif w > h: hh = int(h * ww / w) offset_h = (max_v - hh) / 2 img_ov = ImageOverlay(url=img_path, bounds=((offset_h, offset_w), (hh + offset_h, ww+offset_w))) return img_ov, h, w, hh, ww, offset_h, offset_w
def wmtsRequest(self, layer='AGRICULTURE'): self.layer = layer ID = 'your ID' wmts_url = 'https://services.sentinel-hub.com/ogc/wmts/'+ID wmts = WebMapTileService(wmts_url) self.x, self.y = self.deg2num(self.lat_center, self.lon_center, self.zoom) self.wmtsOut = wmts.gettile(layer=self.layer, tilematrixset='PopularWebMercator256', tilematrix=self.zoom, row=self.y, column=self.x, format="image/png") self.imgArr = imread(io.BytesIO(wmtsOut.read())) self.lat_max, self.lon_min = self.num2deg(self.x, self.y, self.zoom) self.lat_min, self.lon_max = self.num2deg(self.x+1, self.y+1, self.zoom) imgurl = image_to_url(image=self.imgArr) self.map.add_layer(ImageOverlay(url=imgurl, bounds=[[self.lat_min, self.lon_min], [self.lat_max, self.lon_max]]))
def map_bath(ds,m): bounds = [(81.5, 18.5), (64.5, 99.)] imgurl=get_png_bath(ds) if imgurl != '': #bounds = [(18., 68), (100., 85.)] io = ImageOverlay(url=imgurl, bounds=bounds, opacity=0.75) m.add_layer(io)
def wcsRequest(self, layer='AGRICULTURE'): self.layer = layer ID = 'your ID' wcs_url = 'https://services.sentinel-hub.com/ogc/wcs/'+ID wcs = WebCoverageService(wcs_url, version='1.0.0') self.x, self.y = self.deg2num(self.lat_center, self.lon_center, self.zoom) self.lat_max, self.lon_min = self.num2deg(self.x, self.y, self.zoom) self.lat_min, self.lon_max = self.num2deg(self.x+1, self.y+1, self.zoom) inProj = Proj(init='epsg:4326') outProj = Proj(init='epsg:3857') x1,y1 = transform(inProj,outProj,self.lon_min,self.lat_min) x2,y2 = transform(inProj,outProj,self.lon_max,self.lat_max) bb=(x1, y1, x2, y2) self.wcsOut = wcs.getCoverage(identifier=self.layer, time=None, width=800, height=800, bbox = bb, format = 'GeoTIFF') self.imgTiff = Image.open(self.wcsOut) self.imgArr = np.array(self.imgTiff) imgurl = image_to_url(image=self.imgArr) self.map.add_layer(ImageOverlay(url=imgurl, bounds=[[self.lat_min, self.lon_min], [self.lat_max, self.lon_max]]))
def map_temp(ds,m,fdate='2018-07-24T06:00:00'): bounds = [(88., 18), (65., 100.)] imgurl=get_png_temp(ds,fdate) if imgurl != '': #bounds = [(18., 68), (100., 85.)] io = ImageOverlay(url=imgurl, bounds=bounds, opacity=0.3) m.add_layer(io)
def mk_image_overlay(xx: xr.Dataset, clamp: Optional[float] = None, bands: Optional[Tuple[str, str, str]] = None, layer_name='Image', fmt='png', **opts): from ipyleaflet import ImageOverlay comp, mime = dict( png=(to_png_data, 'image/png'), jpg=(to_jpeg_data, 'image/jpeg'), jpeg=(to_jpeg_data, 'image/jpeg'), ).get(fmt.lower(), (None, None)) if comp is None or mime is None: raise ValueError('Only support png an jpeg formats') if 'time' in xx.coords: nt = xx.time.shape[0] if nt == 1: xx = xx.isel(time=0) else: return [ mk_image_overlay(xx.isel(time=t), clamp=clamp, bands=bands, layer_name="{}-{}".format(layer_name, t), fmt=fmt, **opts) for t in range(nt) ] cc = to_rgba(xx, clamp=clamp, bands=bands) im_url = mk_data_uri(comp(cc.values, **opts), mime) return ImageOverlay(url=im_url, bounds=xr_bounds(cc), name=layer_name)
def imgoverlays(self): self.leafletimg = OrderedDict() for i in self.grassimg: layer = ImageOverlay(url=self.grassimg[i]['raster'], bounds=(self.grassimg[i]['LL'], self.grassimg[i]['UR'])) self.leafletimg[i] = layer
def display_da(da, cm): """ Description: Display a colored xarray.DataArray on a map and allow the user to select a point ----- Input: da: xarray.DataArray cm: matplotlib colormap Output: m: map to interact with dc: draw control Usage: View, interact and point a location to be used later on """ # Check inputs assert 'dataarray.DataArray' in str( type(da)), "da must be an xarray.DataArray" # convert DataArray to png64 imgurl = da_to_png64(da, cm) # Display latitude = (da.latitude.values.min(), da.latitude.values.max()) longitude = (da.longitude.values.min(), da.longitude.values.max()) margin = -0.5 zoom_bias = 0 lat_zoom_level = _degree_to_zoom_level(margin=margin, * latitude) + zoom_bias lon_zoom_level = _degree_to_zoom_level(margin=margin, * longitude) + zoom_bias zoom = min(lat_zoom_level, lon_zoom_level) - 1 center = [np.mean(latitude), np.mean(longitude)] m = Map(center=center, zoom=zoom) # http://leaflet-extras.github.io/leaflet-providers/preview/ esri = basemap_to_tiles(basemaps.Esri.WorldImagery) m.add_layer(esri) io = ImageOverlay(name='DataArray', url=imgurl, bounds=[(latitude[0], longitude[0]), (latitude[1], longitude[1])]) m.add_layer(io) dc = DrawControl(circlemarker={'color': 'yellow'}, polygon={}, polyline={}) m.add_control(dc) m.add_control(LayersControl()) return m, dc, io
def mk_image_overlay(xx: Union[xr.Dataset, xr.DataArray], clamp: Optional[float] = None, bands: Optional[Tuple[str, str, str]] = None, layer_name="Image", fmt="png", **opts): """Create ipyleaflet.ImageLayer from raster data. xx - xarray.Dataset that will be converted to RGBA or xarray.DataArray that is already in RGB(A) format clamp, bands -- passed on to to_rgba(..), only used when xx is xarray.Dataset Returns ======= ipyleaflet.ImageOverlay or a list of them one per time slice """ from ipyleaflet import ImageOverlay comp, mime = dict( png=(to_png_data, "image/png"), jpg=(to_jpeg_data, "image/jpeg"), jpeg=(to_jpeg_data, "image/jpeg"), ).get(fmt.lower(), (None, None)) if comp is None or mime is None: raise ValueError("Only support png an jpeg formats") if "time" in xx.dims: nt = xx.time.shape[0] if nt == 1: xx = xx.isel(time=0) else: return [ mk_image_overlay(xx.isel(time=t), clamp=clamp, bands=bands, layer_name="{}-{}".format(layer_name, t), fmt=fmt, **opts) for t in range(nt) ] if isinstance(xx, xr.Dataset): rgba = to_rgba(xx, clamp=clamp, bands=bands) else: if not is_rgb(xx): raise ValueError("Expect RGB xr.DataArray") rgba = xx im_url = mk_data_uri(comp(rgba.values, **opts), mime) return ImageOverlay(url=im_url, bounds=xr_bounds(rgba), name=layer_name)
def rasters_on_map(rasters_list, out_dir, overlay_names_list, geojson_data=None): """ displays a raster on a ipyleaflet map :param rasters_list: rasters to display (rasterio image) :param out_dir: path to the output directory (preview writing) :param overlay_names_list: name of the overlays for the map """ # - get bounding box raster = rasters_list[0] epsg4326 = {'init': 'EPSG:4326'} bounds = transform_bounds(raster.crs, epsg4326, *raster.bounds) center = [(bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2] # - get centered map m = Map(center=(center[-1], center[0]), zoom=10) # - plot quicklook for raster, overlay_name in zip(rasters_list, overlay_names_list): bounds = transform_bounds(raster.crs, epsg4326, *raster.bounds) quicklook_url = os.path.join( out_dir, "PREVIEW_{}.JPG".format(datetime.datetime.now())) write_quicklook(raster, quicklook_url) quicklook = ImageOverlay(url=quicklook_url, bounds=((bounds[1], bounds[0]), (bounds[3], bounds[2])), name=overlay_name) m.add_layer(quicklook) m.add_control(LayersControl()) m.add_control(FullScreenControl()) # - add geojson data if geojson_data is not None: geo_json = GeoJSON(data=geojson_data, style={ 'color': 'green', 'opacity': 1, 'weight': 1.9, 'dashArray': '9', 'fillOpacity': 0.1 }) m.add_layer(geo_json) # - add draw control dc = DrawControl() m.add_control(dc) return m, dc
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)
def show_acc(label, coord, m, current_io, width, da): width2 = width / 2. lat, lon = coord acc = da.loc[1, lat + width2:lat - width2, lon - width2:lon + width2] acc_v = int(acc.sel(y=lat, x=lon, method='nearest').values) imgurl = get_img(np.sqrt(acc.values)) bounds = [(acc.y[-1].values - 0.5 / 1200, acc.x[0].values - 0.5 / 1200), (acc.y[0].values + 0.5 / 1200, acc.x[-1].values + 0.5 / 1200)] io = ImageOverlay(url=imgurl, bounds=bounds, opacity=0.5) if current_io is not None: m.remove_layer(current_io) m.add_layer(io) return io, acc_v
def create_map(normalized_image: np.ndarray) -> Map: """ Creates leaflet map with given image :param normalized_image: Image data normalized to 0-255 8-bit integer :return: Leaflet map """ width = normalized_image.shape[0] height = normalized_image.shape[1] bounds = [(-width / 2, -height / 2), (width / 2, height / 2)] layer = ImageOverlay(url=serialize_to_url(normalized_image), bounds=bounds) leaflet = Map(center=[0, 0], zoom=1, interpolation='nearest') leaflet.clear_layers() leaflet.add_layer(layer) return leaflet
def addImageLayer(inMap, filename, spatial_extent, name): im = PIL.Image.open(filename) f = BytesIO() im.save(f, 'png') data = b64encode(f.getvalue()) data = data.decode('ascii') imgurl = 'data:image/png;base64,' + data image = ImageOverlay(url=imgurl, bounds=((spatial_extent['south'], spatial_extent['east']), (spatial_extent['north'], spatial_extent['west'])), name=name) layers_control = LayersControl(position='topright') inMap.map.add_layer(image) return
def overlay(label, coord, m, current_io, width, da, func=None, nan=None): width2 = width / 2. lat, lon = coord tile = da.loc[1, lat + width2:lat - width2, lon - width2:lon + width2] value = int(tile.sel(y=lat, x=lon, method='nearest').values) values = tile.values if func is not None: values = func(values) imgurl = get_img(values, nan) bounds = [(tile.y[-1].values - 0.5 / 1200, tile.x[0].values - 0.5 / 1200), (tile.y[0].values + 0.5 / 1200, tile.x[-1].values + 0.5 / 1200)] io = ImageOverlay(url=imgurl, bounds=bounds, opacity=0.5) if current_io is not None: m.remove_layer(current_io) m.add_layer(io) return io, value
def convert_array_to_image_overlay(self, array, **kwargs): """Converting an array to an Image Overlay Args: array: ndarray - array to be converted to an Image Overlay Kwargs: layer: string - layer of WMS Service extent: tuple - extent of the map crs: string - crs of the layer """ layer = kwargs.get('layer', 'WMS Layer') extent = kwargs.get('extent', (5, 49, 10, 52)) crs = kwargs.get('crs', None) # If the extent is not provided in WGS 84 coordinates, it will be transformed if 'crs' in kwargs.keys(): if crs is None or crs == 'EPSG:4326': extent_transf = extent else: proj_custom = Proj(init=crs) proj_deafult = Proj(init='epsg:4326') extent_transf = np.zeros(4) extent_transf[0], extent_transf[1] = transform( proj_custom, proj_deafult, extent[0], extent[1]) extent_transf[2], extent_transf[3] = transform( proj_custom, proj_deafult, extent[2], extent[3]) else: extent_transf = extent # Array is saved as PNG File for the Image Overlay plt.imsave('%s.png' % layer, array) # Creating Image Overlay map = ImageOverlay(url='%s.png' % layer, name=[layer][0], bounds=((extent_transf[1], extent_transf[0]), (extent_transf[3], extent_transf[2]))) return map
def overlay(m, current_io, da, label): lats, lons = da.lat.values, da.lon.values affine = [0.1, 0, lons[0] - 0.5 * 0.1, 0, -0.1, lats[-1] + 0.5 * 0.1] bounds = [ lons[0] - 0.5 * 0.1, lats[0] - 0.5 * 0.1, lons[-1] + 0.5 * 0.1, lats[-1] + 0.5 * 0.1 ] a_web, affine, shape = to_webmercator(da.values[::-1], affine, bounds) inProj = Proj(init='epsg:3857') outProj = Proj(init='epsg:4326') x1, y1 = affine[2], affine[5] x2, y2 = transform(inProj, outProj, x1, y1) x3, y3 = affine[2] + shape[1] * affine[0], affine[5] + shape[0] * affine[4] x4, y4 = transform(inProj, outProj, x3, y3) bounds = [(y4, x2), (y2, x4)] imgurl = get_img(a_web) io = ImageOverlay(url=imgurl, bounds=bounds, opacity=0.5) if current_io is not None: m.remove_layer(current_io) m.add_layer(io) return io
def plot_raster_from_path(input_path): """Creates map window with geo-referenced raster file from local or url visualized Args: input_path (str): input raster dataset (GeoTiff) file path Returns: map (ipyleaflet.Map): ipyleaflet Map object """ bbox = GeoUtil.get_raster_boundary(input_path) image_url = GeoUtil.create_data_img_url_from_geotiff_for_ipyleaflet( input_path) map = GeoUtil.get_ipyleaflet_map(bbox) image = ImageOverlay(url=image_url, bounds=((bbox[1], bbox[0]), (bbox[3], bbox[2]))) map.add_layer(image) return map
def MercatorPlot(self): ##### LOAD A GeoJSON MAP FOR THE PLOTTING center = [ np.min(self.lats) + (np.max(self.lats) - np.min(self.lats)) / 2, np.min(self.lons) + (np.max(self.lons) - np.min(self.lons)) / 2 ] #center = [0, 0] zoom = 4 if self.proj == 'laea': tls = TileLayer( opacity=1.0, url= 'https://{s}.tiles.arcticconnect.org/osm_3575/{z}/{x}/{y}.png', zoom=0, max_zoom=10, attribution= 'Map data (c) <a href="https://webmap.arcticconnect.org/">ArcticConnect</a> . Data (c) <a href="http://osm.org/copyright">OpenStreetMap</a>' ) M = Map(default_tiles=tls, center=center, zoom=zoom) else: M = Map(center=center, zoom=zoom) ##### PLOT THE PRODUCT ON TOP OF THE MAP WITH ImageOverlay imgName = self.out + '.png' try: img_bounds = [self.bottomleft, self.topright] except: img_bounds = [(np.min(self.lats), np.min(self.lons)), (np.max(self.lats), np.max(self.lons))] io = ImageOverlay(url=imgName, bounds=img_bounds) M.add_layer(io) return M
def item_to_img_overlay(item): dsw = gdal.Warp('/vsimem/warp.tif', item.get_assets()['rgb'].get_absolute_href(), dstSRS='EPSG:4326', format='GTiff', dstAlpha=True) ds = gdal.Open('/vsimem/warp.tif') _bands = [] for band_index in [1,2,3,4]: band = ds.GetRasterBand(band_index) w = band.XSize h = band.YSize _bands.append(band.ReadAsArray().astype(np.uint8)) rgb_uint8 = np.dstack(_bands).astype(np.uint8) im = Image.fromarray(rgb_uint8) f = BytesIO() im.save(f, 'png') data = b64encode(f.getvalue()) ds = None dsw = None del(ds) del(dsw) return ImageOverlay( url=b'data:image/png;base64,' + data, bounds=((shape(item.geometry).bounds[1], shape(item.geometry).bounds[0]), (shape(item.geometry).bounds[3], shape(item.geometry).bounds[2])) )
def get_image_overlay(img_path): # We need to create an ImageOverlay for each image to show, # and set the appropriate bounds based on the image size im = cv2.imread(img_path) h, w, _ = im.shape max_v = 100 offset_h = sizemap[config["size"]] offset_w = sizemap[config["size"]] hh = max_v - offset_h*2 ww = max_v - offset_w*2 if h > w: ww = int(w * hh / h) offset_w = (max_v - ww) / 2 else: hh = int(h * ww / w) offset_h = (max_v - hh) / 2 img_ov = ImageOverlay(url=img_path, bounds=((offset_h, offset_w), (hh + offset_h, ww+offset_w))) return img_ov, h, w, hh, ww, offset_h, offset_w
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])
def show_m(): multipoly = [] multycent = [] geom = spatial_utils.transform_geometry(info_data) poly = geom['geom'][0]['coordinates'][0] # poly = spatial_utils.swap_xy(geom['coordinates'][0])[0] multipoly.append(poly) centroid = spatial_utils.centroid(poly) multycent.append(centroid) centroid = spatial_utils.centroid(multycent) m = Map(center=centroid, zoom=16, basemap=basemaps.OpenStreetMap.Mapnik) polygon = Polygon(locations=multipoly, name='Parcel polygon', color="yellow", fill_color=None) m.add_layer(polygon) basemap2 = basemap_to_tiles(basemaps.Esri.WorldImagery) poly_text = HTML() poly_text.value = f"""Parcel ID: {pid}<br> Crop name: {crop_name}<br> Area: {area:.2f} sqm<br> Coordinates: {centroid} """ poly_text.placeholder = "HTML" poly_text.description = "" # Popup with a given location on the map: poly_popup = Popup(child=poly_text, close_button=False, auto_close=False, close_on_escape_key=False) m.add_layer(poly_popup) polygon.popup = poly_popup # Popup associated to a layer # Layers control show_poly = Checkbox(value=True, description='Polygon', indent=False, layout=Layout(width='140px')) show_sat = Checkbox(value=False, description='High res basemap', indent=False, layout=Layout(width='140px')) def polygon_changed(b): try: if show_poly.value is True: m.add_layer(polygon) else: m.remove_layer(polygon) except Exception: pass show_poly.observe(polygon_changed) def show_sat_changed(b): try: if show_sat.value is True: m.add_layer(basemap2) else: m.remove_layer(basemap2) except Exception: pass show_sat.observe(show_sat_changed) try: df = raster_utils.create_df(ci_path, pid, ci_band.value) geotiff = normpath( join(ci_path, f"{df['imgs'][0]}.{ci_band.value[0]}.tif")) bounds = raster_utils.bounds(geotiff) images = {} for i, row in df.iterrows(): str_date = str(row['date'].date()).replace('-', '') img_tc = normpath( join(ci_path, f"{('').join(ci_band.value)}_{str_date}.png")) # Create false color image if it does not exist # Merge bands (images path, export image path, bands list) if not isfile(img_tc): imgs_path = normpath(join(ci_path, row['imgs'])) raster_utils.merge_bands(imgs_path, img_tc, ci_band.value) if bool(config.get_value(['set', 'jupyterlab'])) is True: jlab_path = os.getcwd().replace(os.path.expanduser("~"), '') image_path = normpath(join(f'files{jlab_path}', img_tc)) else: image_path = img_tc # print('image_path: ', image_path) images[i] = ImageOverlay(url=image_path, name=str_date, bounds=(bounds)) # Time slider slider = IntSlider(value=1, min=1, max=len(images), step=1, description=str(df['date'][0].date()), continuous_update=False, orientation='horizontal', readout=True, readout_format='d') show_chip = Checkbox(value=True, description='Chip image', indent=False, layout=Layout(width='140px')) def on_ci_band_change(change): pass ci_band.observe(on_ci_band_change, 'value') def show_chip_changed(b): try: if show_chip.value is True: m.add_layer(images[slider.value - 1]) else: m.remove_layer(images[slider.value - 1]) except Exception: pass show_chip.observe(show_chip_changed) # Slider control play = Play( value=1, min=1, max=len(images), step=1, interval=1000, description="Press play", ) def slider_changed(b): if show_chip.value is True: try: m.substitute_layer(images[b['old'] - 1], images[b['new'] - 1]) except Exception: pass slider.description = str(df['date'][slider.value - 1].date()) slider.observe(slider_changed) jslink((play, 'value'), (slider, 'value')) time_box = HBox([slider, play]) time_control = WidgetControl(widget=time_box, position='bottomleft') m.add_control(time_control) m.add_layer(images[0]) map_options = VBox([show_poly, show_chip, show_sat]) except Exception as err: map_options = VBox([show_poly, show_sat]) print(err) layers_control = WidgetControl(widget=map_options, position='topright', max_width=150) m.add_control(layers_control) return m
def plot_maps_dataset_list(dataset_list, client, column='guid', category=False, basemap=True): """Create map window using dataset list. Should be okay whether it is shapefile or geotiff Args: dataset_list (list): A list of dataset to be mapped. column (str): column name to be plot client (Client): pyincore service Client Object category (boolean): turn on/off category option basemap (boolean): turn on/off base map (e.g. openstreetmap) Returns: map(ipyleaflet.Map): ipyleaflet map obejct """ layer_list = [] bbox_all = [9999, 9999, -9999, -9999] for dataset in dataset_list: # check if dataset is shapefile or raster try: if dataset.metadata['format'].lower() == 'shapefile': gdf = gpd.read_file(dataset.local_file_path) geodata = GeoUtil.create_geodata_from_geodataframe( gdf, dataset.metadata['title']) bbox = gdf.total_bounds bbox_all = GeoUtil.merge_bbox(bbox_all, bbox) layer_list.append(geodata) elif dataset.metadata['format'].lower( ) == 'table' or dataset.metadata['format'] == 'csv': # check source dataset gdf = GeoUtil.join_table_dataset_with_source_dataset( dataset, client) if gdf is None: print(dataset.metadata['title'] + "'s data format" + dataset.metadata['format'] + " is not supported.") else: geodata = GeoUtil.create_geodata_from_geodataframe( gdf, dataset.metadata['title']) bbox = gdf.total_bounds bbox_all = GeoUtil.merge_bbox(bbox_all, bbox) layer_list.append(geodata) elif dataset.metadata['format'].lower() == 'raster' \ or dataset.metadata['format'].lower() == 'geotif' \ or dataset.metadata['format'].lower() == 'geotif': input_path = dataset.get_file_path('tif') bbox = GeoUtil.get_raster_boundary(input_path) bbox_all = GeoUtil.merge_bbox(bbox_all, bbox) image_url = GeoUtil.create_data_img_url_from_geotiff_for_ipyleaflet( input_path) image = ImageOverlay(url=image_url, bounds=((bbox[1], bbox[0]), (bbox[3], bbox[2]))) layer_list.append(image) else: print(dataset.metadata['title'] + "'s data format" + dataset.metadata['format'] + " is not supported.") except Exception: print( "There is a problem in dataset format for ' + dataset.metadata['title'] + '." ) map = GeoUtil.get_ipyleaflet_map(bbox_all) for layer in layer_list: map.add_layer(layer) map.add_control(ipylft.LayersControl()) return map