Пример #1
0
def run():
    global m,center
#    center = list(reversed(poly.centroid().coordinates().getInfo()))
    center = [51.0,6.4]
    osm = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
    ews = basemap_to_tiles(basemaps.Esri.WorldStreetMap)
    ewi = basemap_to_tiles(basemaps.Esri.WorldImagery)
    
    dc = DrawControl(polyline={},circlemarker={})
    dc.rectangle = {"shapeOptions": {"fillColor": "#0000ff","color": "#0000ff","fillOpacity": 0.05}}
    dc.polygon = {"shapeOptions": {"fillColor": "#0000ff","color": "#0000ff","fillOpacity": 0.05}}
    dc.on_draw(handle_draw)
    
    lc = LayersControl(position='topright')
    fs = FullScreenControl(position='topleft')
    mc = MeasureControl(position='topright',primary_length_unit = 'kilometers')

    m = Map(center=center, zoom=11, layout={'height':'500px'},layers=(ewi,ews,osm),controls=(mc,dc,lc,fs))   
#    m = Map(center=center, zoom=11, layout={'height':'500px'},controls=(lc,dc,fs,mc,sm_control)) 

    with w_out:
        w_out.clear_output()
        print('Algorithm output')
    display(m) 
    return box
Пример #2
0
def run():
    global m, dc, center
    #    center = list(reversed(poly.centroid().coordinates().getInfo()))
    center = [51.0, 6.4]
    osm = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
    ews = basemap_to_tiles(basemaps.Esri.WorldStreetMap)
    ewi = basemap_to_tiles(basemaps.Esri.WorldImagery)
    #    mb = TileLayer(url="https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v9/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWNhbnR5IiwiYSI6ImNpcjRsMmJxazAwM3hoeW05aDA1cmNkNzMifQ.d2UbIugbQFk2lnU8uHwCsQ",
    #                   attribution = "<a href='https://www.mapbox.com/about/maps/'>Mapbox</a> © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> <strong><a href='https://www.mapbox.com/map-feedback/' target='_blank'>Improve this map</a></strong>" )
    #    sm_control = SplitMapControl(left_layer=osm,right_layer=ewi)
    lc = LayersControl(position='topright')
    fs = FullScreenControl(position='topleft')
    mc = MeasureControl(position='topright', primary_length_unit='kilometers')

    m = Map(center=center,
            zoom=11,
            layout={'height': '500px'},
            layers=(ewi, ews, osm),
            controls=(mc, dc, lc, fs))
    #    m = Map(center=center, zoom=11, layout={'height':'500px'},controls=(lc,dc,fs,mc,sm_control))

    with w_out:
        w_out.clear_output()
        print('Algorithm output')
    display(m)
    return box
Пример #3
0
def demo_basemaps(location, base_demo):

    strava = ipl.basemap_to_tiles(ipl.basemaps.Strava.Winter)
    carto_dark = ipl.basemap_to_tiles(ipl.basemaps.CartoDB.DarkMatter)
    mapnik = ipl.basemap_to_tiles(ipl.basemaps.OpenStreetMap.Mapnik)
    black_white = ipl.basemap_to_tiles(
        ipl.basemaps.OpenStreetMap.BlackAndWhite)
    osm_hot = ipl.basemap_to_tiles(ipl.basemaps.OpenStreetMap.HOT)
    esri_image = ipl.basemap_to_tiles(ipl.basemaps.Esri.WorldImagery)
    esri_topo = ipl.basemap_to_tiles(ipl.basemaps.Esri.WorldTopoMap)
    esri_world = ipl.basemap_to_tiles(ipl.basemaps.Esri.NatGeoWorldMap)
    water_color = ipl.basemap_to_tiles(ipl.basemaps.Stamen.Watercolor)

    layer_demo = [
        strava, carto_dark, mapnik, black_white, osm_hot, esri_image,
        esri_topo, esri_world, water_color
    ]

    for show_layer in layer_demo:

        base_demo.add_layer(show_layer)

        time.sleep(.95)
        base_demo.remove_layer(base_demo.layers[0])

    time.sleep(1.2)
    base_demo.add_layer(mapnik)
    base_demo.add_control(ipl.LayersControl())
Пример #4
0
def print_geojson(geojson, limit=100):
    center = None
    j = json.load(StringIO(geojson))
    layer_group = LayerGroup()

    features = j['features']
    if limit is not None:
        features = features[0:limit]

    for f in features:
        location = (f['geometry']['coordinates'][1],
                    f['geometry']['coordinates'][0])
        marker = Marker(location=location)
        marker.popup = HTML(str(f['properties']))
        layer_group.add_layer(marker)
        if not center:
            center = location

    if not center:
        center = (0, 0)

    m = Map(layers=(basemap_to_tiles(basemaps.OpenStreetMap.Mapnik), ),
            center=center,
            zoom=8)

    m.add_layer(layer_group)
    return m
Пример #5
0
    def __init__(self, n_days_old_satimg=1):
        t = datetime.datetime.now() - datetime.timedelta(days=n_days_old_satimg)
        t_str = t.strftime("%Y-%m-%d")

        self.m = Map(
            layers=[
                basemap_to_tiles(basemaps.NASAGIBS.ModisTerraTrueColorCR, t_str),
            ],
            center=(52.204793, 360.121558),
            zoom=2,
        )

        self.domain_coords = []
        self.polygon = None
        self.marker_locs = {}

        self.m.on_interaction(self._handle_map_click)

        button_reset = Button(description="reset")
        button_reset.on_click(self._clear_domain)
        button_save = Button(description="save domain")
        button_save.on_click(self._save_domain)
        self.name_textfield = Text(value="domain_name", width=10)

        self.m.add_control(WidgetControl(widget=button_save, position="bottomright"))
        self.m.add_control(WidgetControl(widget=button_reset, position="bottomright"))
        self.m.add_control(
            WidgetControl(widget=self.name_textfield, position="bottomright")
        )
Пример #6
0
 def __init__(self, bounds: tuple):
     self.layer = None
     self._leaflet_map = Map(layers=(basemap_to_tiles(
         basemaps.OpenStreetMap.BlackAndWhite), ),
                             name="Leaflet Map",
                             center=center(bounds),
                             zoom=12,
                             scroll_wheel_zoom=True)
     self._leaflet_map.add_control(FullScreenControl())
Пример #7
0
def draw_map():
    """
    Description:
      Create an empty map to be used to draw a polygon or rectangle
    -----
    Input:
      None
    Output:
      m: empty map ti interact with
      dc: draw control
    Usage:
      Draw a polygon or a rectangle
    """

    # Location
    center = [47, 8]
    zoom = 7
    m = Map(center=center, zoom=zoom)

    # Layers
    # http://leaflet-extras.github.io/leaflet-providers/preview/
    esri = basemap_to_tiles(basemaps.Esri.WorldImagery)
    m.add_layer(esri)
    terrain = basemap_to_tiles(basemaps.Stamen.Terrain)
    m.add_layer(terrain)
    mapnik = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
    m.add_layer(mapnik)

    m.add_control(LayersControl())

    # Controls
    dc = DrawControl(rectangle={'shapeOptions': {'color': '#0000FF'}},
                     polygon={'shapeOptions': {'color': '#0000FF'}},
                     marker={},
                     polyline={},
                     circle={},
                     circlemarker={}
                    )

    m.add_control(dc)

    return m, dc
Пример #8
0
def run():
    global m,dc,center
    center = list(reversed(poly.centroid().coordinates().getInfo()))
    m = Map(center=center, zoom=11, layout={'height':'400px'})
    osm = basemap_to_tiles(basemaps.OpenStreetMap.HOT)
    mb = TileLayer(url="https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v9/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWNhbnR5IiwiYSI6ImNpcjRsMmJxazAwM3hoeW05aDA1cmNkNzMifQ.d2UbIugbQFk2lnU8uHwCsQ")
    sm_control = SplitMapControl(left_layer=osm,right_layer=mb)
    m.add_control(dc)
    m.add_control(sm_control)
    display(m)
    display(box)
Пример #9
0
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
Пример #10
0
    def flight_map(self, center=None, basemap=None, zoom=8):
        """Display interactive map of the flight path. (Jupyter notebook only.)

        Parameters
        ----------
        center: tuple, optional
            (latitude, longitude) center of the map. The default is the average
            of the flight's lat/lon bounding box.
        basemap: str, or list or tuple of str, optional
            Name of the base map available in ipyleaflet. Default:
            ``('Esri.WorldImagery', 'OpenTopoMap')``.
        zoom: int, optional
            Map zoom level. Default is 8.
        """
        if not display_map:
            raise RuntimeError('Cannot display map')
        if basemap is None:
            basemap = ('Esri.WorldImagery', 'OpenTopoMap')
        elif isinstance(basemap, str):
            basemap = (basemap, )
        elif not isinstance(basemap, (list, tuple)):
            raise TypeError('basemap is not a str, list, or tuple')
        base_layers = list()
        for layer in basemap:
            name_parts = layer.split('.')
            base_layer = basemaps
            for p in name_parts:
                base_layer = base_layer[p]
            if not isinstance(base_layer, dict):
                raise TypeError('base layer not a dict')
            base_layers.append(basemap_to_tiles(base_layer))
        data = self._flight
        flight_lat = data['latitude']
        flight_lon = data['longitude']
        if center is None:
            center = (flight_lat.mean(), flight_lon.mean())
        flight_path = Polyline(
            locations=[np.column_stack((flight_lat, flight_lon)).tolist()],
            color='blue',
            fill=False,
            name='Flight path')
        flight_map = Map(center=center, zoom=int(zoom))
        for _ in base_layers:
            flight_map.add_layer(_)
        flight_map.add_layer(flight_path)
        flight_map.add_control(FullScreenControl())
        flight_map.add_control(LayersControl())
        display(flight_map)
Пример #11
0
    def show_stations_on_map(self,list_inc,list_process,list_filters,
     opt_params):
        """ Returns an interactive map of source and stations, use only in 
        Jupyter Notebooks.  

        Inputs:
            | list_inc: list of incidents
            | list_process: list of processes, one list per incident
            | list filters: list of filters defined for stations
            | opt_params: optional parameters (dictionary)

        Optional parameters:

        """
                
        records = self._extract_records(list_inc, list_process, list_filters)

        if not records:
            LOGGER.warning("There are no records to satisfy the provided"
             " filters.")
            return

        m = Map(
            basemap=basemap_to_tiles(basemaps.Esri.WorldImagery, "2020-04-08"),
            center = (Station.pr_source_loc[0],Station.pr_source_loc[1]),
            zoom = 8,
            close_popup_on_click=True
        )

        for i in records:
            if not i[0]:
                continue
            lat = i[0].station.lat
            lon = i[0].station.lon
            marker = Marker(location=(lat, lon), draggable=False,
             icon=AwesomeIcon(name="map-pin", marker_color='green',
             icon_color='darkgreen'), opacity=0.8)
            m.add_layer(marker)
            message = HTML()
            message.value = i[0].station.inc_st_name[list_inc[0]]
            marker.popup = message

        m.add_layer(Marker(icon=AwesomeIcon(name="star",
         marker_color='red', icon_color='darkred'),
         location=(Station.pr_source_loc[0],Station.pr_source_loc[1]),
         draggable=False))
        
        return m
Пример #12
0
    def __init__(self, center, zoom):
        self.map = Map(center=center,
                       zoom=zoom,
                       scroll_wheel_zoom=True,
                       interpolation='nearest')
        self.bbox = []
        self.point_coords = []
        self.figure = None
        self.figure_widget = None
        feature_collection = {'type': 'FeatureCollection', 'features': []}

        draw = DrawControl(
            circlemarker={},
            polyline={},
            polygon={},
            marker={"shapeOptions": {
                "original": {},
                "editing": {},
            }},
            rectangle={"shapeOptions": {
                "original": {},
                "editing": {},
            }})

        self.map.add_control(draw)

        def handle_draw(target, action, geo_json):
            feature_collection['features'] = []
            feature_collection['features'].append(geo_json)
            if feature_collection['features'][0]['geometry'][
                    'type'] == 'Point':
                self.point_coords = feature_collection['features'][0][
                    'geometry']['coordinates']
            else:
                coords = feature_collection['features'][0]['geometry'][
                    'coordinates'][0]
                polygon = shapely.geometry.Polygon(coords)
                self.bbox = polygon.bounds

        layers_control = LayersControl(position='topright')
        self.map.add_control(layers_control)
        self.map.add_control(FullScreenControl())
        self.map.add_layer(basemap_to_tiles(basemaps.Esri.WorldImagery))
        draw.on_draw(handle_draw)
Пример #13
0
    def test_remove_last_layer(self):

        # init
        m = sm.SepalMap()

        # there is just one (the basemap) so not supposed to move
        res = m.remove_last_layer()

        self.assertEqual(res, m)
        self.assertEqual(len(m.layers), 1)

        # add 1 layer and remove it
        layer = basemap_to_tiles(basemaps.CartoDB.Positron)
        m.add_layer(layer)
        m.remove_last_layer()

        self.assertEqual(len(m.layers), 1)

        #######################################################
        ##      TODO problem dealing with local rasters      ##
        #######################################################

        # # add 1 local raster
        # out_dir = os.path.expanduser('~')
        # dem = os.path.join(out_dir, 'dem.tif')
        #
        # if not os.path.exists(dem):
        #     dem_url = 'https://drive.google.com/file/d/1vRkAWQYsLWCi6vcTMk8vLxoXMFbdMFn8/view?usp=sharing'
        #     geemap.download_from_gdrive(dem_url, 'dem.tif', out_dir, unzip=False)
        #
        # # add a raster
        # m.add_raster(dem, colormap='terrain', layer_name='DEM')
        #
        # # remove it
        # m.remove_last_layer()
        #
        # self.assertEqual(len(m.layers), 1)
        # self.assertEqual(len(m.loaded_rasters), 0)
        #
        # # remove the file
        # os.remove(dem)

        return
Пример #14
0
Файл: map.py Проект: yyu/ipymap
    def __init__(
        self,
        data_url_prefix='https://raw.githubusercontent.com/yyu/GeoJSON-US/master'
    ):
        self.zipcodes = WebDict(
            url_maker=lambda z:
            f'{data_url_prefix}/perZIPgeojson/{z[0]}/{z[1]}/{z[2]}/{z}.json',
            response_processor=json.loads)
        self.gazetteer = WebTSV(f'{data_url_prefix}/ZIPCodesGazetteer.tsv')
        self.zipcode_set = set(self.gazetteer.keys())

        self.center = [47.621795, -122.334958]
        self.zoom = 8
        self.height = '500px'
        self.progress_bar_width = '500px'
        self.area_style = {
            'color': '#0000ff',
            'weight': .5,
            'fillColor': '#000077',
            'fillOpacity': 0.2
        }

        self.progress_bar = widgets.IntProgress(
            bar_style='info',
            layout=widgets.Layout(width=self.progress_bar_width))
        self.label = widgets.Label()
        self.progress_label = widgets.Label()
        self.info_box = widgets.HBox([self.progress_label, self.progress_bar])

        self.basemap = leaflet.basemaps.OpenMapSurfer.Roads
        self.basemap['name'] = 'basemap'
        self.heatmap_data = leaflet.basemaps.Strava.All
        self.heatmap_data['name'] = 'heatmap'
        self.heatmap = leaflet.basemap_to_tiles(self.heatmap_data)
        self.layers_control = leaflet.LayersControl()
        self.map_layout = widgets.Layout(height=self.height)

        self.map = None
Пример #15
0
def sel_params_form(processing_parameters: ProcessingParameters,
                    identifier='identifier',
                    name='name',
                    mock=False):
    debug_view = get_debug_view()

    fetch_inputs_func = fetch_inputs
    if mock:

        @debug_view.capture(clear_output=True)
        def fetch_inputs_mock(input_request: InputRequest,
                              message_func) -> ProcessingRequest:
            debug_view.value = ''
            time.sleep(2)
            input_identifiers = {
                input_type: [f'iid-{i}' for i in range(10)]
                for input_type in input_request.input_types
            }
            processing_request_data = input_request.as_dict()
            processing_request_data.update(
                dict(inputIdentifiers=input_identifiers))
            return ProcessingRequest(processing_request_data)

        fetch_inputs_func = fetch_inputs_mock

    form_item_layout = widgets.Layout(
        display='flex',
        flex_flow='row',
        justify_content='space-between',
    )
    var_checks_layout = widgets.Layout(
        display='flex',
        flex_flow='row',
        justify_content='center',
    )

    variable_names = []
    for variable_id in processing_parameters.variables.ids:
        variable_names.append(
            processing_parameters.variables.get(variable_id).name)
    forward_model_names = []
    for model_id in processing_parameters.forward_models.ids:
        forward_model_names.append(
            processing_parameters.forward_models.get(model_id).name)
    variable_boxes_dict = _get_checkboxes_dict(
        processing_parameters.variables.ids, variable_names)
    forward_model_boxes_dict = _get_checkboxes_dict(
        processing_parameters.forward_models.ids, forward_model_names)
    request_validation = widgets.HTML(
        value=html_element('h3',
                           att=dict(style='color:red'),
                           value='No variable or forward model selected'))
    non_disabled_forward_models = []
    available_forward_models_per_type = {}
    forward_models_per_variable = {}
    forward_model_select_buttons = {}
    for fm_id in processing_parameters.forward_models.ids:
        non_disabled_forward_models.append(fm_id)
        fm = processing_parameters.forward_models.get(fm_id)
        if not fm.input_type in available_forward_models_per_type:
            available_forward_models_per_type[fm.input_type] = []
        available_forward_models_per_type[fm.input_type].append(fm_id)
        for variable in fm.variables:
            if not variable in forward_models_per_variable:
                forward_models_per_variable[variable] = []
            forward_models_per_variable[variable].append(fm_id)
    selected_forward_models = []
    selected_variables = []
    selected_forward_model_per_type = {}
    for it in processing_parameters.input_types.ids:
        selected_forward_model_per_type[it] = None

    def _fm_variables(fm_id: str):
        return processing_parameters.forward_models.get(fm_id).variables

    def _fm_input_type(fm_id: str):
        return processing_parameters.forward_models.get(fm_id).input_type

    def _recommend(id: str):
        if id in processing_parameters.variables.ids:
            _recommend_box(variable_boxes_dict[id])
        elif id in processing_parameters.forward_models.ids:
            if id not in non_disabled_forward_models:
                non_disabled_forward_models.append(id)
            _recommend_box(forward_model_boxes_dict[id])

    def _recommend_box(box: LabeledCheckbox):
        box.enabled = True
        box.color = "green"
        box.font_weight = "bold"

    def _disable(id: str):
        if id in processing_parameters.variables.ids:
            _disable_box(variable_boxes_dict[id])
        elif id in processing_parameters.forward_models.ids:
            if id in non_disabled_forward_models:
                non_disabled_forward_models.remove(id)
            _disable_box(forward_model_boxes_dict[id])

    def _disable_box(box: LabeledCheckbox):
        box.enabled = False
        box.font_weight = "normal"

    def _display_normally(id: str):
        if id in processing_parameters.variables.ids:
            _display_normally_box(variable_boxes_dict[id])
        elif id in processing_parameters.forward_models.ids:
            if id not in non_disabled_forward_models:
                non_disabled_forward_models.append(id)
            _display_normally_box(forward_model_boxes_dict[id])

    def _display_normally_box(box: LabeledCheckbox):
        box.enabled = True
        box.color = "black"
        box.font_weight = "bold"

    def _request_status() -> str:
        if len(selected_variables) == 0 and len(selected_forward_models) == 0:
            return 'No variable or forward model selected'
        elif len(selected_variables) == 0:
            return 'No variable selected'
        elif len(selected_forward_models) == 0:
            return 'No forward model selected'
        else:
            for selected_variable in selected_variables:
                forward_model_available = False
                for variable_fm in forward_models_per_variable[
                        selected_variable]:
                    if variable_fm in selected_forward_models:
                        forward_model_available = True
                        break
                if not forward_model_available:
                    return f"Variable '{selected_variable}' cannot be derived with any of the selected forward models."
            for selected_forward_model in selected_forward_models:
                at_least_one_variable_selected = False
                for variable in processing_parameters.forward_models.get(
                        selected_forward_model).variables:
                    if variable in selected_variables:
                        at_least_one_variable_selected = True
                        break
                if not at_least_one_variable_selected:
                    return f"Selection is valid, " \
                           f"but no variable is selected for forward model '{selected_forward_model}'."
            return 'Selection is valid'

    def _validate_selection():
        color = 'red'
        request_status = _request_status()
        if request_status.startswith('Selection is valid'):
            if request_status == 'Selection is valid':
                color = 'green'
            else:
                color = 'orange'
            request_status = _format_request_status(request_status)
        request_validation.value = html_element(
            'h3', att=dict(style=f'color:{color}'), value=request_status)

    def _format_request_status(request_status: str) -> str:
        if not request_status.startswith('Selection is valid'):
            return request_status
        forward_model_lines = []
        for forward_model_id in selected_forward_models:
            fm_selected_variables = []
            fm_variables = processing_parameters.forward_models.get(
                forward_model_id).variables
            for fm_variable in fm_variables:
                if fm_variable in selected_variables:
                    fm_selected_variables.append(f"'{fm_variable}'")
            if len(fm_selected_variables) > 0:
                fm_selected_variables = ', '.join(fm_selected_variables)
                forward_model_lines.append(
                    f"With model '{forward_model_id}': Compute {fm_selected_variables}"
                )
            else:
                forward_model_lines.append(
                    f"Model '{forward_model_id}' "
                    f"is selected, but does not compute any variables")
        forward_model_lines = '<br>'.join(forward_model_lines)
        message = f"{request_status}:<br>{forward_model_lines}"
        return message

    def _handle_variable_selection(change: dict):
        if change['name'] is not '_property_lock':
            return
        variable_id = change['owner'].label_text
        if change['new']['selected']:
            selected_variables.append(variable_id)
        else:
            selected_variables.remove(variable_id)
        _update_forward_models_after_variable_change(variable_id, True)
        _validate_selection()

    def _update_forward_models_after_variable_change(
            variable_id: str, examine_secondary_models: bool = False):
        already_examined_types = []
        for potential_forward_model in forward_models_per_variable[
                variable_id]:
            fm_type = _fm_input_type(potential_forward_model)
            if (selected_forward_model_per_type[fm_type]
                ) is not None or fm_type in already_examined_types:
                continue
            _validate_forward_models_of_type(fm_type)
            _validate_variables_of_forward_models_of_type(fm_type)
            if examine_secondary_models:
                _validate_forward_models_of_variables_of_forward_models_of_type(
                    fm_type)
            already_examined_types.append(fm_type)

    def _validate_forward_models_of_type(fm_type: str):
        for fm_of_same_type in available_forward_models_per_type[fm_type]:
            if selected_forward_model_per_type[fm_type] == fm_of_same_type:
                _recommend(fm_of_same_type)
                continue
            if selected_forward_model_per_type[fm_type] is not None:
                _disable(fm_of_same_type)
                continue
            fm_of_same_type_variables = _fm_variables(fm_of_same_type)
            at_least_one_variable_selected = False
            for fm_of_same_type_variable in fm_of_same_type_variables:
                if fm_of_same_type_variable in selected_variables:
                    afms_for_st_variable = _available_forward_models_for_variable(
                        fm_of_same_type_variable)
                    if len(afms_for_st_variable) == 1 and _fm_input_type(
                            afms_for_st_variable[0]) == fm_type:
                        _recommend(fm_of_same_type)
                        for other_fm_of_same_type in available_forward_models_per_type[
                                fm_type]:
                            if other_fm_of_same_type != fm_of_same_type:
                                _disable(other_fm_of_same_type)
                        return
                    at_least_one_variable_selected = True
            if at_least_one_variable_selected:
                _recommend(fm_of_same_type)
            else:
                _display_normally(fm_of_same_type)

    def _validate_variables_of_forward_models_of_type(fm_type: str):
        for fm_of_same_type in available_forward_models_per_type[fm_type]:
            fm_of_same_type_variables = _fm_variables(fm_of_same_type)
            for fm_of_same_type_variable in fm_of_same_type_variables:
                _validate_variable(fm_of_same_type_variable)

    def _validate_forward_models_of_variables_of_forward_models_of_type(
            fm_type: str):
        for fm_of_same_type in available_forward_models_per_type[fm_type]:
            fm_of_same_type_variables = _fm_variables(fm_of_same_type)
            for fm_of_same_type_variable in fm_of_same_type_variables:
                afms_for_same_type_variable = _available_forward_models_for_variable(
                    fm_of_same_type_variable)
                if _fm_input_type(afms_for_same_type_variable[0]) != fm_type:
                    _validate_forward_models_of_type(
                        _fm_input_type(afms_for_same_type_variable[0]))
                    _validate_variables_of_forward_models_of_type(
                        _fm_input_type(afms_for_same_type_variable[0]))

    def _available_forward_models_for_variable(variable_id: str) -> List[str]:
        available_forward_models_for_variable = []
        for model_id in forward_models_per_variable[variable_id]:
            if model_id in non_disabled_forward_models:
                available_forward_models_for_variable.append(model_id)
        return available_forward_models_for_variable

    def _validate_variable(variable: str):
        if variable in selected_variables:
            _recommend(variable)
            return
        available_forward_models_for_variable = _available_forward_models_for_variable(
            variable)
        if len(available_forward_models_for_variable) == 0:
            _disable(variable)
            return
        for available_forward_model_for_variable in available_forward_models_for_variable:
            if available_forward_model_for_variable in selected_forward_models:
                _recommend(variable)
                return
        _display_normally(variable)

    @debug_view.capture(clear_output=True)
    def _handle_forward_model_selection(change: dict):
        if change['name'] is not '_property_lock':
            return
        if 'selected' not in change['new']:
            return
        selected_fm_id = change['owner'].label_text
        selected_fm_it = _fm_input_type(selected_fm_id)
        if change['new']['selected']:
            selected_forward_models.append(selected_fm_id)
            selected_forward_model_per_type[selected_fm_it] = selected_fm_id
            forward_model_select_buttons[selected_fm_id].disabled = False
        else:
            selected_forward_models.remove(selected_fm_id)
            selected_forward_model_per_type[selected_fm_it] = None
            forward_model_select_buttons[selected_fm_id].disabled = True
        _validate_forward_models_of_type(selected_fm_it)
        _validate_variables_of_forward_models_of_type(selected_fm_it)
        _validate_selection()
        _update_preprocessing_states()
        _setup_user_priors()

    def _clear_variable_selection(b):
        for variable_id in variable_boxes_dict:
            if variable_id in selected_variables:
                selected_variables.remove(variable_id)
                variable_boxes_dict[variable_id].selected = False
                _validate_variable(variable_id)
                _update_forward_models_after_variable_change(variable_id)
        _validate_selection()

    def _clear_forward_model_selection(b):
        affected_input_types = []
        for forward_model_id in forward_model_boxes_dict:
            if forward_model_id in selected_forward_models:
                selected_forward_models.remove(forward_model_id)
                forward_model_type = _fm_input_type(forward_model_id)
                selected_forward_model_per_type[forward_model_type] = None
                if forward_model_type not in affected_input_types:
                    affected_input_types.append(forward_model_type)
                forward_model_boxes_dict[forward_model_id].selected = False
        for input_type in affected_input_types:
            _validate_forward_models_of_type(input_type)
            _validate_variables_of_forward_models_of_type(input_type)
        _update_preprocessing_states()
        _validate_selection()
        _setup_user_priors()

    def _select_all_variables_for_forward_model(forward_model_id: str):
        fm_variables = _fm_variables(forward_model_id)
        for variable_id in fm_variables:
            if variable_id not in selected_variables:
                selected_variables.append(variable_id)
                variable_boxes_dict[variable_id].selected = True
                _update_forward_models_after_variable_change(variable_id)
        _validate_selection()

    # noinspection PyTypeChecker
    variables_box = _wrap_variable_checkboxes_in_widget(
        variable_boxes_dict.values(), 4, _handle_variable_selection)
    clear_variable_selection_button = widgets.Button(
        description="Clear Variable Selection",
        layout=widgets.Layout(left='60%', width='35%'))
    clear_variable_selection_button.on_click(_clear_variable_selection)
    forward_model_variables = {}
    for fm_id in processing_parameters.forward_models.ids:
        forward_model_variables[
            fm_id] = processing_parameters.forward_models.get(fm_id).variables
        forward_model_select_buttons[fm_id] = _get_select_button(
            _select_all_variables_for_forward_model, fm_id)

    # noinspection PyTypeChecker
    forward_models_box = _wrap_forward_model_checkboxes_in_widget(
        forward_model_boxes_dict.values(), forward_model_select_buttons,
        _handle_forward_model_selection, forward_model_variables)
    clear_model_selection_button = widgets.Button(
        description="Clear Forward Model Selection",
        layout=widgets.Layout(left='60%', width='35%'))
    clear_model_selection_button.on_click(_clear_forward_model_selection)

    user_priors_box = widgets.Box(children=[],
                                  layout=widgets.Layout(overflow='hidden',
                                                        display='flex'))
    user_priors_component = widgets.VBox(children=[
        widgets.HTML(
            value=html_element('h2', value='User Priors')), user_priors_box
    ])
    user_priors_dict = {}

    def _handle_user_prior_change(user_prior_dict):
        for user_prior in user_prior_dict:
            user_priors_dict[user_prior] = user_prior_dict[user_prior]

    @debug_view.capture(clear_output=True)
    def _setup_user_priors():
        possible_user_priors = []
        s2_output_variables = []
        if selected_forward_model_per_type['Sentinel-2'] is not None:
            selected_forward_model = \
                processing_parameters.forward_models.get(selected_forward_model_per_type['Sentinel-2'])
            for prior in selected_forward_model.requiredPriors:
                if prior not in possible_user_priors:
                    possible_user_priors.append(prior)
            s2_output_variables = selected_forward_model.variables
        if selected_forward_model_per_type['Sentinel-1'] is not None:
            selected_forward_model = \
                processing_parameters.forward_models.get(selected_forward_model_per_type['Sentinel-1'])
            for prior in selected_forward_model.requiredPriors:
                if prior not in possible_user_priors and prior not in s2_output_variables:
                    possible_user_priors.append(prior)
        user_prior_components = []
        for possible_user_prior_id in possible_user_priors:
            prior = processing_parameters.variables.get(possible_user_prior_id)
            if not prior.may_be_user_prior:
                continue
            mu = None
            unc = None
            if possible_user_prior_id in user_priors_dict:
                if 'mu' in user_priors_dict[possible_user_prior_id]:
                    mu = user_priors_dict[possible_user_prior_id]['mu']
                if 'unc' in user_priors_dict[possible_user_prior_id]:
                    unc = user_priors_dict[possible_user_prior_id]['unc']
            user_prior_components.append(
                user_prior_component(prior.id, prior.unit,
                                     _handle_user_prior_change, mu, unc))
        user_priors_box.children = [
            _wrap_user_priors_in_widget(user_prior_components)
        ]

    @debug_view.capture(clear_output=True)
    def _must_preprocess(it: str) -> bool:
        must_preprocess = it in selected_forward_model_per_type and selected_forward_model_per_type[
            it] is not None
        if not must_preprocess:
            for post_processor_name in post_processor_checkbox_dict:
                if post_processor_checkbox_dict[post_processor_name].selected:
                    post_processor = processing_parameters.post_processors.get(
                        post_processor_name)
                    if it in post_processor.input_types:
                        must_preprocess = True
                        break
        return must_preprocess

    def _update_preprocessing_states():
        preprocess_s1_temporal_filter.disabled = not _must_preprocess(
            'Sentinel-1')
        preprocess_s2_only_roi_checkbox.enabled = _must_preprocess(
            'Sentinel-2')

    preprocess_s1_temporal_filter = widgets.BoundedIntText(value=5,
                                                           min=2,
                                                           max=15,
                                                           step=1,
                                                           disabled=True)
    preprocess_s2_only_roi_checkbox = LabeledCheckbox(
        selected=False,
        label_text='Only preprocess Region of Interest',
        tooltip='Only preprocess Region of Interest',
        enabled=False,
        layout=widgets.Layout(display='flex', width='30%'))

    global _NUM_REQUESTS
    _NUM_REQUESTS += 1
    request_name = widgets.Text(name)
    python_var_name = widgets.Text(identifier)

    start_date = widgets.DatePicker(
        value=datetime.datetime(year=2018, month=5, day=10))
    end_date = widgets.DatePicker(
        value=datetime.datetime(year=2018, month=5, day=15))

    time_steps = Spinner(value=5, min=1)

    time_steps_unit = widgets.Dropdown(options=['days', 'weeks'],
                                       value='days',
                                       disabled=False)

    map_background_layer = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
    geometry_layer = GeoJSON()
    leaflet_map = Map(layers=(map_background_layer, geometry_layer),
                      center=[52., 10.],
                      zoom=4)
    draw_control = DrawControl()
    draw_control.polyline = {}
    draw_control.polygon = {}
    draw_control.circlemarker = {}
    draw_control.rectangle = {'shapeOptions': {}}
    draw_control.edit = False
    draw_control.remove = False

    @debug_view.capture(clear_output=True)
    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.')

    draw_control.on_draw(_handle_draw)
    leaflet_map.add_control(draw_control)

    roi_area = widgets.Textarea(
        layout=widgets.Layout(flex='1 10 90%', align_items='stretch'))
    roi_map_button = widgets.Button(description="Map region",
                                    layout=widgets.Layout(flex='0 1 10%'))

    def _update_roi_status_for_error(message: str):
        roi_data = leaflet_map.layers[1].data
        if not roi_data:
            roi_validation.value = html_element('h3',
                                                att=dict(style=f'color:red'),
                                                value=message)
            return
        roi_validation.value = html_element(
            'h3',
            att=dict(style=f'color:orange'),
            value=f'{message} Keep previously defined Region of Interest.')

    selected_indicators = []

    indicator_check_boxes = []
    for indicator_id in processing_parameters.indicators.ids:
        indicator = processing_parameters.indicators.get(indicator_id)
        indicator_check_box = LabeledCheckbox(selected=False,
                                              label_text=indicator_id,
                                              tooltip=indicator.description,
                                              enabled=True)
        indicator_check_boxes.append(indicator_check_box)

    @debug_view.capture(clear_output=True)
    def _handle_indicator_selection(change: dict):
        if change['name'] is not '_property_lock' or not 'selected' in change[
                'new']:
            return
        indicator_id = change['owner'].label_text
        if change['new']['selected']:
            selected_indicators.append(indicator_id)
        else:
            selected_indicators.remove(indicator_id)
        for inner_post_processor_name in post_processor_checkbox_dict:
            inner_post_processor = processing_parameters.post_processors.get(
                inner_post_processor_name)
            post_processor_selected = False
            for post_processor_indicator in inner_post_processor.indicators:
                if post_processor_indicator in selected_indicators:
                    post_processor_selected = True
                    break
            if post_processor_checkbox_dict[
                    inner_post_processor_name].selected != post_processor_selected:
                post_processor_checkbox_dict[
                    inner_post_processor_name].selected = post_processor_selected
        _update_preprocessing_states()

    indicators_box = _wrap_variable_checkboxes_in_widget(
        indicator_check_boxes, 3, _handle_indicator_selection)

    post_processor_checkbox_dict = {}
    post_processor_checkboxes = []
    for post_processor_name in processing_parameters.post_processors.names:
        post_processor = processing_parameters.post_processors.get(
            post_processor_name)
        post_processor_checkbox = LabeledCheckbox(
            selected=False,
            label_text=post_processor_name,
            tooltip=post_processor.description,
            enabled=False)
        post_processor_checkboxes.append(post_processor_checkbox)
        post_processor_checkbox_dict[
            post_processor_name] = post_processor_checkbox

    post_processors_box = _wrap_variable_checkboxes_in_widget(
        post_processor_checkboxes, 2, None)

    @debug_view.capture(clear_output=True)
    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.')

    roi_map_button.on_click(_handle_roi_map_button_clicked)
    spatial_resolution = Spinner(value=100, min=1, step=1)
    roi_validation = widgets.HTML(
        value=html_element('h3',
                           att=dict(style='color:red'),
                           value='No region of interest defined'))

    info = InfoComponent()

    def new_input_request():
        request_status = _request_status()
        if request_status != 'Selection is valid':
            info.output_error(request_status)
            return
        input_types = []
        for input_type in selected_forward_model_per_type:
            if selected_forward_model_per_type[input_type] is not None:
                input_types.append(input_type)
        roi_data = leaflet_map.layers[1].data
        if not roi_data:
            info.output_error('Error: No Region of Interest specified')
            return
        roi = shape(roi_data)
        if not roi.is_valid:
            info.output_error('Error: Region of Interest is invalid')
            return
        request_models = []
        required_priors = []
        for model_id in selected_forward_models:
            request_model = processing_parameters.forward_models.get(model_id)
            request_variables = []
            for variable_id in request_model.variables:
                if variable_id in selected_variables:
                    request_variables.append(variable_id)
            request_model_dict = dict(
                name=model_id,
                type=request_model.type,
                modelDataType=request_model.input_type,
                requiredPriors=request_model.requiredPriors,
                outputParameters=request_variables)
            for required_model_prior in request_model.requiredPriors:
                if not required_model_prior in required_priors:
                    required_priors.append(required_model_prior)
            request_models.append(request_model_dict)
        user_priors_for_request_list = []
        for user_prior in user_priors_dict:
            if user_prior in required_priors:
                user_priors_for_request_dict = {'name': user_prior}
                if 'mu' in user_priors_dict:
                    user_priors_for_request_dict['mu'] = user_priors_dict['mu']
                if 'unc' in user_priors_dict:
                    user_priors_for_request_dict['unc'] = user_priors_dict[
                        'unc']
                user_priors_for_request_list.append(
                    user_priors_for_request_dict)
        temporalFilter = None
        if not preprocess_s1_temporal_filter.disabled:
            temporalFilter = preprocess_s1_temporal_filter.value
        computeOnlyRoi = None
        if preprocess_s2_only_roi_checkbox.enabled:
            computeOnlyRoi = preprocess_s2_only_roi_checkbox.selected
        postProcessors = []
        if len(selected_indicators) > 0:
            postProcessors = []
            for post_processor_name in processing_parameters.post_processors.names:
                post_processor = processing_parameters.post_processors.get(
                    post_processor_name)
                selected_pp_indicators = []
                for indicator in post_processor.indicators:
                    if indicator in selected_indicators:
                        selected_pp_indicators.append(indicator)
                if len(selected_pp_indicators) > 0:
                    post_processor_dict = dict(
                        name=post_processor_name,
                        type=post_processor.type,
                        inputTypes=post_processor.input_types,
                        indicatorNames=selected_pp_indicators,
                        variableNames=selected_variables)
                    postProcessors.append(post_processor_dict)

        return InputRequest(
            dict(name=request_name.value,
                 timeRange=[
                     datetime.datetime.strftime(start_date.value, "%Y-%m-%d"),
                     datetime.datetime.strftime(end_date.value, "%Y-%m-%d")
                 ],
                 timeStep=time_steps.value,
                 timeStepUnit=time_steps_unit.value,
                 roi=f"{roi.wkt}",
                 spatialResolution=spatial_resolution.value,
                 inputTypes=input_types,
                 forwardModels=request_models,
                 userPriors=user_priors_for_request_list,
                 s1TemporalFilter=temporalFilter,
                 s2ComputeRoi=computeOnlyRoi,
                 postProcessors=postProcessors))

    # noinspection PyUnusedLocal
    @debug_view.capture(clear_output=True)
    def handle_new_button_clicked(*args, **kwargs):
        req_var_name = python_var_name.value or 'req'
        if req_var_name and not req_var_name.isidentifier():
            info.output_error(
                f'Error: invalid Python identifier: {req_var_name}')
            return

        inputs_request = new_input_request()
        if inputs_request is None:
            return
        info.output_message('Fetching results...')

        processing_request = fetch_inputs_func(inputs_request,
                                               info.message_func)

        if processing_request is None:
            return
        input_identifiers = processing_request.inputs
        data_rows = []
        for input_type, input_ids in input_identifiers.as_dict().items():
            data_rows.append([input_type, len(input_ids)])

        result_html = html_table(
            data_rows, header_row=['Input Type', 'Number of inputs found'])

        # insert shall variable_id whose value is processing_request
        # users can later call the GUI with that object to edit it
        if req_var_name:
            shell = IPython.get_ipython()
            shell.push({req_var_name: processing_request}, interactive=True)
            var_name_html = html_element(
                'p',
                value=f'Note: a new processing request has been '
                f'stored in variable <code>{req_var_name}</code>.')
            result_html = html_element('div',
                                       value=result_html + var_name_html)
        info.output_html(result_html)

    # noinspection PyUnusedLocal
    @debug_view.capture(clear_output=True)
    def handle_submit_button_clicked(*args, **kwargs):
        req_var_name = python_var_name.value or 'job'
        if req_var_name and not req_var_name.isidentifier():
            info.output_error(
                f'Error: invalid Python identifier: {req_var_name}')
            return

        inputs_request = new_input_request()

        info.output_message('Submitting processing request...')

        job = submit_processing_request(inputs_request,
                                        message_func=info.message_func,
                                        mock=mock)
        if job is not None:
            shell = IPython.get_ipython()
            shell.push({req_var_name: job}, interactive=True)
            result_html = html_element(
                'p',
                value=f'Note: a new job is currently being executed and is '
                f'stored in variable_id <code>{req_var_name}</code>.')
            info.output_html(result_html)

    # TODO: make GUI form look nice
    new_button = widgets.Button(description="New Request", icon="search")
    new_button.on_click(handle_new_button_clicked)
    submit_button = widgets.Button(description="Submit Request", icon="upload")
    submit_button.on_click(handle_submit_button_clicked)

    form_items = [
        widgets.Box(
            [widgets.HTML(value=html_element('h2', value='Output Variables'))],
            layout=form_item_layout),
        widgets.Box([variables_box], layout=var_checks_layout),
        widgets.Box([clear_variable_selection_button],
                    layout=form_item_layout),
        widgets.Box(
            [widgets.HTML(value=html_element('h2', value='Forward Models'))],
            layout=form_item_layout),
        widgets.Box([forward_models_box], layout=var_checks_layout),
        widgets.Box([clear_model_selection_button], layout=form_item_layout),
        widgets.Box([request_validation], layout=form_item_layout),
        widgets.Box([
            widgets.HTML(
                value=html_element('h2', value='Sentinel-1 Pre-Processing'))
        ],
                    layout=form_item_layout),
        widgets.Box([
            widgets.Label(value='Temporal Filter'),
            preprocess_s1_temporal_filter
        ],
                    layout=form_item_layout),
        widgets.Box([
            widgets.HTML(
                value=html_element('h2', value='Sentinel-2 Pre-Processing'))
        ],
                    layout=form_item_layout), preprocess_s2_only_roi_checkbox,
        widgets.Box([user_priors_component], layout=form_item_layout),
        widgets.Box([
            widgets.HTML(
                value=html_element('h2', value='Time Period of Interest'))
        ],
                    layout=form_item_layout),
        widgets.Box([widgets.Label(value='Start date'), start_date],
                    layout=form_item_layout),
        widgets.Box([widgets.Label(value='End date'), end_date],
                    layout=form_item_layout),
        widgets.Box([
            widgets.Label(value='Time steps'),
            widgets.Box([time_steps, time_steps_unit])
        ],
                    layout=form_item_layout),
        widgets.Box([
            widgets.HTML(value=html_element('h2', value='Region of Interest'))
        ],
                    layout=form_item_layout),
        widgets.Box([roi_area, roi_map_button], layout=form_item_layout),
        widgets.Box([leaflet_map], layout=form_item_layout),
        widgets.Box(
            [widgets.Label(value='Resolution (m)'), spatial_resolution],
            layout=form_item_layout),
        widgets.Box([roi_validation], layout=form_item_layout),
        widgets.Box(
            [widgets.HTML(value=html_element('h2', value='Post-Processing'))],
            layout=form_item_layout),
        widgets.Label(value='Indicators', layout=form_item_layout),
        widgets.Box([indicators_box], layout=var_checks_layout),
        widgets.Label(value='Post Processors', layout=form_item_layout),
        widgets.Box([post_processors_box], layout=var_checks_layout),
        widgets.Box([widgets.Label(value='Request/job name'), request_name],
                    layout=form_item_layout),
        widgets.Box(
            [widgets.Label(value='Python identifier'), python_var_name],
            layout=form_item_layout),
        widgets.Box([
            widgets.Label(value=''),
            widgets.Box([new_button, submit_button])
        ],
                    layout=form_item_layout),
        widgets.Box([info.as_widget()], layout=form_item_layout)
    ]
    form = widgets.Box(form_items,
                       layout=widgets.Layout(display='flex',
                                             flex_flow='column',
                                             border='solid 1px lightgray',
                                             align_items='stretch',
                                             width='100%'))

    return form
Пример #16
0
# measure line color
measure.completed_color='red'

# display map
measure_control_map

# In[22]

import ipyleaflet
from ipyleaflet import basemaps, basemap_to_tiles, SplitMapControl

# create map
split_map = ipyleaflet.Map(zoom=1)

# create right and left layers
right_layer = basemap_to_tiles(basemaps.Esri.WorldStreetMap)
left_layer = basemap_to_tiles(basemaps.NASAGIBS.ViirsEarthAtNight2012)

# create control
control = SplitMapControl(left_layer=left_layer, right_layer=right_layer)

# add control to map
split_map.add_control(control)

# display map
split_map
# In[23]

from ipyleaflet import Map, Marker
import geocoder
import ipywidgets
Пример #17
0
    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
Пример #18
0
 def display(self,
             basemap=False,
             mapLayout=False,
             style=False,
             groupBy=False,
             colorDict=False,
             pageTitle='GeoJSON map',
             outputPath='html/static'):
     """
     Display the dataframe on a map. Markers can be plotted at once, grouped (style='grouped'), or as pie charts (style='pie') grouped by a chosen category (groupBy='COLUMN').
     """
     if basemap:
         self.basemap = basemap
     else:
         self.basemap = {
             'url':
             'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png',
             'max_zoom': 16,
             'attribution':
             '<a href="https://carto.com">Carto Light NoLabels</a>',
             'name': 'Carto Light'
         }
     latList = [
         x for x in self.df[self.lat].values
         if type(x) not in [str, list, dict]
     ]
     latMean = sum(latList) / len(latList)
     lonList = [
         x for x in self.df[self.lon].values
         if type(x) not in [str, list, dict]
     ]
     lonMean = sum(lonList) / len(lonList)
     self.center = [latMean, lonMean]
     self.zoom = 5
     self.displayMap = ipyleaflet.Map(center=self.center,
                                      zoom=self.zoom,
                                      layers=(ipyleaflet.basemap_to_tiles(
                                          self.basemap), ))
     if mapLayout:
         self.displayMap.layout = mapLayout
     if not style:
         markers = self._generateMarkers()
         for marker in markers:
             self.displayMap.add_layer(marker)
         return self.displayMap
     elif style == 'grouped':
         markers = self._generateMarkers()
         self.markerCluster = ipyleaflet.MarkerCluster(markers=markers)
         self.displayMap.add_control(ipyleaflet.LayersControl())
         self.displayMap.add_layer(self.markerCluster)
         return self.displayMap
     elif style == 'pie':
         if not groupBy:
             raise KeyError(
                 'Please add groupBy=COLNAME. You need to specify the column containing the categories for the pie chart.'
             )
         html = self._writeHTML(groupCategory=groupBy,
                                pageTitle=pageTitle,
                                outputPath=outputPath)
         css = self._writeCSS(groupCategory=groupBy,
                              colorDict=colorDict,
                              outputPath=outputPath)
         print(
             'Your map has been generated at\n\t"/html/static/index.html".\nDue to CORS issues, most browsers will not load the GeoJSON in an Iframe correctly.\nPlease open the map in a seperate browser window.'
         )
         return displayHTML(
             "<iframe allowfullscreen=”true” mozallowfullscreen=”true” webkitallowfullscreen=”true” height=550px; width=100% src='./html/static/index.html'> <iframe>"
         )
Пример #19
0
    def __init__(self, basemaps=[], add_google_map=None, **kwargs):
        """  Initialize Sepal Map.

        Args:

            basemap (str): Select one of the Sepal Base Maps available.


        """
        basemap = dict(
            url='http://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
            max_zoom=20,
            attribution=
            '&copy; <a href="http://www.openstreetmap.org/copyright">\
            OpenStreetMap</a> &copy; <a href="http://cartodb.com/attributions">\
            CartoDB</a>',
            name='CartoDB.DarkMatter')

        basemap = basemap_to_tiles(basemap)

        if not add_google_map:
            add_google_map = False

        super().__init__(**kwargs,
                         add_google_map=add_google_map,
                         basemap=basemap)

        if basemaps:
            for basemap in basemaps:
                self.add_basemap(basemap)

        self.center = [0, 0]
        self.zoom = 2

        super().clear_controls()

        self.add_control(ZoomControl(position='topright'))
        self.add_control(LayersControl(position='topright'))
        self.add_control(AttributionControl(position='bottomleft'))
        self.add_control(ScaleControl(position='bottomleft', imperial=False))

        # Create output space for raster interaction
        output_r = widgets.Output(layout={'border': '1px solid black'})
        output_control_r = WidgetControl(widget=output_r,
                                         position='bottomright')
        self.add_control(output_control_r)

        self.loaded_rasters = {}

        # Define a behavior when ispector checked and map clicked
        def raster_interaction(**kwargs):

            if kwargs.get('type') == 'click' and self.inspector_checked:
                latlon = kwargs.get('coordinates')
                self.default_style = {'cursor': 'wait'}

                local_rasters = [
                    lr.name for lr in self.layers
                    if isinstance(lr, LocalTileLayer)
                ]

                if local_rasters:

                    with output_r:
                        output_r.clear_output(wait=True)

                        for lr_name in local_rasters:

                            lr = self.loaded_rasters[lr_name]
                            lat, lon = latlon

                            # Verify if the selected latlon is the image bounds
                            if any([
                                    lat < lr.bottom, lat > lr.top,
                                    lon < lr.left, lon > lr.right
                            ]):
                                print('Location out of raster bounds')
                            else:
                                #row in pixel coordinates
                                y = int(((lr.top - lat) / abs(lr.y_res)))

                                #column in pixel coordinates
                                x = int(((lon - lr.left) / abs(lr.x_res)))

                                #get height and width
                                h, w = lr.data.shape
                                value = lr.data[y][x]
                                print(f'{lr_name}')
                                print(
                                    f'Lat: {round(lat,4)}, Lon: {round(lon,4)}'
                                )
                                print(f'x:{x}, y:{y}')
                                print(f'Pixel value: {value}')
                else:
                    with output_r:
                        output_r.clear_output()

                self.default_style = {'cursor': 'crosshair'}

        self.on_interaction(raster_interaction)
Пример #20
0
from ipyleaflet import Map, basemaps, basemap_to_tiles


def foo(p):
    print(p)


m = Map(
    layers=(basemap_to_tiles(basemaps.NASAGIBS.ModisTerraTrueColorCR,
                             "2017-04-08"), ),
    center=(52.204793, 360.121558),
    zoom=4,
)

m.on_interaction(foo)
Пример #21
0
    def show(self, **kwargs):
        """
        Generate and return the map object for displaying the map
        Parameters
        -----------
        None

        Returns
        ----------
            map:ipyleaflet.Map
        """
        self.map = ipyleaflet.Map(
            layers=(ipyleaflet.basemap_to_tiles(
                ipyleaflet.basemaps.CartoDB.Positron),),
            **kwargs
        )
        choro_layer = ipyleaflet.Choropleth(
            name=self.dataset,
            geo_data=self.geo_data,
            choro_data=self.choro_data[self.selectedAttr][self.selectedYear],
            colormap=linear.YlOrRd_04,
            style={
                'opacity': 1,
                'weight': 1.9,
                'dashArray': '9',
                'fillOpacity': 0.5}
        )

        def handle_click(**kwargs):
            if kwargs['event'] == 'click':
                clickedFips = kwargs['properties']['GEOID']
                clickedName = self.fipsLookUp[clickedFips]
                dataBox.value = f"{clickedName} : {self.choro_data[self.selectedAttr][self.selectedYear][clickedFips]:,}"
                self.clickedID = clickedFips
        choro_layer.on_click(handle_click)
        # Year select

        def handle_year_change(change):
            new_year = str(change.new)
            choro_layer.choro_data = self.choro_data[self.selectedAttr][new_year]
            if self.clickedID:
                clickedName = self.fipsLookUp[self.clickedID]
                dataBox.value = f"{clickedName} : {self.choro_data[self.selectedAttr][new_year][self.clickedID]:,}"
            self.selectedYear = new_year
        yearList = self.availableYearDict[self.selectedAttr]
        yearListNum = list(map(int, yearList))
        minYear = min(yearListNum)
        maxYear = max(yearListNum)
        yearSlider, yearWidget = self.yearSlider(minYear, maxYear, maxYear)
        yearSlider.observe(handle_year_change, 'value')
        dataBox, dataWidget = self.dataBox()

        def handle_attr_change(change):
            new_attr = change.new
            choro_layer.choro_data = self.choro_data[new_attr][self.selectedYear]
            if self.clickedID:
                clickedName = self.fipsLookUp[self.clickedID]
                dataBox.value = f"{clickedName} : {self.choro_data[new_attr][self.selectedYear][self.clickedID]:,}"
            self.selectedAttr = new_attr
        attrDropdown, attrDropdownWidget = self.attrDropdown()
        attrDropdown.observe(handle_attr_change, "value")
        # Add to map
        self.map.add_layer(choro_layer)
        self.map.add_control(ipyleaflet.LayersControl())
        self.map.add_control(ipyleaflet.FullScreenControl())
        self.map.add_control(attrDropdownWidget)
        self.map.add_control(yearWidget)
        self.map.add_control(dataWidget)
        return self.map
Пример #22
0
def on_map_selected(change):
    m.layers = [
        basemap_to_tiles(maps[basemap_selector.value]),
        weather_maps[heatmap_selector.value]
    ]
Пример #23
0
    def __init__(self, **kwargs):

        if "center" not in kwargs:
            kwargs["center"] = [40, -100]

        if "zoom" not in kwargs:
            kwargs["zoom"] = 4

        if "scroll_wheel_zoom" not in kwargs:
            kwargs["scroll_wheel_zoom"] = True

        super().__init__(**kwargs)

        if "height" not in kwargs:
            self.layout.height = "600px"
        else:
            self.layout.height = kwargs["height"]

        self.add_control(FullScreenControl())
        self.add_control(LayersControl(position="topright"))
        self.add_control(DrawControl(position="topleft"))
        self.add_control(MeasureControl())
        self.add_control(ScaleControl(position="bottomleft"))
        self.toolbar = None

        # tools = {
        #     "folder-open": {
        #         "name": "open_data",
        #         "tooltip": "Open local vector/raster data"
        #     },
        #     "map": {
        #         "name": "basemap",
        #         "tooltip": "Change basemap"
        #     },
        #     "gears": {
        #         "name": "whitebox",
        #         "tooltip": "WhiteboxTools for local geoprocessing"
        #     },
        #     "filter": {
        #         "name": "query",
        #         "tooltip": "Attribute selection"
        #     },
        # }
        # icons = list(tools.keys())
        # tooltips = [item["tooltip"] for item in list(tools.values())]

        # icon_width = "32px"
        # icon_height = "32px"
        # n_cols = 3
        # n_rows = math.ceil(len(icons) / n_cols)

        # toolbar_grid = ipywidgets.GridBox(
        #     children=[
        #         ipywidgets.ToggleButton(
        #             layout=ipywidgets.Layout(
        #                 width="auto", height="auto", padding="0px 0px 0px 4px"
        #             ),
        #             button_style="primary",
        #             icon=icons[i],
        #             tooltip=tooltips[i],
        #         )
        #         for i in range(len(icons))
        #     ],
        #     layout=ipywidgets.Layout(
        #         width="107px",
        #         grid_template_columns=(icon_width + " ") * n_cols,
        #         grid_template_rows=(icon_height + " ") * n_rows,
        #         grid_gap="1px 1px",
        #         padding="5px",
        #     ),
        # )
        # self.toolbar = toolbar_grid

        if "google_map" not in kwargs:
            layer = TileLayer(
                url="https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}",
                attribution="Google",
                name="Google Maps",
            )
            self.add_layer(layer)
        else:
            if kwargs["google_map"] == "ROADMAP":
                layer = TileLayer(
                    url="https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}",
                    attribution="Google",
                    name="Google Maps",
                )
                self.add_layer(layer)
            elif kwargs["google_map"] == "HYBRID":
                layer = TileLayer(
                    url="https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}",
                    attribution="Google",
                    name="Google Satellite")
                self.add_layer(layer)

        if "basemap" not in kwargs:
            layer = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
            self.add_layer(layer)
        else:
            layer = basemap_to_tiles(kwargs["basemap"])
            self.add_layer(layer)

        main_toolbar(self)
Пример #24
0
def add_basemap(m, basemap):

    bm = ipyleaflet.basemap_to_tiles(basemap)
    m.add_layer(bm)

    return
Пример #25
0
def run_filmstrip_app(output_name,
                      time_range,
                      time_step,
                      tide_range=(0.0, 1.0),
                      resolution=(-30, 30),
                      max_cloud=0.5,
                      ls7_slc_off=False,
                      size_limit=10000):
    '''
    An interactive app that allows the user to select a region from a
    map, then load Digital Earth Africa Landsat data and combine it
    using the geometric median ("geomedian") statistic to reveal the 
    median or 'typical' appearance of the landscape for a series of 
    time periods.
    
    The results for each time period are combined into a 'filmstrip' 
    plot which visualises how the landscape has changed in appearance 
    across time, with a 'change heatmap' panel highlighting potential 
    areas of greatest change.
    
    For coastal applications, the analysis can be customised to select 
    only satellite images obtained during a specific tidal range 
    (e.g. low, average or high tide).
    
    Last modified: April 2020

    Parameters
    ----------  
    output_name : str
        A name that will be used to name the output filmstrip plot file.
    time_range : tuple
        A tuple giving the date range to analyse 
        (e.g. `time_range = ('1988-01-01', '2017-12-31')`).
    time_step : dict
        This parameter sets the length of the time periods to compare 
        (e.g. `time_step = {'years': 5}` will generate one filmstrip 
        plot for every five years of data; `time_step = {'months': 18}` 
        will generate one plot for each 18 month period etc. Time 
        periods are counted from the first value given in `time_range`.
    tide_range : tuple, optional
        An optional parameter that can be used to generate filmstrip 
        plots based on specific ocean tide conditions. This can be 
        valuable for analysing change consistently along the coast. 
        For example, `tide_range = (0.0, 0.2)` will select only 
        satellite images acquired at the lowest 20% of tides; 
        `tide_range = (0.8, 1.0)` will select images from the highest 
        20% of tides. The default is `tide_range = (0.0, 1.0)` which 
        will select all images regardless of tide.
    resolution : tuple, optional
        The spatial resolution to load data. The default is 
        `resolution = (-30, 30)`, which will load data at 30 m pixel 
        resolution. Increasing this (e.g. to `resolution = (-100, 100)`) 
        can be useful for loading large spatial extents.
    max_cloud : float, optional
        This parameter can be used to exclude satellite images with 
        excessive cloud. The default is `0.5`, which will keep all images 
        with less than 50% cloud.
    ls7_slc_off : bool, optional
        An optional boolean indicating whether to include data from 
        after the Landsat 7 SLC failure (i.e. SLC-off). Defaults to 
        False, which removes all Landsat 7 observations > May 31 2003.
    size_limit : int, optional
        An optional integer (in hectares) specifying the size limit 
        for the data query. Queries larger than this size will receive
        a warning that he data query is too large (and may
        therefore result in memory errors).
        
        
    Returns
    -------
    ds_geomedian : xarray Dataset
        An xarray dataset containing geomedian composites for each 
        timestep in the analysis.
        
    '''

    ########################
    # Select and load data #
    ########################

    # Define centre_coords as a global variable
    global centre_coords

    # Test if centre_coords is in the global namespace;
    # use default value if it isn't
    if 'centre_coords' not in globals():
        centre_coords = (6.587292, 1.532833)

    # Plot interactive map to select area
    basemap = basemap_to_tiles(basemaps.Esri.WorldImagery)
    geopolygon = select_on_a_map(height='600px',
                                 layers=(basemap, ),
                                 center=centre_coords,
                                 zoom=14)

    # Set centre coords based on most recent selection to re-focus
    # subsequent data selections
    centre_coords = geopolygon.centroid.points[0][::-1]

    # Test size of selected area
    msq_per_hectare = 10000
    area = (geopolygon.to_crs(crs=CRS('epsg:6933')).area / msq_per_hectare)
    radius = np.round(np.sqrt(size_limit), 1)
    if area > size_limit:
        print(f'Warning: Your selected area is {area:.00f} hectares. '
              f'Please select an area of less than {size_limit} hectares.'
              f'\nTo select a smaller area, re-run the cell '
              f'above and draw a new polygon.')

    else:

        print('Starting analysis...')

        # Connect to datacube database
        dc = datacube.Datacube(app='Change_filmstrips')

        # Configure local dask cluster
        create_local_dask_cluster()

        # Obtain native CRS
        crs = mostcommon_crs(dc=dc,
                             product='ls5_usgs_sr_scene',
                             query={
                                 'time': '1990',
                                 'geopolygon': geopolygon
                             })

        # Create query based on time range, area selected, custom params
        query = {
            'time': time_range,
            'geopolygon': geopolygon,
            'output_crs': crs,
            'resolution': resolution,
            'dask_chunks': {
                'x': 3000,
                'y': 3000
            },
            'align': (resolution[1] / 2.0, resolution[1] / 2.0)
        }

        # Load data from all three Landsats
        warnings.filterwarnings("ignore")
        ds = load_ard(dc=dc,
                      measurements=['red', 'green', 'blue'],
                      products=[
                          'ls5_usgs_sr_scene', 'ls7_usgs_sr_scene',
                          'ls8_usgs_sr_scene'
                      ],
                      min_gooddata=max_cloud,
                      ls7_slc_off=ls7_slc_off,
                      **query)

        # Optionally calculate tides for each timestep in the satellite
        # dataset and drop any observations out side this range
        if tide_range != (0.0, 1.0):
            ds = tidal_tag(ds=ds, tidepost_lat=None, tidepost_lon=None)
            min_tide, max_tide = ds.tide_height.quantile(tide_range).values
            ds = ds.sel(time=(ds.tide_height >= min_tide)
                        & (ds.tide_height <= max_tide))
            ds = ds.drop('tide_height')
            print(f'    Keeping {len(ds.time)} observations with tides '
                  f'between {min_tide:.2f} and {max_tide:.2f} m')

        # Create time step ranges to generate filmstrips from
        bins_dt = pd.date_range(start=time_range[0],
                                end=time_range[1],
                                freq=pd.DateOffset(**time_step))

        # Bin all satellite observations by timestep. If some observations
        # fall outside the upper bin, label these with the highest bin
        labels = bins_dt.astype('str')
        time_steps = (pd.cut(ds.time.values, bins_dt,
                             labels=labels[:-1]).add_categories(
                                 labels[-1]).fillna(labels[-1]))
        time_steps_var = xr.DataArray(time_steps, [('time', ds.time)],
                                      name='timestep')

        # Resample data temporally into time steps, and compute geomedians
        ds_geomedian = (
            ds.groupby(time_steps_var).apply(lambda ds_subset: xr_geomedian(
                ds_subset,
                num_threads=
                1,  # disable internal threading, dask will run several concurrently
                eps=0.2 * (1 / 10_000),  # 1/5 pixel value resolution
                nocheck=True))
        )  # disable some checks inside geomedian library that use too much ram
Пример #26
0
class Plot_interface(object):
    """Class to handle map and plot interaction"""

    # Declare class attributes
    pyccd_flag = False
    pyccd_flag2 = False
    current_band = ''
    band_index1 = 4
    band_index2 = 4
    click_col = ''
    point_color = ['#43a2ca']
    click_df = pd.DataFrame()
    sample_col = ''
    sample_df = pd.DataFrame()
    PyCCDdf = pd.DataFrame()
    table = pd.DataFrame()
    band_list = ['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2']
    year_range = [1986, 2018]
    doy_range = [1, 365]
    step = 1  #in years

    # Create widget controls
    next_pt = Button(value=False, description='Next point', disabled=False)
    previous_pt = Button(value=False,
                         description='Previous point',
                         disabled=False)
    pyccd_button = Button(value=False,
                          description='Run PyCCD 1',
                          disabled=False)
    pyccd_button2 = Button(value=False,
                           description='Run PyCCD 2',
                           disabled=False)
    band_selector1 = Dropdown(
        options=['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'],
        description='Select band',
        value=None)
    band_selector2 = Dropdown(
        options=['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'],
        description='Select band',
        value=None)
    image_band_1 = Dropdown(
        options=['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'],
        description='Red:',
        value='SWIR1')
    image_band_2 = Dropdown(
        options=['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'],
        description='Green:',
        value='NIR')
    image_band_3 = Dropdown(
        options=['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'],
        description='Blue:',
        value='RED')
    stretch_min = FloatText(value=0, description='Min:', disabled=False)
    stretch_max = FloatText(value=6000, description='Min:', disabled=False)

    # Clear layers on map
    clear_layers = Button(value=False, description='Clear Map', disabled=False)

    # Color points by DOY
    color_check = widgets.Checkbox(value=False,
                                   description='Color DOY',
                                   disabled=False)

    idBox = widgets.Text(value='0', description='ID:', disabled=False)

    ylim = widgets.IntRangeSlider(value=[0, 4000],
                                  min=0,
                                  max=10000,
                                  step=500,
                                  description='YLim:',
                                  disabled=False,
                                  continuous_update=False,
                                  orientation='horizontal',
                                  readout=True,
                                  readout_format='d')

    xlim = widgets.IntRangeSlider(value=[2000, 2018],
                                  min=1986,
                                  max=2018,
                                  step=1,
                                  description='XLim:',
                                  disabled=False,
                                  continuous_update=False,
                                  orientation='horizontal',
                                  readout=True,
                                  readout_format='d')

    ylim2 = widgets.IntRangeSlider(value=[0, 4000],
                                   min=0,
                                   max=10000,
                                   step=500,
                                   description='YLim:',
                                   disabled=False,
                                   continuous_update=False,
                                   orientation='horizontal',
                                   readout=True,
                                   readout_format='d')

    xlim2 = widgets.IntRangeSlider(value=[2000, 2018],
                                   min=1986,
                                   max=2018,
                                   step=1,
                                   description='XLim:',
                                   disabled=False,
                                   continuous_update=False,
                                   orientation='horizontal',
                                   readout=True,
                                   readout_format='d')

    coords_label = Label()
    pt_message = HTML("Current ID: ")
    time_label = HTML(value='')
    selected_label = HTML("ID of selected point")
    hover_label = HTML("test value")
    text_brush = HTML(value='Selected year range:')
    kml_link = HTML(value='KML:')
    error_label = HTML(value='Load a point')

    # Create map including streets and satellite and controls
    m = ipyleaflet.Map(zoom=5,
                       layout={'height': '400px'},
                       center=(3.3890701010382958, -67.32297252983098),
                       dragging=True,
                       close_popup_on_click=False,
                       basemap=ipyleaflet.basemaps.Esri.WorldStreetMap)

    streets = ipyleaflet.basemap_to_tiles(
        ipyleaflet.basemaps.Esri.WorldImagery)
    m.add_layer(streets)

    dc = ipyleaflet.DrawControl(marker={'shapeOptions': {
        'color': '#ff0000'
    }},
                                polygon={},
                                circle={},
                                circlemarker={},
                                polyline={})

    # Table widget
    table_widget = qgrid.show_grid(table, show_toolbar=False)

    # Set plots
    # Plot scales. HERE
    lc1_x = bqplot.DateScale(min=datetime.date(xlim.value[0], 2, 1),
                             max=datetime.date(xlim.value[1], 1, 1))

    # DOY scale
    lc1_x3 = bqplot.LinearScale(min=0, max=365)

    lc2_y = bqplot.LinearScale(min=ylim.value[0], max=ylim.value[1])

    lc1_x2 = bqplot.DateScale(min=datetime.date(xlim.value[0], 2, 1),
                              max=datetime.date(xlim.value[1], 1, 1))
    lc2_y2 = bqplot.LinearScale(min=ylim.value[0], max=ylim.value[1])

    # Main scatter plot for samples
    lc2 = bqplot.Scatter(x=[],
                         y=[],
                         scales={
                             'x': lc1_x,
                             'y': lc2_y
                         },
                         size=[1, 1],
                         interactions={
                             'click': 'select',
                             'hover': 'tooltip'
                         },
                         selected_style={
                             'opacity': 1.0,
                             'fill': 'DarkOrange',
                             'stroke': 'Red'
                         },
                         unselected_style={'opacity': 0.5},
                         display_legend=True,
                         labels=['Sample point'])

    # Pyccd model fit
    lc4 = bqplot.Lines(
        x=[],
        y=[],
        colors=['black'],
        stroke_width=3,
        scales={
            'x': lc1_x,
            'y': lc2_y
        },
        size=[1, 1],
    )

    # Pyccd model break
    lc5 = bqplot.Scatter(x=[],
                         y=[],
                         marker='triangle-up',
                         colors=['red'],
                         scales={
                             'x': lc1_x,
                             'y': lc2_y
                         },
                         size=[1, 1],
                         display_legend=False,
                         labels=['Model Endpoint'])

    # Scatter plot for clicked points in map
    lc3 = bqplot.Scatter(x=[],
                         y=[],
                         scales={
                             'x': lc1_x2,
                             'y': lc2_y2
                         },
                         size=[1, 1],
                         colors=['gray'],
                         interactions={
                             'click': 'select',
                             'hover': 'tooltip'
                         },
                         selected_style={
                             'opacity': 1.0,
                             'fill': 'DarkOrange',
                             'stroke': 'Red'
                         },
                         unselected_style={'opacity': 0.5},
                         display_legend=True,
                         labels=['Clicked point'])

    # Pyccd model fit for clicked point
    lc6 = bqplot.Lines(
        x=[],
        y=[],
        colors=['black'],
        stroke_width=3,
        scales={
            'x': lc1_x2,
            'y': lc2_y2
        },
        size=[1, 1],
    )

    # Pyccd model break for clicked point
    lc7 = bqplot.Scatter(x=[],
                         y=[],
                         marker='triangle-up',
                         colors=['red'],
                         scales={
                             'x': lc1_x2,
                             'y': lc2_y2
                         },
                         size=[1, 1],
                         display_legend=False,
                         labels=['Model Endpoint'])

    # Scatter for sample DOY
    lc8 = bqplot.Scatter(x=[],
                         y=[],
                         scales={
                             'x': lc1_x3,
                             'y': lc2_y
                         },
                         size=[1, 1],
                         interactions={
                             'click': 'select',
                             'hover': 'tooltip'
                         },
                         selected_style={
                             'opacity': 1.0,
                             'fill': 'DarkOrange',
                             'stroke': 'Red'
                         },
                         unselected_style={'opacity': 0.5},
                         display_legend=True,
                         labels=['Sample point'])

    # Plot axes.
    x_ax1 = bqplot.Axis(label='Date',
                        scale=lc1_x,
                        num_ticks=6,
                        tick_format='%Y')
    x_ax2 = bqplot.Axis(label='Date',
                        scale=lc1_x2,
                        num_ticks=6,
                        tick_format='%Y')
    x_ax3 = bqplot.Axis(label='DOY', scale=lc1_x3, num_ticks=6)

    x_ay1 = bqplot.Axis(label='SWIR1', scale=lc2_y, orientation='vertical')
    x_ay2 = bqplot.Axis(label='SWIR1', scale=lc2_y2, orientation='vertical')

    # Create a figure for sample points.
    fig = bqplot.Figure(marks=[lc2, lc4, lc5],
                        axes=[x_ax1, x_ay1],
                        layout={
                            'height': '300px',
                            'width': '100%'
                        },
                        title="Sample TS")

    # Create a figure for clicked points.
    fig2 = bqplot.Figure(marks=[lc3, lc6, lc7],
                         axes=[x_ax2, x_ay2],
                         layout={
                             'height': '300px',
                             'width': '100%'
                         },
                         title="Clicked TS")

    # Create a figure for sample DOY.
    fig3 = bqplot.Figure(marks=[lc8],
                         axes=[x_ax3, x_ay1],
                         layout={
                             'height': '300px',
                             'width': '100%'
                         },
                         title="Clicked TS")

    def __init__(self, navigate):
        Plot_interface.navigate = navigate
        Plot_interface.band_index1 = 4
        Plot_interface.band_index2 = 4
        Plot_interface.pyccd_flag = False
        Plot_interface.pyccd_flag2 = False
        Plot_interface.table = None
        # Set up database
        conn = sqlite3.connect(Plot_interface.navigate.dbPath)
        Plot_interface.current_id = Plot_interface.navigate.current_id
        Plot_interface.c = conn.cursor()
        Plot_interface.minv = 0
        Plot_interface.maxv = 6000
        Plot_interface.b1 = 'SWIR1'
        Plot_interface.b2 = 'NIR'
        Plot_interface.b3 = 'RED'

    @classmethod
    def map_point(self):
        gjson = ipyleaflet.GeoJSON(
            data=Plot_interface.navigate.fc_df['geometry'][
                Plot_interface.current_id],
            name="Sample point")
        Plot_interface.m.center = gjson.data['coordinates'][::-1]
        Plot_interface.m.zoom = 12
        Plot_interface.m.add_layer(gjson)
        kmlstr = ee.FeatureCollection(
            ee.Geometry.Point(Plot_interface.navigate.fc_df['geometry'][
                Plot_interface.current_id]['coordinates'])).getDownloadURL(
                    "kml")
        Plot_interface.kml_link.value = "<a '_blank' rel='noopener noreferrer' href={}>KML Link</a>".format(
            kmlstr)

    @classmethod
    def get_ts(self):
        #try:
        Plot_interface.error_label.value = 'Loading'
        Plot_interface.current_band = Plot_interface.band_list[
            Plot_interface.band_index1]
        Plot_interface.sample_col = get_full_collection(
            Plot_interface.navigate.fc_df['geometry'][
                Plot_interface.current_id]['coordinates'],
            Plot_interface.year_range, Plot_interface.doy_range)
        Plot_interface.sample_df = get_df_full(
            Plot_interface.sample_col,
            Plot_interface.navigate.fc_df['geometry'][
                Plot_interface.current_id]['coordinates']).dropna()
        Plot_interface.error_label.value = 'Point loaded!'
        #except:
        #    Plot_interface.error_label.value = 'Point could not be loaded!'

    def clear_map(b):
        Plot_interface.m.clear_layers()
        Plot_interface.m.add_layer(Plot_interface.streets)
        Plot_interface.map_point()

    @classmethod
    def plot_ts(self):
        current_band = Plot_interface.band_list[Plot_interface.band_index1]
        Plot_interface.lc2.x = Plot_interface.sample_df['datetime']
        if Plot_interface.color_check.value == False:
            Plot_interface.lc2.colors = list(Plot_interface.point_color)
            Plot_interface.lc8.colors = list(Plot_interface.point_color)
        else:
            Plot_interface.lc2.colors = list(
                Plot_interface.sample_df['color'].values)
            Plot_interface.lc8.colors = list(
                Plot_interface.sample_df['color'].values)
        Plot_interface.lc2.y = Plot_interface.sample_df[current_band]
        Plot_interface.x_ay1.label = current_band
        Plot_interface.lc4.x = []
        Plot_interface.lc4.y = []
        Plot_interface.lc5.x = []
        Plot_interface.lc5.y = []

        Plot_interface.lc8.x = Plot_interface.sample_df['doy']
        Plot_interface.lc8.y = Plot_interface.sample_df[current_band]

        #if pyccd_flag:
        if Plot_interface.pyccd_flag:
            Plot_interface.run_pyccd(0)

    # Go back or forth between sample points
    def advance(b):
        # Plot point in map
        Plot_interface.lc4.x = []
        Plot_interface.lc4.y = []
        Plot_interface.lc5.x = []
        Plot_interface.lc5.y = []
        Plot_interface.lc5.display_legend = False
        Plot_interface.pyccd_flag = False
        Plot_interface.current_id += 1
        Plot_interface.pt_message.value = "Point ID: {}".format(
            Plot_interface.current_id)
        Plot_interface.map_point()
        Plot_interface.get_ts()
        Plot_interface.plot_ts()
        Plot_interface.change_table(0)
        Plot_interface.navigate.valid.value = False
        Plot_interface.navigate.description = 'Not Saved'

    def decrease(b):
        # Plot point in map
        Plot_interface.lc4.x = []
        Plot_interface.lc4.y = []
        Plot_interface.lc5.x = []
        Plot_interface.lc5.y = []
        Plot_interface.lc5.display_legend = False
        Plot_interface.pyccd_flag = False
        Plot_interface.current_id -= 1
        Plot_interface.pt_message.value = "Point ID: {}".format(
            Plot_interface.current_id)
        Plot_interface.map_point()
        Plot_interface.get_ts()
        Plot_interface.plot_ts()
        Plot_interface.change_table(0)
        Plot_interface.navigate.valid.value = False
        Plot_interface.navigate.description = 'Not Saved'

    def change_table(b):
        # Update the table based on current ID

        # Get header
        cursor = Plot_interface.c.execute('select * from measures')
        names = list(map(lambda x: x[0], cursor.description))
        previous_inputs = pd.DataFrame()
        for i, row in enumerate(
                Plot_interface.c.execute(
                    "SELECT * FROM measures WHERE id = '%s'" %
                    Plot_interface.current_id)):
            previous_inputs[i] = row
        previous_inputs = previous_inputs.T
        if previous_inputs.shape[0] > 0:
            previous_inputs.columns = names
        Plot_interface.table_widget.df = previous_inputs

    # Functions for changing image stretch
    def change_image_band1(change):
        new_band = change['new']
        Plot_interface.b1 = new_band

    def change_image_band2(change):
        new_band = change['new']
        Plot_interface.b2 = new_band

    def change_image_band3(change):
        new_band = change['new']
        Plot_interface.b3 = new_band

    # Band selection for sample point
    def on_band_selection1(change):
        new_band = change['new']
        #global band_index
        band_index = change['owner'].index
        Plot_interface.band_index1 = band_index
        Plot_interface.plot_ts()

    # Band selection for clicked point
    def on_band_selection2(change):
        new_band = change['new']
        band_index = change['owner'].index
        Plot_interface.band_index2 = band_index
        Plot_interface.lc3.x = Plot_interface.click_df['datetime']
        Plot_interface.lc3.y = Plot_interface.click_df[new_band]
        Plot_interface.x_ay2.label = new_band
        if Plot_interface.pyccd_flag2:
            Plot_interface.run_pyccd2(0)

    def change_yaxis(value):
        Plot_interface.lc2_y.min = Plot_interface.ylim.value[0]
        Plot_interface.lc2_y.max = Plot_interface.ylim.value[1]

    def change_xaxis(value):
        Plot_interface.lc1_x.min = datetime.date(Plot_interface.xlim.value[0],
                                                 2, 1)
        Plot_interface.lc1_x.max = datetime.date(Plot_interface.xlim.value[1],
                                                 2, 1)
        Plot_interface.year_range = [
            Plot_interface.xlim.value[0], Plot_interface.xlim.value[1]
        ]

    def change_yaxis2(value):
        Plot_interface.lc2_y2.min = Plot_interface.ylim2.value[0]
        Plot_interface.lc2_y2.max = Plot_interface.ylim2.value[1]

    def change_xaxis2(value):
        Plot_interface.lc1_x2.min = datetime.date(
            Plot_interface.xlim2.value[0], 2, 1)
        Plot_interface.lc1_x2.max = datetime.date(
            Plot_interface.xlim2.value[1], 2, 1)

    def hover_event(self, target):
        Plot_interface.hover_label.value = str(target['data']['x'])

    # Add layer from clicked point in sample TS figure
    def click_event(self, target):
        pt_index = target['data']['index']
        current_band = Plot_interface.band_list[Plot_interface.band_index1]
        image_id = Plot_interface.sample_df['id'].values[pt_index]
        selected_image = ee.Image(
            Plot_interface.sample_col.filterMetadata('system:index', 'equals',
                                                     image_id).first())
        tile_url = GetTileLayerUrl(
            selected_image.visualize(min=Plot_interface.stretch_min.value,
                                     max=Plot_interface.stretch_max.value,
                                     bands=[
                                         Plot_interface.b1, Plot_interface.b2,
                                         Plot_interface.b3
                                     ]))

        Plot_interface.m.add_layer(
            ipyleaflet.TileLayer(url=tile_url, name=image_id))

    # Add layer from clicked point in clicked TS figure
    def click_event2(self, target):
        pt_index = target['data']['index']
        current_band = Plot_interface.band_list[Plot_interface.band_index2]
        #Find clicked image. .values needed to access the nth element of that list instead of indexing by ID
        image_id = Plot_interface.click_df['id'].values[pt_index]
        selected_image = ee.Image(
            Plot_interface.click_col.filterMetadata('system:index', 'equals',
                                                    image_id).first())
        tile_url = GetTileLayerUrl(
            selected_image.visualize(min=Plot_interface.minv,
                                     max=Plot_interface.maxv,
                                     bands=[
                                         Plot_interface.b1, Plot_interface.b2,
                                         Plot_interface.b3
                                     ]))

        Plot_interface.m.add_layer(
            ipyleaflet.TileLayer(url=tile_url, name=image_id))

    # Plot TS from clicked point
    def handle_draw(self, action, geo_json):
        # Get the selected coordinates from the map's drawing control.
        current_band = Plot_interface.band_list[Plot_interface.band_index2]
        coords = geo_json['geometry']['coordinates']
        Plot_interface.click_col = get_full_collection(
            coords, Plot_interface.year_range, Plot_interface.doy_range)
        Plot_interface.click_df = get_df_full(Plot_interface.click_col,
                                              coords).dropna()
        Plot_interface.lc6.x = []
        Plot_interface.lc6.y = []
        Plot_interface.lc7.x = []
        Plot_interface.lc7.y = []
        Plot_interface.lc3.x = Plot_interface.click_df['datetime']
        Plot_interface.lc3.y = Plot_interface.click_df[current_band]

        if Plot_interface.color_check.value == False:
            Plot_interface.lc3.colors = list(Plot_interface.point_color)
        else:
            Plot_interface.lc3.colors = list(
                Plot_interface.click_df['color'].values)

    # Plotting pyccd
    def plot_pyccd(results, band, plotband, dates, yl, ylabel, ts_type):
        mask = np.array(results['processing_mask']).astype(np.bool_)
        predicted_values = []
        prediction_dates = []
        break_dates = []
        start_dates = []

        for num, result in enumerate(results['change_models']):
            days = np.arange(result['start_day'], result['end_day'] + 1)
            prediction_dates.append(days)
            break_dates.append(result['break_day'])
            start_dates.append(result['start_day'])
            intercept = result[list(result.keys())[6 + band]]['intercept']
            coef = result[list(result.keys())[6 + band]]['coefficients']

            predicted_values.append(
                intercept + coef[0] * days +
                coef[1] * np.cos(days * 1 * 2 * np.pi / 365.25) +
                coef[2] * np.sin(days * 1 * 2 * np.pi / 365.25) +
                coef[3] * np.cos(days * 2 * 2 * np.pi / 365.25) +
                coef[4] * np.sin(days * 2 * 2 * np.pi / 365.25) +
                coef[5] * np.cos(days * 3 * 2 * np.pi / 365.25) +
                coef[6] * np.sin(days * 3 * 2 * np.pi / 365.25))

        num_breaks = len(break_dates)

        break_y = [plotband[dates == i][0] for i in break_dates]

        #break_y = [0] * num_breaks
        break_dates_plot = [
            datetime.datetime.fromordinal(i).strftime('%Y-%m-%d %H:%M:%S.%f')
            for i in break_dates
        ]

        plot_dates = np.array(
            [datetime.datetime.fromordinal(i) for i in (dates)])

        # Predicted curves
        all_dates = []
        all_preds = []
        for _preddate, _predvalue in zip(prediction_dates, predicted_values):
            all_dates.append(_preddate)
            all_preds.append(_predvalue)

        all_preds = [item for sublist in all_preds for item in sublist]
        all_dates = [item for sublist in all_dates for item in sublist]

        date_ord = [
            datetime.datetime.fromordinal(i).strftime('%Y-%m-%d %H:%M:%S.%f')
            for i in all_dates
        ]
        _x = np.array(date_ord, dtype='datetime64')
        _y = all_preds

        if ts_type == 'sample_ts':
            Plot_interface.lc4.x = _x
            Plot_interface.lc4.y = _y
            Plot_interface.lc5.x = np.array(break_dates_plot,
                                            dtype='datetime64')
            Plot_interface.lc5.y = break_y
        elif ts_type == 'clicked_ts':
            Plot_interface.lc6.x = _x
            Plot_interface.lc6.y = _y
            Plot_interface.lc7.x = np.array(break_dates_plot,
                                            dtype='datetime64')
            Plot_interface.lc7.y = break_y

    # Go to a specific sample
    def go_to_sample(b):
        # Plot point in map
        Plot_interface.lc4.x = []
        Plot_interface.lc4.y = []
        Plot_interface.lc5.x = []
        Plot_interface.lc5.y = []
        Plot_interface.lc5.display_legend = False
        Plot_interface.pyccd_flag = False
        Plot_interface.current_id = int(b.value)
        Plot_interface.pt_message.value = "Point ID: {}".format(
            Plot_interface.current_id)
        Plot_interface.navigate.valid.value = False
        Plot_interface.navigate.description = 'Not Saved'
        Plot_interface.map_point()
        Plot_interface.get_ts()
        Plot_interface.plot_ts()

    # Run pyccd
    def run_pyccd(b):
        # Run pyCCD on current point
        Plot_interface.pyccd_flag = True
        Plot_interface.lc5.display_legend = True
        dfPyCCD = Plot_interface.sample_df

        dfPyCCD['pixel_qa'][dfPyCCD['pixel_qa'] > 4] = 0

        #TODO: Paramaterize everything
        params = {
            'QA_BITPACKED': False,
            'QA_FILL': 255,
            'QA_CLEAR': 0,
            'QA_WATER': 1,
            'QA_SHADOW': 2,
            'QA_SNOW': 3,
            'QA_CLOUD': 4
        }

        dates = np.array(dfPyCCD['ord_time'])
        blues = np.array(dfPyCCD['BLUE'])
        greens = np.array(dfPyCCD['GREEN'])
        reds = np.array(dfPyCCD['RED'])
        nirs = np.array(dfPyCCD['NIR'])
        swir1s = np.array(dfPyCCD['SWIR1'])
        swir2s = np.array(dfPyCCD['SWIR2'])
        thermals = np.array(dfPyCCD['THERMAL'])
        qas = np.array(dfPyCCD['pixel_qa'])
        results = ccd.detect(dates,
                             blues,
                             greens,
                             reds,
                             nirs,
                             swir1s,
                             swir2s,
                             thermals,
                             qas,
                             params=params)

        band_names = [
            'Blue SR', 'Green SR', 'Red SR', 'NIR SR', 'SWIR1 SR', 'SWIR2 SR',
            'THERMAL'
        ]
        plotlabel = band_names[Plot_interface.band_index1]

        plot_arrays = [blues, greens, reds, nirs, swir1s, swir2s]
        plotband = plot_arrays[Plot_interface.band_index1]
        Plot_interface.plot_pyccd(results, Plot_interface.band_index1,
                                  plotband, dates, (0, 4000), 'PyCCD Results',
                                  'sample_ts')

    def run_pyccd2(b):
        # Run pyCCD on current point
        Plot_interface.pyccd_flag2 = True

        # Display the legend
        Plot_interface.lc7.display_legend = True

        dfPyCCD = Plot_interface.click_df

        # First two lines no longer required bc we are removing NA's when we load the TS
        dfPyCCD['pixel_qa'][dfPyCCD['pixel_qa'] > 4] = 0

        #TODO: Paramaterize everything
        params = {
            'QA_BITPACKED': False,
            'QA_FILL': 255,
            'QA_CLEAR': 0,
            'QA_WATER': 1,
            'QA_SHADOW': 2,
            'QA_SNOW': 3,
            'QA_CLOUD': 4
        }

        dates = np.array(dfPyCCD['ord_time'])
        blues = np.array(dfPyCCD['BLUE'])
        greens = np.array(dfPyCCD['GREEN'])
        reds = np.array(dfPyCCD['RED'])
        nirs = np.array(dfPyCCD['NIR'])
        swir1s = np.array(dfPyCCD['SWIR1'])
        swir2s = np.array(dfPyCCD['SWIR2'])
        thermals = np.array(dfPyCCD['THERMAL'])
        qas = np.array(dfPyCCD['pixel_qa'])
        results = ccd.detect(dates,
                             blues,
                             greens,
                             reds,
                             nirs,
                             swir1s,
                             swir2s,
                             thermals,
                             qas,
                             params=params)

        band_names = [
            'Blue SR', 'Green SR', 'Red SR', 'NIR SR', 'SWIR1 SR', 'SWIR2 SR',
            'THERMAL'
        ]
        plotlabel = band_names[Plot_interface.band_index2]

        plot_arrays = [blues, greens, reds, nirs, swir1s, swir2s]
        plotband = plot_arrays[Plot_interface.band_index2]
        Plot_interface.plot_pyccd(results, Plot_interface.band_index2,
                                  plotband, dates, (0, 4000), 'PyCCD Results',
                                  'clicked_ts')

    ylim.observe(change_yaxis)
    xlim.observe(change_xaxis)
    ylim2.observe(change_yaxis2)
    xlim2.observe(change_xaxis2)
    next_pt.on_click(advance)
    previous_pt.on_click(decrease)
    pyccd_button.on_click(run_pyccd)
    pyccd_button2.on_click(run_pyccd2)
    clear_layers.on_click(clear_map)
    band_selector1.observe(on_band_selection1, names='value')
    band_selector2.observe(on_band_selection2, names='value')

    image_band_1.observe(change_image_band1, names='value')
    image_band_2.observe(change_image_band2, names='value')
    image_band_3.observe(change_image_band3, names='value')

    lc2.on_element_click(click_event)
    lc2.tooltip = hover_label
    lc2.on_hover(hover_event)

    lc3.on_element_click(click_event2)
    lc3.tooltip = hover_label
    lc3.on_hover(hover_event)

    idBox.on_submit(go_to_sample)

    dc.on_draw(handle_draw)
    m.add_control(dc)
    m.add_control(ipyleaflet.LayersControl())
Пример #27
0
# the above domain; make layer now
domainf = 'data/ABoVE_Study_Domain/ABoVE_Study_Domain.json'
with open(domainf, 'r') as file:
    above_domain = json.load(file)

# get some info about ABoVE collection in CMR for ORNL
above_search = collections.keyword(
    "*Boreal Vulnerability Experiment*").get_all()
above_results = [
    r for r in above_search
    if any(["ABoVE" in r["dataset_id"], "ABoVE" in r["summary"]])
]
above_results_df = pd.DataFrame(above_results)

# load a basemap from ESRI #basemaps.NASAGIBS.ModisTerraTrueColorCR
esri = basemap_to_tiles(basemaps.Esri.WorldImagery)

# map draw poly styling
draw_style = {
    "shapeOptions": {
        "fillColor": "lightgreen",
        "color": "lightgreen",
        "fillOpacity": 0.5
    }
}

# ----------------------------------------------------------------------------
# JSON input interface and some other ui elements

geojson_label = HTML("<h4><b> or paste your GeoJSON: </b></h4>")
Пример #28
0
import ipywidgets as widgets
from ipywidgets import Button, Layout
from IPython.display import display, clear_output, Markdown as md

#need this to stop numpy from returning truncated arrays
import sys

np.set_printoptions(threshold=sys.maxsize)
# for automatic linebreaks and multi-line cells
pd.options.display.max_colwidth = 10000

output = widgets.Output()
data_output = widgets.Output()

center = (40.7210907, -73.9877836)
basemap = basemap_to_tiles(basemaps.CartoDB.Positron)
m = Map(layers=(basemap, ), center=center, zoom=14, min_zoom=7, max_zoom=20)


def extract_location():
    global gdf, lat, lon

    lat = str(markerlocation[0])
    lon = str(markerlocation[1])

    df2 = pd.DataFrame(markerlocation)
    df = df2.transpose()
    df.columns = ['Latitude', 'Longitude']

    gdf = gpd.GeoDataFrame(df,
                           geometry=gpd.points_from_xy(df.Longitude,
Пример #29
0
        name="USGS Hydrography",
        attribution="USGS",
        format="image/png",
        transparent=True,
    ),
    "USGS 3DEP Elevation": WMSLayer(
        url="https://elevation.nationalmap.gov/arcgis/services/3DEPElevation/ImageServer/WMSServer?",
        layers="3DEPElevation:None",
        name="USGS 3DEP Elevation",
        attribution="USGS",
        format="image/png",
        transparent=True,
    ),
}

# Adds ipyleaflet basemaps
for item in ipybasemaps.values():
    try:
        name = item["name"]
        basemap = "ipybasemaps.{}".format(name)
        _ee_basemaps[name] = basemap_to_tiles(eval(basemap))
    except Exception:
        for sub_item in item:
            name = item[sub_item]["name"]
            basemap = "ipybasemaps.{}".format(name)
            basemap = basemap.replace("Mids", "Modis")
            _ee_basemaps[name] = basemap_to_tiles(eval(basemap))

basemap_tiles = Box(_ee_basemaps, frozen_box=True)
basemaps = Box(
    dict(zip(list(_ee_basemaps.keys()), list(_ee_basemaps.keys()))), frozen_box=True)
Пример #30
0
def draw_map(lat_ext=None, lon_ext=None):
    """
    Description:
      Create an empty map with a blue rectangle of given <lat_ext>, <lon_ext> to be used to manually
      draw a polygon or rectangle
    -----
    Input:
      lat_ext: latitude extent
      lon_ext: longitude extent
    Output:
      m: empty map ti interact with
      dc: draw control
    Usage:
      Draw a polygon or a rectangle
    """
    # check options combination
    assert not((lat_ext is None) or (lon_ext is None)), \
           'lat_ext and lon_ext are required'
    assert lat_ext[0] < lat_ext[1], 'lat_ext values are in the wrong order'
    assert lon_ext[0] < lon_ext[1], 'lon_ext values are in the wrong order'

    # Location
    center = [np.mean(lat_ext), np.mean(lon_ext)]

    # source: https://sdc.unepgrid.ch:8080/edit/utils/data_cube_utilities/dc_display_map.py
    margin = -0.5
    zoom_bias = 0
    lat_zoom_level = _degree_to_zoom_level(margin=margin, *lat_ext) + zoom_bias
    lon_zoom_level = _degree_to_zoom_level(margin=margin, *lon_ext) + zoom_bias
    zoom = min(lat_zoom_level, lon_zoom_level)

    m = Map(center=center, zoom=zoom, scroll_wheel_zoom=True)

    # Layers
    # http://leaflet-extras.github.io/leaflet-providers/preview/
    esri = basemap_to_tiles(basemaps.Esri.WorldImagery)
    m.add_layer(esri)
    terrain = basemap_to_tiles(basemaps.Stamen.Terrain)
    m.add_layer(terrain)
    mapnik = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
    m.add_layer(mapnik)

    rectangle = Rectangle(bounds=((lat_ext[0], lon_ext[0]), (lat_ext[1],
                                                             lon_ext[1])),
                          color='red',
                          weight=2,
                          fill=False)

    m.add_layer(rectangle)

    m.add_control(LayersControl())

    # Controls
    dc = DrawControl(rectangle={'shapeOptions': {
        'color': '#0000FF'
    }},
                     polygon={'shapeOptions': {
                         'color': '#0000FF'
                     }},
                     marker={},
                     polyline={},
                     circle={},
                     circlemarker={})

    m.add_control(dc)

    return m, dc