Esempio n. 1
0
class Cell(object):
    """ """

    offstyle = {"fill_opacity": 0, "color": "white", "weight": 0.75}
    onstyle = {"fill_opacity": 0.4, "color": "lightgreen", "weight": 1}

    def __init__(self, feat):
        """Inits with id,lat,lon; makes request string, map point."""

        self.feat = feat
        self.shape = shape(feat["geometry"])

        self.prop = feat["properties"]
        self.feat["properties"]["style"] = {
            "fill_opacity": 0.1,
            "opacity": 0.1,
            "color": "white",
            "weight": 0.75
        }
        self.id = self.prop["grid_id"]
        self.level = self.prop["grid_level"]

        self.layer = GeoJSON(data=self.feat,
                             hover_style={
                                 "weight": 1,
                                 "color": "white",
                                 "fillColor": "white",
                                 "fillOpacity": 0.3
                             })
        self.layer.on_click(self.toggle)
        self.on = False

    def toggle(self, **kwargs):
        """Routine for when a cell is toggled on."""
        self.on = False if self.on else True
Esempio n. 2
0
    def __init__(self, feat):
        """Inits with id,lat,lon; makes request string, map point."""

        self.feat = feat
        self.shape = shape(feat["geometry"])

        self.prop = feat["properties"]
        self.feat["properties"]["style"] = {
            "fill_opacity": 0.1,
            "opacity": 0.1,
            "color": "white",
            "weight": 0.75
        }
        self.id = self.prop["grid_id"]
        self.level = self.prop["grid_level"]

        self.layer = GeoJSON(data=self.feat,
                             hover_style={
                                 "weight": 1,
                                 "color": "white",
                                 "fillColor": "white",
                                 "fillOpacity": 0.3
                             })
        self.layer.on_click(self.toggle)
        self.on = False
    def prepare_map(dc, m):

        dc.rectangle = {'shapeOptions': {'color': '#FF0000'}}
        dc.marker = {
            "shapeOptions": {
                "fillColor": "#fca45d",
                "color": "#fca45d",
                "fillOpacity": 1.0
            }
        }
        dc.polyline = {}
        dc.polygon = {}
        dc.circlemarker = {}

        # Create a group of layers and add it to the Map
        group = LayerGroup()
        m.add_layer(group)

        # given Africa: N: 38.25, S: -36.25, E: 53.25, W: -19.25
        africa = GeoJSON(data={
            'type': 'Feature',
            'properties': {
                'name': "Africa",
                'style': {
                    'color': '#0000FF',
                    'clickable': True
                }
            },
            'geometry': {
                'type': 'Polygon',
                'coordinates': [[[-19, 38], [53, 38], [53, -36], [-19, -36]]]
            }
        },
                         hover_style={'fillColor': '03449e'})

        group.add_layer(africa)

        # given Colombia: N: 13.75, S: -5.25, E: -62.75, W: -83.25
        colombia = GeoJSON(data={
            'type': 'Feature',
            'properties': {
                'name': "Colombia",
                'style': {
                    'color': '#0000FF',
                    'clickable': True
                }
            },
            'geometry': {
                'type': 'Polygon',
                'coordinates': [[[-83, 14], [-63, 14], [-63, -5], [-83, -5]]]
            }
        },
                           hover_style={'fillColor': '03449e'})

        group.add_layer(colombia)
Esempio n. 4
0
def map_shapefile(gdf, colormap=mpl.cm.YlOrRd, weight=2, default_zoom=13):
    def n_colors(n, colormap=colormap):
        data = np.linspace(0.0, 1.0, n)
        c = [mpl.colors.rgb2hex(d[0:3]) for d in colormap(data)]
        return c

    def data_to_colors(data, colormap=colormap):
        c = [
            mpl.colors.rgb2hex(d[0:3])
            for d in colormap(mpl.colors.Normalize()(data))
        ]
        return c

    def click_handler(event=None,
                      id=None,
                      properties=None,
                      type=None,
                      coordinates=None):
        try:
            datasetID = properties['time']
            print(datasetID)
        except:
            pass

    # Convert to WGS 84 and geojson format
    gdf_wgs84 = gdf.to_crs(epsg=4326)
    data = gdf_wgs84.__geo_interface__

    # For each feature in dataset, append colour values
    n_features = len(data['features'])
    colors = n_colors(n_features)

    for feature, color in zip(data['features'], colors):
        feature['properties']['style'] = {
            'color': color,
            'weight': weight,
            'fillColor': color,
            'fillOpacity': 1.0
        }

    # Get centroid to focus map on
    lon, lat = gdf_wgs84.unary_union.centroid.coords.xy

    # Plot map and add geojson layers
    m = Map(center=(lat[0], lon[0]),
            zoom=default_zoom,
            basemap=basemaps.Esri.WorldImagery,
            layout=dict(width='800px', height='600px'))
    feature_layer = GeoJSON(data=data)
    feature_layer.on_click(click_handler)
    m.add_layer(feature_layer)

    return m
Esempio n. 5
0
def force(south, north, west, east):
    """Force a rectangle onto the map.
    
    Arguments:
        south: float
        north: float
        west: float
        east: float
        
    Returns:
        None
    """

    # check for values
    if all([cardinal is not None for cardinal in [south, north, west, east]]):

        # construct coordinates
        coordinates = [[[west, south], [west, north], [east, north],
                        [east, south], [west, south]]]

        # construct geo_json
        geo_json = {'type': 'Feature'}
        geo_json['properties'] = {
            'style': chart.controls[-1].rectangle['shapeOptions']
        }
        geo_json['geometry'] = {'type': 'Polygon', 'coordinates': coordinates}

        # add rectangle to chart
        chart.add_layer(GeoJSON(data=geo_json))

    return None
    def _load_shapes(self, widget, event, data):

        # get the data from the selected file
        gdf, column = self.load_shape.read_data()

        gdf = gdf.filter(items=[column, "geometry"])

        # add them to the map
        for i, row in gdf.iterrows():

            # transform the data into a feature
            feat = {
                "type": "Feature",
                "properties": {
                    "style": {}
                },
                "geometry": row.geometry.__geo_interface__,
            }
            self._add_geom(feat, row[column])

        # display a tmp geometry before validation
        data = json.loads(gdf.to_json())
        style = {
            **cp.aoi_style,
            "color": sc.info,
            "fillColor": sc.info,
            "opacity": 0.5,
            "weight": 2,
        }
        layer = GeoJSON(data=data, style=style, name="tmp")
        self.m.add_layer(layer)

        return
    def _save_features(self):
        """save the features as layers on the map"""

        # remove any sub aoi layer
        layers_2_keep = [
            "CartoDB.DarkMatter", "restoration layer", self.aoi_model.name
        ]
        [
            self.m.remove_layer(l) for l in self.m.layers
            if l.name not in layers_2_keep
        ]

        # save the drawn features
        draw_features = self.draw_features

        # remove the shapes from the dc
        # as a side effect the draw_features member will be emptied
        self.m.dc.clear()

        # reset the draw_features
        # I'm sure the the AOI folder exists because the recipe was already saved there
        self.draw_features = draw_features
        features_file = (cp.result_dir / self.aoi_model.name /
                         f"features_{self.question_model.recipe_name}.geojson")
        with features_file.open("w") as f:
            json.dump(draw_features, f)

        # set up the colors using the tab10 matplotlib colormap
        self.colors = [
            to_hex(plt.cm.tab10(i))
            for i in range(len(self.draw_features["features"]))
        ]

        # create a layer for each aoi
        for feat, color in zip(self.draw_features["features"], self.colors):
            name = feat["properties"]["name"]
            style = {**cp.aoi_style, "color": color, "fillColor": color}
            hover_style = {**style, "fillOpacity": 0.4, "weight": 2}
            layer = GeoJSON(data=feat,
                            style=style,
                            hover_style=hover_style,
                            name=name)
            layer.on_hover(self._display_name)
            self.m.add_layer(layer)

        return self
Esempio n. 8
0
    def show_restrictions(b):
        polygons = './vehiclerestrictions_wgs.json'

        with open(polygons) as f:
            polygons_json = json.load(f)

        global geojson
        geojson = GeoJSON(data=polygons_json)
        m.add_layer(geojson)
Esempio n. 9
0
    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)
Esempio n. 10
0
 def show_geojson(self, *args):
     data = json.loads(
         list(
             self.file_upload.value.values())[0]['content'].decode('ascii'))
     self.remove_marker()
     self.remove_geojson()
     self.geojson = GeoJSON(
         data=data,
         style={'color': 'green'})  #, 'opacity': 1})#, 'fillOpacity':0.1})
     self.m.add_layer(self.geojson)
     self.marker_or_geojson = 'GeoJSON'
Esempio n. 11
0
    def _handle_draw(self, action, geo_json):
        self.clear()
        leaflet_map.remove_layer(leaflet_map.layers[1])
        geometry_layer = GeoJSON(data=geo_json['geometry'])
        leaflet_map.add_layer(geometry_layer)

        roi_shape = shape(leaflet_map.layers[1].data)
        roi_area.value = roi_shape.wkt
        roi_validation.value = html_element(
            'h3',
            att=dict(style=f'color:green'),
            value='Region of Interest defined.')
Esempio n. 12
0
def filter_layer(df, name, start, end):
    if start is None and end is None:
        return df[['timestamp', 'geometry']].to_json()
    filtered_frame = df[df.date.between(start, end)][['timestamp', 'geometry']].to_json()
    geo_layer = GeoJSON(
        name=name,
        data=json.loads(filtered_frame),
        style={
            'opacity': 0.5, 'dashArray': '9', 'fillOpacity': 0.1, 'weight': 0.5
        }
    )
    return geo_layer
def show_map(selected_stats, year): 
    control = WidgetControl(widget=districtbox, position='topright', min_width = 250, max_width=500)

    # load selected stats into choro_data_all
    choro_data_all, unit = choro_data_complete[selected_stats], units[selected_stats]
    # for geo plot extract chosen year and assign to choro_data
    choro_data = choro_data_all[choro_data_all['year']==year]
    choro_data = dict(choro_data.drop(columns=['year', 'name']).to_dict('split')['data'])
    
    # initialize bar chart with Frankfurt vs Offenbach
    update_figure('06412', selected_stats, choro_data_all, year)
    update_figure('06413', selected_stats, choro_data_all, year)

    # initialize districtbox
    loading_name, loading_values = id_to_name['06413'], choro_data['06413']
    districtbox.value = f'<center><p><b>{loading_name}</b>:</p> {loading_values:g} {unit} {norm_unit}</center>'
    
    # set y-axis label
    fig.update_layout(yaxis_title=f'{stat_dict[selected_stats]} [{unit} {norm_unit}]', yaxis={'range':[0,max(choro_data_all[selected_stats])]})
    

    # define chropleth layer for basic geo plotting
    layer = Choropleth(geo_data=geo_data,choro_data=choro_data,colormap=cm,
                       style={'fillOpacity': 0.65, 'dashArray': '0, 0', 'weight':1})
    
    # define GeoJSON layer for click and hover event interactions
    geo_json = GeoJSON(data=geo_data,
                       style={'opacity': 0, 'dashArray': '9', 'fillOpacity': .0, 'weight': 1},
                       hover_style={'color': 'blue', 'dashArray': '0', 'fillOpacity': 0.7})

    # on hover, the districtbox is updated to show properties of the hovered district
    def update_districtbox(feature,  **kwargs):
        feature['value'] = choro_data[feature['id']]
        districtbox.value = f'<center><p><b>{id_to_name[feature["id"]]}</b>:</p> {feature["value"]:g} {unit} {norm_unit}</center>'

    # this function is called upon a click events and triggers figure update with the arguments passed from the map
    def update_fig_on_click(feature, **kwags):
        update_figure(feature['id'], selected_stats, choro_data_all, year)
    geo_json.on_hover(update_districtbox)
    geo_json.on_click(update_fig_on_click)

    # add layers and controls; set layout parameters
    m = Map(basemap=basemaps.OpenStreetMap.Mapnik, center=(50.5,9), zoom=8)
    m.add_layer(layer)
    m.add_layer(geo_json)
    m.add_control(control)
    m.layout.width = '40%'
    m.layout.height = '700px'

    # custom made legend using min/max normalization
    min_value, max_value = min(choro_data.values()), max(choro_data.values())
    legend = LegendControl(
          {f"{min_value:g} {unit}  {norm_unit}": cm(0), #hier
          f"{min_value+0.5*(max_value-min_value):g} {unit}  {norm_unit}": cm(.5),
          f"{max_value:g} {unit}  {norm_unit}": cm(1)},
          name= f"{stat_dict[selected_stats]} ({year})", position="bottomleft")
    m.add_control(legend)
    return HBox([m, fig], layout=Layout(width='85%'))

    
Esempio n. 14
0
def addS2Tiles(inMap):
    with open('./Shapefiles/Europe.geojson') as f:
        data = json.load(f)
    for feature in data['features']:
        feature['properties']['style'] = {
            'color': 'grey',
            'weight': 1,
            'fillColor': None,
            'fillOpacity': 0.1    }

    s2_tiles_layer = GeoJSON(data=data,name='S2_tiles')
    inMap.map.add_layer(s2_tiles_layer)
    return
Esempio n. 15
0
def areaCommand(x):    
    if x:        
        for l in map.layers[1:]:            
            map.remove_layer(l)        
        cursor.execute("SELECT ST_AsGeoJSON(i.geom) FROM incidents i JOIN areacommand acmd ON ST_Intersects(acmd.geom, i.geom) WHERE acmd.name like'{}' and date >= NOW() - interval '10 day';".format(x))
        c=cursor.fetchall()
        for x in c:            
            layer=json.loads(x[0])            
            layergeojson=GeoJSON(data=layer)            
            map.add_layer(layergeojson)        
        return c    
    else:        
        pass 
Esempio n. 16
0
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
Esempio n. 17
0
def get_ipy(wards, wardcentres, const, constcentres, x="ratio"):
    from ipyleaflet import Map, Marker, GeoJSON, basemaps, GeoData, LayersControl
    from pymapbox.utils import geojson

    m = Map()
    m.center = [52.1917, -1.7083]
    m.zoom = 10
    m.scroll_wheel_zoom = True

    x, cats, colorset, wards = get_cats(x, wards)

    # create style columns
    wards["fillcolor"] = wards[x].map(dict(zip(cats, colorset)))
    wards = wards[["geometry", "wardname", "fillcolor"]]
    wardcentres = wardcentres[["wardname", "geometry"]]

    def wardstyle(row):
        return dict(fillColor=row["properties"]["fillcolor"], fillOpacity=1)

    layer = GeoJSON(
        name="constituencies",
        data=geojson(const),
        style=dict(fillColor="#00000000", weight=3),
    )
    m.add_layer(layer)

    layer = GeoJSON(
        name="wards",
        data=geojson(wards),
        style_callback=wardstyle,
        style=dict(weight=1),
    )
    m.add_layer(layer)

    m.add_control(LayersControl())

    return m
def generate_route_map(pathToGeojson, zoomLevel=11):

    with open(pathToGeojson, "r") as f:
        data = json.load(f)
    ctrLon, ctrLat = np.mean(np.array(
        data['features'][0]['geometry']['coordinates']),
                             axis=0)
    url = "http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png"
    provider = TileLayer(url=url, opacity=1)
    center = [ctrLat, ctrLon]
    m = Map(default_tiles=provider, center=center, zoom=zoomLevel)
    m.layout = Layout(width='100%', height='800px')
    trueRouteCoords, resampledCoords, gpsRouteCoords, \
        displacementLines, gpsMatchCoords = data['features']
    g = GeoJSON(data=FeatureCollection([trueRouteCoords, gpsMatchCoords]))
    m.add_layer(g)
    for coords in resampledCoords['geometry']['coordinates']:
        cm = Circle(location=coords[::-1],
                    radius=10,
                    weight=1,
                    color='#ff0000',
                    opacity=1.0,
                    fill_opacity=0.4,
                    fill_color='#ff0000')
        m.add_layer(cm)
    for coords in gpsRouteCoords['geometry']['coordinates']:
        cm = Circle(location=coords[::-1],
                    radius=10,
                    weight=1,
                    color='#0000ff',
                    opacity=1.0,
                    fill_opacity=0.4,
                    fill_color='#0000ff')
        m.add_layer(cm)
    g = GeoJSON(data=displacementLines)
    m.add_layer(g)
    return m
Esempio n. 19
0
def theDate(x):
    if x:        
        for l in map.layers[1:]:        
        map.remove_layer(l)    
        nohyphen=str(x).replace("-","")    
        d=datetime.datetime.strptime(nohyphen,'%Y%m%d').date()    
        cursor.execute("SELECT ST_AsGeoJSON(geom) from incidents where date = '{}' ".format(str(d)))    
        c=cursor.fetchall()
    for x in c:        
        layer=json.loads(x[0])        
        layergeojson=GeoJSON(data=layer)        
        map.add_layer(layergeojson)    
    return len(c)
    else:        
        pass
Esempio n. 20
0
    def get_ipygeojson(self):
        """return a ipygeojson layer ready to be displayed on the map"""

        if self.gdf is None:
            raise Exception("Impossible to load layer without he json data")

        # create a GeoJSON object
        ipygeojson = GeoJSON(
            data=self.gdf.__geo_interface__,
            style=cp.alert_style,
            hover_style={
                **cp.alert_style, "weight": 5
            },
            name=cm.map.layer.alerts,
        )

        return ipygeojson
Esempio n. 21
0
        def wrapper(*args, **kwargs):
            legend_file = BytesIO()

            value = func(*args, **kwargs)

            overwrite_parameters(other_options, kwargs)
            overwrite_parameters(plot_options, kwargs)

            if isinstance(value, xr.Dataset):
                if "varin" not in kwargs_dec:
                    print("Error")
                geojson_str = return_geojson(value[kwargs_dec.get("varin")],
                                             plot_options, legend_file,
                                             **other_options)
                name = kwargs_dec.get("varin")
            else:
                name = value.name
                geojson_str = return_geojson(value, plot_options, legend_file,
                                             **other_options)

            geojson_data = json.loads(geojson_str)

            apply_style(geojson_data["features"])
            #if "country_file" in kwargs_dec:
            #    crop_country(geojson_data,country_file=kwargs_dec.get("country_file"))

            geojson_layer = GeoJSON(data=geojson_data, name=name)
            map_out = Map(zoom=6,
                          center=(float(value.latitude.mean().values),
                                  float(value.longitude.mean().values)))
            map_out.add_layer(geojson_layer)

            if kwargs_dec.get("borders", False):
                if "country_file" in kwargs_dec:
                    bord = Borders(fname=kwargs_dec.get("country_file"),
                                   color="black")
                    map_out.add_layer(bord)
            if plot_options["save_colorbar"]:
                legend_file.seek(0)
                legend = widgets.Image(layout=widgets.Layout(height="430px"))
                legend.value = legend_file.read()
                widg_out = widgets.HBox([map_out, legend])
            else:
                widg_out = map_out
            return widg_out
Esempio n. 22
0
    def _handle_roi_map_button_clicked(*args, **kwargs):
        try:
            geom = loads(roi_area.value)
            if type(geom) is not Polygon:
                _update_roi_status_for_error(
                    'User-provided Region of Interest is not of type Polygon.')
                return
            geojson_feature = geojson.Feature(geometry=geom, properties={})
            draw_control.clear()
            leaflet_map.remove_layer(leaflet_map.layers[1])
            geometry_layer = GeoJSON(data=geojson_feature['geometry'])
            leaflet_map.add_layer(geometry_layer)
            center_lon, center_lat = geom.centroid.coords.xy
            leaflet_map.center = [center_lat[0], center_lon[0]]

            @debug_view.capture(clear_output=False)
            def _adjust_zoom_level(event):
                if event['name'] == 'bounds' and leaflet_map.zoom < 18:
                    southwest, northeast = leaflet_map.bounds
                    map_bounds = Polygon([(southwest[1], southwest[0]),
                                          (southwest[1], northeast[0]),
                                          (northeast[1], northeast[0]),
                                          (northeast[1], southwest[0]),
                                          (southwest[1], southwest[0])])
                    if map_bounds.covers(geom):
                        leaflet_map.zoom = leaflet_map.zoom + 1
                    elif leaflet_map.zoom > 1:
                        leaflet_map.zoom = leaflet_map.zoom - 1
                        leaflet_map.unobserve(_adjust_zoom_level)

            leaflet_map.zoom = 1
            leaflet_map.observe(_adjust_zoom_level)
            if geom.is_valid:
                roi_validation.value = html_element(
                    'h3',
                    att=dict(style=f'color:green'),
                    value='Region of Interest defined.')
            else:
                roi_validation.value = html_element(
                    'h3',
                    att=dict(style=f'color:orange'),
                    value='User-provided Region of Interest is invalid.')
        except WKTReadingError:
            _update_roi_status_for_error(
                'User-provided Region of Interest cannot be read.')
Esempio n. 23
0
def show_locations_on_map(locations):
    m = Map(center=(40.7205, -73.9060), zoom=11)
    for locs in locations:
        parse_loc = {
            "type":
            "FeatureCollection",
            "features": [{
                "type": "Feature",
                "properties": {},
                "geometry": {
                    "type": "Point",
                    "coordinates": [locs[0], locs[1]]
                }
            }]
        }
        geo_json = GeoJSON(data=parse_loc)
        m.add_layer(geo_json)
    return m
Esempio n. 24
0
def layer_from_element(element, style_function=None):
    """Return Leaflet layer from shape.

    Parameters
    ----------
    element : telluric.vectors.GeoVector, telluric.features.GeoFeature, telluric.collections.BaseCollection
        Data to plot.

    """
    # This import is here to avoid cyclic references
    from telluric.collections import BaseCollection

    if isinstance(element, BaseCollection):
        styled_element = element.map(lambda feat: style_element(feat, style_function))

    else:
        styled_element = style_element(element, style_function)

    return GeoJSON(data=mapping(styled_element), name='GeoJSON')
Esempio n. 25
0
    def get_ipygeojson(self):
        """ 
        Converts current geopandas object into ipyleaflet GeoJSON
        
        Return: 
            (GeoJSON): the geojson layer of the aoi gdf
        """

        if type(self.gdf) == type(None):
            raise Exception(
                "You must set the gdf before converting it into GeoJSON")

        data = json.loads(self.gdf.to_json())
        self.ipygeojson = GeoJSON(data=data,
                                  style=AOI_STYLE,
                                  name='aoi',
                                  attribution='SEPA(c)')

        return self.ipygeojson
Esempio n. 26
0
def rid(self, action, geo_json):
    """Rid the map of previous polygons, keeping only the one drawn.
    
    Arguments:
        self: self
        action: action
        geo_json: dict
        
    Returns:
        None
    """

    # clear polygons and rectanges from draw control
    chart.controls[-1].clear_polygons()
    chart.controls[-1].clear_rectangles()

    # remove all previous layers
    chart.layers = chart.layers[:1]

    # add polygon to chart
    chart.add_layer(GeoJSON(data=geo_json))

    return None
Esempio n. 27
0
for footprint, color in zip(footprints, colors):
    # create the leaflet object
    feat = {
        'geometry': footprint,
        "properties": {
            'style': {
                'color': color,
                'fillColor': color,
                'fillOpacity': 0.2,
                'weight': 1
            }
        },
        'type': u"Feature"
    }
    # convert to geojson
    gjson = GeoJSON(data=feat)
    # add it our map
    m.add_layer(gjson)
# now we will draw our original AOI on top
feat = {
    'geometry': myAOI,
    "properties": {
        'style': {
            'color': "#FFFFFF",
            'fillColor': "#FFFFFF",
            'fillOpacity': 0.5,
            'weight': 1
        }
    },
    'type': u"Feature"
}
Esempio n. 28
0
    def handle_draw(self, action, geo_json):
        nonlocal polygon_number

        # Execute behaviour based on what the user draws
        if geo_json['geometry']['type'] == 'Polygon':

            # Convert the drawn geometry to pixel coordinates
            geom_selectedarea_flat, geom_selectedarea = transform_from_wgs_poly(
                geo_json['geometry'],
                EPSGa=3577  # hard-coded to be same as case-study data
            )

            geom_envelope = geom_selectedarea_flat.GetEnvelope()
            minX, maxX, minY, maxY = geom_envelope

            # Insert dc.load for dem and dlcdnsw
            x_range = (minX, maxX)
            y_range = (minY, maxY)
            inputcrs = "EPSG:3577"
            dem_res = (-5, 5)
            # dlcd_res is unused as the same res must be used when loading
            # multiple products (to support the cross count process). The
            # smallest cell size is used as this will provide the greatest
            # accuracy.
            dlcd_res = (-100, 100)  # unused

            slope_cat = get_slope_raster(dc, x_range, y_range, inputcrs,
                                         dem_res, geom_selectedarea)
            dlcd = get_dlcd_raster(dc, x_range, y_range, inputcrs, dem_res,
                                   geom_selectedarea)

            stacked = xr.merge([dlcd, slope_cat])
            cross_counts = unique_counts(stacked)

            slope_cat_count = slope_cat.to_dataframe(
            ).slope_category.value_counts().rename('counts').to_frame()
            slope_cat_count.index.name = 'index'
            slope_cat_table = pd.read_csv('slope_cat.csv')
            slope_coverage = pd.merge(slope_cat_count,
                                      slope_cat_table,
                                      how="left",
                                      left_on=['index'],
                                      right_on=['id'])

            # Compute the total number of pixels in the masked data set
            pix_dlcd = dlcd.count().compute().item()

            # Convert dlcd to pandas and get value counts for each class
            pd_dlcd = dlcd.to_dataframe()
            pd_dlcd_classcount = pd_dlcd.dlcd.value_counts().reset_index(
                name='counts')

            # Convert slope_cat to pandas and get value counts for each category
            # pd_slope_cat_count = slope_cat.to_dataframe().band1.value_counts()

            # Load DLCD land cover look-up table
            dlcd_lookup = pd.read_csv("dlcd.csv")

            # Join dlcd counts against landcover look up table
            pd_dlcd_coverage = pd.merge(pd_dlcd_classcount,
                                        dlcd_lookup,
                                        how="left",
                                        left_on=['index'],
                                        right_on=['id'])

            # Format the counts table to keep necessary items
            pd_dlcd_coverage['area(km^2)'] = pd_dlcd_coverage['counts'] * (
                dem_res[1] / 1000.)**2
            pd_dlcd_coverage['percentage_area'] = pd_dlcd_coverage[
                'counts'] / pd_dlcd_coverage['counts'].sum() * 100

            pd_dlcd_output = pd_dlcd_coverage[[
                'Name', 'area(km^2)', 'percentage_area'
            ]]

            # manipulate cross counts into format suitable for presentation as
            # a table
            pd_cross_counts = cross_counts.to_dataframe()
            pd_cross_counts.sort_values(by='count',
                                        ascending=False,
                                        inplace=True)
            # join DLCD lookup table for DLCD class names
            pd_cross_counts = pd.merge(pd_cross_counts,
                                       dlcd_lookup,
                                       how='left',
                                       left_on=['dlcd'],
                                       right_on=['id'])
            pd_cross_counts = pd_cross_counts.rename(columns={
                'dlcd': 'dlcd_id',
                'Name': 'DLCD'
            })
            # join slope category definition table for slope class names
            pd_cross_counts = pd.merge(pd_cross_counts,
                                       slope_cat_table,
                                       how='left',
                                       left_on=['slope_category'],
                                       right_on=['id'])
            pd_cross_counts['slope'] = (pd_cross_counts[[
                'label', 'range'
            ]].apply(lambda x: '{} {}'.format(x[0], x[1]), axis=1))

            # Format the counts table to keep necessary items
            pd_cross_counts['area(km^2)'] = (pd_cross_counts['count'] *
                                             (dem_res[1] / 1000.)**2)
            pd_cross_counts['percentage_area'] = (
                pd_cross_counts['count'] / pd_cross_counts['count'].sum() *
                100)

            pd_cross_counts_output = (pd_cross_counts[[
                'DLCD', 'slope', 'area(km^2)', 'percentage_area'
            ]])

            # display(pd_cross_counts)

            colour = colour_list[polygon_number % len(colour_list)]

            # Add a layer to the map to make the most recently drawn polygon
            # the same colour as the line on the plot
            studyarea_map.add_layer(
                GeoJSON(data=geo_json,
                        style={
                            'color': colour,
                            'opacity': 1,
                            'weight': 4.5,
                            'fillOpacity': 0.0
                        }))

            # Make the DLDC Summary plot
            ax.clear()
            pd_dlcd_output.plot.bar(x='Name',
                                    y='percentage_area',
                                    rot=45,
                                    ax=ax,
                                    legend=False,
                                    color=colour)
            ax.set_xlabel("Land Cover Class")
            ax.set_ylabel("Percentage Coverage Of Polygon")

            # refresh display
            fig_display.clear_output(
                wait=True)  # wait=True reduces flicker effect
            with fig_display:
                display(fig)

            info.clear_output(wait=True)  # wait=True reduces flicker effect
            with info:
                # use to_string function to avoid truncation of results
                print(pd_cross_counts_output.to_string())

            # Iterate the polygon number before drawing another polygon
            polygon_number = polygon_number + 1

        else:
            info.clear_output(wait=True)
            with info:
                print("Plot status: this drawing tool is not currently "
                      "supported. Please use the polygon tool.")
Esempio n. 29
0
def run_miningrehab_app(ds):
    """
    Plots an interactive map of the mining case-study area and allows
    the user to draw polygons. This returns plots of the fractional cover value
    of bare soil, green vegetation and brown vegetation in the polygon area.
    Last modified: January 2020

    inputs
    ds - data set containing masked Fractional Cover data from Landsat 8
    """

    # Suppress warnings
    warnings.filterwarnings("ignore")

    # Update plotting functionality through rcParams
    mpl.rcParams.update({"figure.autolayout": True})

    # Define the bounding box that will be overlayed on the interactive map
    # The bounds are hard-coded to match those from the loaded data
    geom_obj = {
        "type": "Feature",
        "properties": {
            "style": {
                "stroke": True,
                "color": "red",
                "weight": 4,
                "opacity": 0.8,
                "fill": True,
                "fillColor": False,
                "fillOpacity": 0,
                "showArea": True,
                "clickable": True,
            }
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[
                [116.630731, -34.434517],
                [116.630731, -34.426512],
                [116.648123, -34.426512],
                [116.648123, -34.434517],
                [116.630731, -34.434517],
            ]],
        },
    }

    # Create a map geometry from the geom_obj dictionary
    # center specifies where the background map view should focus on
    # zoom specifies how zoomed in the background map should be
    loadeddata_geometry = ogr.CreateGeometryFromJson(str(geom_obj["geometry"]))
    loadeddata_center = [
        loadeddata_geometry.Centroid().GetY(),
        loadeddata_geometry.Centroid().GetX(),
    ]
    loadeddata_zoom = 15

    # define the study area map
    studyarea_map = Map(
        layout=widgets.Layout(width="480px", height="600px"),
        center=loadeddata_center,
        zoom=loadeddata_zoom,
        basemap=basemaps.Esri.WorldImagery,
    )

    # define the drawing controls
    studyarea_drawctrl = DrawControl(
        polygon={"shapeOptions": {
            "fillOpacity": 0
        }},
        marker={},
        circle={},
        circlemarker={},
        polyline={},
    )

    # add drawing controls and data bound geometry to the map
    studyarea_map.add_control(studyarea_drawctrl)
    studyarea_map.add_layer(GeoJSON(data=geom_obj))

    # Index to count drawn polygons
    polygon_number = 0

    # Define widgets to interact with
    instruction = widgets.Output(layout={"border": "1px solid black"})
    with instruction:
        print("Draw a polygon within the red box to view plots of "
              "the fractional cover values of bare, green and "
              "non-green cover for the area over time.")

    info = widgets.Output(layout={"border": "1px solid black"})
    with info:
        print("Plot status:")

    fig_display = widgets.Output(layout=widgets.Layout(
        width="50%"  # proportion of horizontal space taken by plot
    ))

    with fig_display:
        plt.ioff()
        fig, ax = plt.subplots(3, 1, figsize=(9, 9))

        for axis in ax:
            axis.set_ylim([0, 1])

    colour_list = plt.rcParams["axes.prop_cycle"].by_key()["color"]

    # Function to execute each time something is drawn on the map
    def handle_draw(self, action, geo_json):
        nonlocal polygon_number

        #         info.clear_output(wait=True)  # wait=True reduces flicker effect
        #         with info:
        #             print("Plot status: entered handle draw")

        # Execute behaviour based on what the user draws
        if geo_json["geometry"]["type"] == "Polygon":

            # Convert the drawn geometry to pixel coordinates
            geom_selectedarea = transform_geojson_wgs_to_epsg(
                geo_json,
                EPSG=3577  # hard-coded to be same as case-study data
            )

            # Construct a mask to only select pixels within the drawn polygon
            mask = rasterio.features.geometry_mask(
                [geom_selectedarea for geoms in [geom_selectedarea]],
                out_shape=ds.geobox.shape,
                transform=ds.geobox.affine,
                all_touched=False,
                invert=True,
            )

            masked_ds = ds.where(mask)
            masked_ds_mean = masked_ds.mean(dim=["x", "y"], skipna=True)

            colour = colour_list[polygon_number % len(colour_list)]

            # Add a layer to the map to make the most recently drawn polygon
            # the same colour as the line on the plot
            studyarea_map.add_layer(
                GeoJSON(
                    data=geo_json,
                    style={
                        "color": colour,
                        "opacity": 1,
                        "weight": 4.5,
                        "fillOpacity": 0.0,
                    },
                ))

            # Add Fractional cover plots to app
            masked_ds_mean.BS.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[0])
            masked_ds_mean.PV.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[1])
            masked_ds_mean.NPV.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[2])

            # reset titles back to custom
            ax[0].set_ylabel("Bare cover")
            ax[1].set_ylabel("Green cover")
            ax[2].set_ylabel("Non-green cover")

            # refresh display
            fig_display.clear_output(
                wait=True)  # wait=True reduces flicker effect
            with fig_display:
                display(fig)

            # Update plot info
            info.clear_output(wait=True)  # wait=True reduces flicker effect
            with info:
                print("Plot status: polygon added to plot")

            # Iterate the polygon number before drawing another polygon
            polygon_number = polygon_number + 1

        else:
            info.clear_output(wait=True)
            with info:
                print("Plot status: this drawing tool is not currently "
                      "supported. Please use the polygon tool.")

    # call to say activate handle_draw function on draw
    studyarea_drawctrl.on_draw(handle_draw)

    with fig_display:
        # TODO: update with user friendly something
        display(widgets.HTML(""))

    # Construct UI:
    #  +-----------------------+
    #  | instruction           |
    #  +-----------+-----------+
    #  |  map      |  plot     |
    #  |           |           |
    #  +-----------+-----------+
    #  | info                  |
    #  +-----------------------+
    ui = widgets.VBox(
        [instruction,
         widgets.HBox([studyarea_map, fig_display]), info])
    display(ui)
Esempio n. 30
0
    def handle_draw(self, action, geo_json):
        nonlocal polygon_number

        #         info.clear_output(wait=True)  # wait=True reduces flicker effect
        #         with info:
        #             print("Plot status: entered handle draw")

        # Execute behaviour based on what the user draws
        if geo_json["geometry"]["type"] == "Polygon":

            # Convert the drawn geometry to pixel coordinates
            geom_selectedarea = transform_geojson_wgs_to_epsg(
                geo_json,
                EPSG=3577  # hard-coded to be same as case-study data
            )

            # Construct a mask to only select pixels within the drawn polygon
            mask = rasterio.features.geometry_mask(
                [geom_selectedarea for geoms in [geom_selectedarea]],
                out_shape=ds.geobox.shape,
                transform=ds.geobox.affine,
                all_touched=False,
                invert=True,
            )

            masked_ds = ds.where(mask)
            masked_ds_mean = masked_ds.mean(dim=["x", "y"], skipna=True)

            colour = colour_list[polygon_number % len(colour_list)]

            # Add a layer to the map to make the most recently drawn polygon
            # the same colour as the line on the plot
            studyarea_map.add_layer(
                GeoJSON(
                    data=geo_json,
                    style={
                        "color": colour,
                        "opacity": 1,
                        "weight": 4.5,
                        "fillOpacity": 0.0,
                    },
                ))

            # Add Fractional cover plots to app
            masked_ds_mean.BS.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[0])
            masked_ds_mean.PV.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[1])
            masked_ds_mean.NPV.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[2])

            # reset titles back to custom
            ax[0].set_ylabel("Bare cover")
            ax[1].set_ylabel("Green cover")
            ax[2].set_ylabel("Non-green cover")

            # refresh display
            fig_display.clear_output(
                wait=True)  # wait=True reduces flicker effect
            with fig_display:
                display(fig)

            # Update plot info
            info.clear_output(wait=True)  # wait=True reduces flicker effect
            with info:
                print("Plot status: polygon added to plot")

            # Iterate the polygon number before drawing another polygon
            polygon_number = polygon_number + 1

        else:
            info.clear_output(wait=True)
            with info:
                print("Plot status: this drawing tool is not currently "
                      "supported. Please use the polygon tool.")