def get_polygon(mask, lat, lon): x0 = lon x1 = x0 + mask.shape[1] / 1200 y0 = lat y1 = y0 - mask.shape[0] / 1200 mask2 = np.zeros((mask.shape[0] + 2, mask.shape[1] + 2), dtype=np.uint16) mask2[1:-1, 1:-1] = mask affine = Affine(1 / 1200, 0, lon - 1 / 1200, 0, -1 / 1200, lat + 1 / 1200) shapes = list(rasterio.features.shapes(mask2, transform=affine)) polygons = [] polygon = polygons i = 0 for shape in shapes: if len(shape[0]['coordinates'][0]) > 5: if i == 1: # more than one polygon polygons = [polygons] if i >= 1: polygons.append([]) polygon = polygons[-1] for coord in shape[0]['coordinates'][0]: x, y = coord polygon.append((y, x)) i += 1 polygon = Polygon(locations=polygons, color='green', fill_color='green') return polygon
def __init__(self, center=(41.8204600, 1.8676800), zoom=9): self.map = Map(center=center, zoom=zoom, basemap=basemaps.OpenStreetMap.HOT) polygon = Polygon(locations=[[]], color="green", fill_color="green") def handle_click(**kwargs): if kwargs.get('type') == 'click': pol = next(layer for layer in self.map.layers if isinstance(layer, Polygon)) coords = kwargs.get('coordinates') if (len(polygon.locations) == 0): pol.locations[0].extend([coords, coords]) else: pol.locations[0].insert(1, coords) self.map.remove_layer(pol) other = Polygon(locations=pol.locations, color="green", fill_color="green") self.map.add_layer(other) if kwargs.get('type') == 'contextmenu': pol = next(layer for layer in self.map.layers if isinstance(layer, Polygon)) self.map.remove_layer(pol) other = Polygon(locations=[[]], color="green", fill_color="green") self.map.add_layer(other) self.map.on_interaction(handle_click) self.map.add_layer(polygon) display(self.map)
def airspace_leaflet(airspace: Airspace, **kwargs) -> Polygon: shape = airspace.flatten() kwargs = {**dict(weight=3), **kwargs} return Polygon(locations=list( (lat, lon) for (lon, lat) in shape.exterior.coords), **kwargs)
def ipyleaflet_contourmap( center, datapoints=None, contourmap=None, isolines=[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], lineopacity=1.0, colormap=linear.viridis, fillopacity=0.7, legend_title='Legend', m=None, zoom=11, width='600px', height='400px'): if m is None: m = Map(center=center, zoom=zoom) m.layout.width = width m.layout.height = height cs = contourmap colors = [ colormap(i / (len(cs.levels) - 1)) for i in range(len(cs.levels) - 1) ] allsegs = cs.allsegs allkinds = cs.allkinds for clev in range(len(cs.allsegs)): kinds = None if allkinds is None else allkinds[clev] segs = split_contours(allsegs[clev], kinds) polygons = Polygon( locations=[p.tolist() for p in segs], # locations=segs[14].tolist(), color=colors[clev], weight=2, opacity=lineopacity, fill_color=colors[clev], fill_opacity=fillopacity) m.add_layer(polygons) if datapoints is not None: m = ipyleaflet_scatterplot_per_class(datapoints[0], datapoints[1], proportion=1.0, m=m) legend_colors = {} for i in reversed(range(len(isolines) - 1)): legend_colors["{:0.1f}-{:0.1f}".format( isolines[i], isolines[i + 1])] = colormap(i / (len(isolines) - 1)) legend = LegendControl(legend_colors, name=legend_title, position="topright") m.add_control(legend) return m
def _update_domain_render(self): if self.polygon is not None: self.m.remove_layer(self.polygon) if len(self.domain_coords) > 1: self.polygon = Polygon( locations=self.domain_coords, color="green", fill_color="green" ) self.m.add_layer(self.polygon) else: self.polygon = None
def airspace_leaflet(airspace: Airspace, **kwargs) -> Polygon: shape = airspace.flatten() kwargs = {**dict(weight=3), **kwargs} coords: List[Any] = [] if shape.geom_type == "Polygon": coords = list((lat, lon) for (lon, lat) in shape.exterior.coords) else: coords = list( list((lat, lon) for (lon, lat) in piece.exterior.coords) for piece in shape) return Polygon(locations=coords, **kwargs)
def bdc_plot_datasets(datasets, zoom=4, layout=Layout(width='600px', height='600px')): """Plot Dataset tiles """ bbox = get_bounds(datasets, datasets[0].crs) bbox_pol = shapely.wkt.loads(bbox.wkt) project = partial(pyproj.transform, pyproj.Proj(datasets[0].crs.crs_str), pyproj.Proj(init='epsg:4674')) bbox_pol_wgs84 = transform(project, bbox_pol) bbox = bbox_pol_wgs84.bounds center = ((bbox[1] + bbox[3]) / 2, (bbox[0] + bbox[2]) / 2) m = Map(basemap=basemaps.Esri.WorldImagery, center=center, zoom=zoom, layout=layout) grid = WMSLayer( url='http://brazildatacube.dpi.inpe.br/bdc/geoserver/grids/ows', layers='BDC_GRID', styles='tiles', format='image/png', transparent=True, tile_size=512) m.add_layer(grid) if len(datasets): project = partial(pyproj.transform, pyproj.Proj(datasets[0].crs.crs_str), pyproj.Proj(init='epsg:4674')) plotted = [] for ds in datasets: idt = "{},{};{},{}".format(ds.metadata.lon[0], ds.metadata.lat[0], ds.metadata.lon[1], ds.metadata.lat[1]) if idt not in plotted: plotted.append(idt) # apply projection ds_pol = transform(project, shapely.wkt.loads(ds.extent.wkt)) x, y = ds_pol.exterior.xy points = [(y1, x1) for x1, y1 in zip(x, y)] polygon = Polygon(locations=points, color="#0033CC", fill_color="#388b8b", weight=2, fill_opacity=.6) m.add_layer(polygon) return m
def handle_click(**kwargs): if kwargs.get('type') == 'click': pol = next(layer for layer in self.map.layers if isinstance(layer, Polygon)) coords = kwargs.get('coordinates') if (len(polygon.locations) == 0): pol.locations[0].extend([coords, coords]) else: pol.locations[0].insert(1, coords) self.map.remove_layer(pol) other = Polygon(locations=pol.locations, color="green", fill_color="green") self.map.add_layer(other) if kwargs.get('type') == 'contextmenu': pol = next(layer for layer in self.map.layers if isinstance(layer, Polygon)) self.map.remove_layer(pol) other = Polygon(locations=[[]], color="green", fill_color="green") self.map.add_layer(other)
def init_map(self): self.mainmap = ilfl.Map(basemap=ilfl.basemaps.Gaode.Satellite, center=[self.lat, self.lon], zoom=self.zoom) self.marker = ilfl.Marker(location=[self.lat, self.lon], draggable=True) self.mainmap.add_layer(self.marker) self.pr_selection = self.idxs.data.index[0] self.record = self.spatial_index.data.loc[self.pr_selection] self.map_polygon = Polygon(locations=[ (self.record.lat_UL, self.record.lon_UL), (self.record.lat_UR, self.record.lon_UR), (self.record.lat_LR, self.record.lon_LR), (self.record.lat_LL, self.record.lon_LL) ], color="blue") self.mainmap.add_layer(self.map_polygon)
def airspace_leaflet(airspace: "Airspace", **kwargs) -> Polygon: """Returns a Leaflet layer to be directly added to a Map. .. warning:: This is only available if the Leaflet `plugin <plugins.html>`_ is activated. (true by default) The elements passed as kwargs as passed as is to the Polygon constructor. """ shape = airspace.flatten() kwargs = {**dict(weight=3), **kwargs} coords: List[Any] = [] if shape.geom_type == "Polygon": coords = list((lat, lon) for (lon, lat) in shape.exterior.coords) else: coords = list( list((lat, lon) for (lon, lat) in piece.exterior.coords) for piece in shape) return Polygon(locations=coords, **kwargs)
def update_Map(keys,polysel,df): """Update ipyleaflet Map with query results Parameters: keys (list): list of product names polysel (dict): dictionary containing the AOI coordinates df (pandas dataframe): dataframe containing query results Returns: Map containing the drawn AOI and single product footprints (ipyleaflet Map) """ polygon = Polygon( locations=make_locations(polysel), color="dodgerblue", fill_color="dodgerblue" ) ind = [list(key)[1] for key in keys][0] objects = see_footprint(df,ind) # single footprint related to the (selected) product m = Map(basemap=basemaps.Esri.WorldTopoMap, center=centre(polysel), zoom=3,dragging=True,scroll_wheel_zoom=True) # initial map m.add_layer(polygon); # reference polygon (user input) for obj in objects: m.add_layer(obj); 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])
def see_footprint(dataframe,i): """Draw the single product footprint Parameters: dataframe (pandas dataframe): query results (from function: search) i (int): index of a single product Returns: polygons per each product (list), with different color attribute """ colors = ["orange","forestgreen","blue","violet"] if "S1" in dataframe.iloc[i,1]: color = colors[0] elif "S2" in dataframe.iloc[i,1]: color = colors[1] elif "S3" in dataframe.iloc[i,1]: color = colors[2] elif "S5" in dataframe.iloc[i,1]: color = colors[3] else: color = "gray" objects = list() # list containing polygons if "MULT" in dataframe.iloc[i,4]: tmp = dataframe.iloc[i,4][14:-1].split("))")[0:-1] if len(tmp) == 1: # multipolygon that is a polygon actually string = tmp[0][2:].split(",")[:-1] b = list() for s in string: temp = s.split(" ") tlist = [float(temp[-1]),float(temp[-2])] # fixed b.append(tuple(tlist)) obj = Polygon( locations=b, color=color, fill_color=color ) objects.append(obj) # len 1 else: # this is a true multipolygon for k in range(len(tmp)): # instances help in finding how to split string if k > 0: string = tmp[k][3:].split(",")[:-1] b = list() for s in string: temp = s.split(" ") tlist = [float(temp[-1]),float(temp[-2])] # fixed b.append(tuple(tlist)) obj = Polygon( locations=b, color=color, fill_color=color ) objects.append(obj) else: string = tmp[k][2:].split(",")[:-1] b = list() for s in string: temp = s.split(" ") tlist = [float(temp[-1]),float(temp[-2])] # fixed b.append(tuple(tlist)) obj = Polygon( locations=b, color=color, fill_color=color ) objects.append(obj) else: # this is a simple POLYGON string = dataframe.iloc[i,4][10:-2].split(",")[:-1] b = list() for s in string: temp = s.split(" ") tlist = [float(temp[-1]),float(temp[-2])] # fix b.append(tuple(tlist)) obj = Polygon( locations=b, color=color, fill_color=color ) objects.append(obj) return objects
def update_selected_cells(self, *args, **kwargs): """ """ # clear all draw and selection layers self.draw_control.clear() # -------------------------------------------------------------------- # update active cells and make a big merged polgyon for selection # make shapely geom from geojson drawn_json = kwargs["geo_json"] shapely_geom = shape(drawn_json["geometry"]) cells = self.grid_dict # iterate over cells and collect intersecting cells on = [] for id, cell in cells.items(): if shapely_geom.intersects(cell.shape): on.append(cell.shape) # this is blatant abuse of try/except; fix it try: # get the union of all of the cells that are toggled on union = cascaded_union(on) centroid = union.centroid # make layer that represents selected cells and add to selected_layer self.selected_layer.clear_layers() x, y = union.exterior.coords.xy self.selected_layer.add_layer(Polygon(locations=list(zip(y, x)))) self.map.center = (centroid.y, centroid.x) # -------------------------------------------------------------- # find all CMR collections that intersect with merged cells geom selected = [] for index, collection in above_results_df.iterrows(): box = collection.boxes shapely_box = CMR_box_to_Shapely_box(box[0]) # intersect: use shapely_geom if strictly using drawn poly intersect_bool = shapely_box.intersects(union) if intersect_bool: selected.append(index) self.coll = above_results_df.iloc[selected] self.tab = qgrid.show_grid( self.coll[["dataset_id", "time_start", "time_end", "boxes"]], grid_options={ 'forceFitColumns': False, 'minColumnWidth': "0", 'maxColumnWidth': "400" }, show_toolbar=False) self.output.clear_output() with self.output: display(self.tab) #display(self.coll[[ # "dataset_id", "time_start", "time_end", "boxes"]]) except: pass
def create_layer(geo_table, name, label_col=None, secondary_label_col=None, layer_type=None, inverse=False, **kwargs): if 'color' in kwargs: color = kwargs['color'] else: color = 'orange' output = LayerGroup(name=name) geo_table = clean_table(geo_table) if 'filter_on' in kwargs.keys(): filter_col = kwargs['filter_on'] if inverse: geo_table = geo_table[geo_table[filter_col].isna()] else: geo_table = geo_table[~geo_table[filter_col].isna()] if layer_type is None: raise (ValueError('must provide a type of layer to make with table!')) for _, row in geo_table.iterrows(): if layer_type == 'polygon': y = list(row.geometry.exterior.coords.xy[1]) x = list(row.geometry.exterior.coords.xy[0]) locations = [(y, x) for y, x in zip(y, x)] temp_layer = Polygon( locations=locations, color=color, fill_color=color, opacity=0.8, ) elif layer_type == 'marker': temp_layer = CircleMarker( location=(row.geometry.y, row.geometry.x), color=color, radius=5, fill_color=color, ) if label_col is not None: if secondary_label_col is not None: extra_labels = row[secondary_label_col] if extra_labels is None: extra_labels = '' else: extra_labels = extra_labels.split(',') size = len(extra_labels) if size > 6: size = 6 extra_labels = extra_labels[:size] extra_labels.append('truncated') extra_labels = '\n'.join(extra_labels[:size]) else: extra_labels = '' message = HTML() message.value = extra_labels message.description = row[label_col] temp_layer.popup = message temp_layer.popup_max_width = 800 output.add_layer(temp_layer) geo_table.to_file(name + '.shp') return output
def TheisContours(self, T, qs, bnds=None, grad=[0, 0], levels=(0.5, 0.75, 1, 1.25, 1.5, 1.75, 2.0)): lats = [] lons = [] for w in self.wells: lat, lon = w.location lats.append(lat) lons.append(lon) xs, ys = transform(outProj, inProj, lats, lons) if bnds is None: xs2, ys2 = xs, ys else: for bnd in bnds: lat, lon = bnd lats.append(lat) lons.append(lon) xs2, ys2 = transform(outProj, inProj, lats, lons) n = 100 x0, x1 = np.min(xs2), np.max(xs2) xr = x1 - x0 y0, y1 = np.min(ys2), np.max(ys2) yr = y1 - y0 xx, yy = np.meshgrid(np.linspace(x0 - 0.05 * xr, x1 + 0.05 * xr, n), np.linspace(y0 - 0.05 * yr, y1 + 0.05 * yr, n)) hh = 0. * xx + grad[0] * (np.cos(grad[1]) * (xx - xs[0]) + np.sin(grad[1]) * (yy - ys[0])) #/1.e3 try: t = self.widgets['t'].value except KeyError: t = 100. for w, x, y, q in zip(self.wells, xs, ys, qs): hh += Theis(np.sqrt((xx.flatten() - x)**2 + (yy.flatten() - y)**2), t * 24 * 3600, T, 1.e-4, q).reshape(xx.shape) lat, lon = transform(inProj, outProj, xx.flatten(), yy.flatten()) cs = plt.contourf(lat.reshape(xx.shape), lon.reshape(yy.shape), hh, levels=levels, extend='both') ts = plt.clabel( cs, levels=[l for l, a in zip(cs.levels, cs.allsegs) if len(a) > 0]) plt.close() allsegs = cs.allsegs allkinds = cs.allkinds cmap = cm.Blues colors = [ '#%02x%02x%02x' % tuple(int(j * 255) for j in cmap(i)[:3]) for i in np.linspace(0, 1, len(allsegs)) ] alphas = np.linspace(0.2, 0.7, len(allsegs)) ps = [] for clev in range(len(cs.allsegs)): kinds = None if allkinds is None else allkinds[clev] segs = split_contours(allsegs[clev], kinds) polygons = Polygon(locations=[p.tolist() for p in segs], color='yellow', weight=1, opacity=1., fill_color=colors[clev], fill_opacity=alphas[clev]) ps.append(polygons) return ps, ts
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