def display_composite_ipyleaflet(self, zoom=10):
        image = self.image.clip(ee.Geometry(self.polygon))
        mapid = image.getMapId()
        tiles_url = self.ee_tiles.format(**mapid)

        tile_layer = ipyl.TileLayer(url=tiles_url,
                                    layers='collection',
                                    format='image/png',
                                    name=self.collection,
                                    opacity=1)

        polygon = ipyl.Polygon(locations=self.locations,
                               color=self.color,
                               fill_opacity=0.,
                               name='AoI')

        m = ipyl.Map(center=tuple(self.centroid), zoom=zoom)

        m.add_layer(tile_layer)
        m.add_layer(polygon)

        control = ipyl.LayersControl(position='topright')
        m.add_control(control)
        m.add_control(ipyl.FullScreenControl())
        return m
    def create_map_widgets(self, title_list, map, inventory_df):
        """Create and add map widgets into map.

        Args:
            title_list (list): A list of the file names in the folder.

        """
        map_dropdown = ipywgt.Dropdown(description='Outputfile - 1',
                                       options=title_list,
                                       width=500)
        file_control1 = ipylft.WidgetControl(widget=map_dropdown,
                                             position='bottomleft')

        # use the following line when it needs to have another dropdown
        # dropdown2 = ipywgt.Dropdown(description = 'Outputfile - 2', options = title_list2, width=500)
        # file_control2 = ipylft.WidgetControl(widget=dropdown2, position='bottomleft')

        button = ipywgt.Button(description='Generate Map', button_style='info')
        button.on_click(self.on_button_clicked)
        map_control = ipylft.WidgetControl(widget=button,
                                           position='bottomleft')

        map.add_control(ipylft.LayersControl(position='topright',
                                             style='info'))
        map.add_control(ipylft.FullScreenControl(position='topright'))
        map.add_control(map_control)
        # map.add_control(file_control2)      # use the line when it needs to have extra dropdown
        map.add_control(file_control1)

        # set global for button click
        self.map_dropdown = map_dropdown
        self.inventory_df = inventory_df
        self.inventory_json = json.loads(inventory_df.to_json())

        return map
Example #3
0
def plotHeatmap(locations: [tuple],
                heatmapName: str,
                worldMap: lf.Map = None,
                center: tuple = (0, 0),
                **kwargs) -> lf.Map:
    ''' Plot the given lat lon locations as a heatmap layer on a world map object
      @center: the center coordinate when creating the world map object
      @locations: list of latitude & longitude pair
      @worldMap: ipyleaflet Map object. If this is specified, the new heatmap will be addded
                 to this object. Else a new Map object will be created
      @heatmapName: name of the heatmap layer
      Returns: a newly created Map object or the passed in worldMap object.
  '''
    # Create map if it's not passed in to the function
    if (worldMap is None):
        baseMap = lf.basemaps.CartoDB.DarkMatter  # lf.basemaps.Esri.WorldTopoMap
        worldMap = lf.Map(basemap=baseMap, center=center, zoom=10)
        worldMap.add_control(lf.FullScreenControl())
        worldMap.add_control(lf.LayersControl(position='topright'))

    # Remove existing heatmap layer that has the same name
    removeLayerByType(worldMap, heatmapName, lf.Heatmap)

    # Add the heatmap layer to the world map object
    heatmap = lf.Heatmap(locations=locations,
                         radius=20,
                         name=heatmapName,
                         **kwargs)
    worldMap.add_layer(heatmap)

    return worldMap
Example #4
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())
Example #5
0
    def get_gdf_map(datasets: list):
        """Get ipyleaflet map with list of datasets with geopandas .

        Args:
            datasets (list): a list of pyincore Dataset objects

        Returns:
            ipyleaflet.Map: ipyleaflet Map object

        """

        # TODO: how to add a style for each dataset
        # TODO: performance issue. If there are a lot of data, the browser will crash
        geo_data_list = []
        # (min_lat, min_lon, max_lat, max_lon)
        bbox_all = [9999, 9999, -9999, -9999]

        for dataset in datasets:
            # maybe this part should be moved to Dataset Class
            gdf = gpd.read_file(dataset.local_file_path)
            geo_data = ipylft.GeoData(geo_dataframe=gdf,
                                      name=dataset.metadata['title'])
            geo_data_list.append(geo_data)

            bbox = gdf.total_bounds
            bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

        m = GeoUtil.get_ipyleaflet_map(bbox_all)

        for entry in geo_data_list:
            m.add_layer(entry)

        m.add_control(ipylft.LayersControl())
        return m
Example #6
0
    def show(self, tabs=True, layer_control=True, draw_control=False,
             fullscreen=True):
        """ Show the Map on the Notebook """
        if not self.is_shown:
            if layer_control:
                # Layers Control
                lc = ipyleaflet.LayersControl()
                self.add_control(lc)
            if draw_control:
                # Draw Control
                dc = ipyleaflet.DrawControl(edit=False)
                dc.on_draw(self.handle_draw)
                self.add_control(dc)
            if fullscreen:
                # Control
                full_control = ipyleaflet.FullScreenControl()
                self.add_control(full_control)

            if tabs:
                display(self, self.tab_widget)
            else:
                display(self)
        else:
            if tabs:
                display(self, self.tab_widget)
            else:
                display(self)

        self.is_shown = True
        # Start with crosshair cursor
        self.default_style = {'cursor': 'crosshair'}
Example #7
0
    def get_gdf_wms_map(datasets,
                        wms_datasets,
                        wms_url=globals.INCORE_GEOSERVER_WMS_URL):
        """Get a map with WMS layers from list of datasets for geopandas and list of datasets for WMS

        Args:
            datasets (list): list of pyincore Dataset objects
            wms_datasets (list): list of pyincore Dataset objects for wms layers
            wms_url (str): URL of WMS server

        Returns:
            obj: A ipylfealet Map object

        """

        # TODO: how to add a style for each WMS layers (pre-defined styules on WMS server) and gdf layers

        # (min_lat, min_lon, max_lat, max_lon)
        bbox_all = [9999, 9999, -9999, -9999]

        geo_data_list = []
        for dataset in datasets:
            # maybe this part should be moved to Dataset Class
            gdf = gpd.read_file(dataset.local_file_path)
            geo_data = ipylft.GeoData(geo_dataframe=gdf,
                                      name=dataset.metadata['title'])
            geo_data_list.append(geo_data)

            bbox = gdf.total_bounds
            bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

        wms_layers = []
        for dataset in wms_datasets:
            wms_layer_name = 'incore:' + dataset.id
            wms_layer = ipylft.WMSLayer(url=wms_url,
                                        layers=wms_layer_name,
                                        format='image/png',
                                        transparent=True,
                                        name=dataset.metadata['title'] +
                                        '-WMS')
            wms_layers.append(wms_layer)

            bbox = dataset.metadata['boundingBox']
            bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

        m = GeoUtil.get_ipyleaflet_map(bbox_all)

        for layer in wms_layers:
            m.add_layer(layer)

        for g in geo_data_list:
            m.add_layer(g)

        m.add_control(ipylft.LayersControl())

        return m
Example #8
0
    def __init__(self, distance_choice="agat"):
        self.m = ipyl.Map(center=(45, 0), zoom=7, layout={"height": "500px"})
        # Date
        date_picker = widg.DatePicker(value=dt.datetime(2020, 1, 26))
        self._date = date_picker.value
        date_picker.observe(self.change_date, "value")
        self.step = 0
        self.distance_choice = distance_choice
        variable_picker = widg.Dropdown(
            value="WWMF", options=["WWMF", "WME", "W1", "PRECIP", "T"])
        variable_picker.observe(self.variable_change, "value")
        dept_picker = widg.Dropdown(value="41",
                                    options={
                                        "Finistère": "29",
                                        "Isère": "38",
                                        "Hérault": "34",
                                        "Loire-et-cher": "41"
                                    })
        dept_picker.observe(self.change_dept, "value")
        self.dept = dept_picker.value
        self._variable = variable_picker.value
        # Open dataset and mask
        self.open_file()

        # Add other widgets
        self.legend = widg.Image(layout=widg.Layout(height="430px"))
        self.html1 = HTML('''
                    <h4>Type de temps</h4>
                        Hover over a pixel
                        ''')
        self.html1.layout.margin = '0px 20px 20px 20px'
        # Add controls
        control1 = WidgetControl(widget=self.html1, position='bottomright')
        self.m.add_control(control1)
        self.m.add_control(ipyl.LayersControl())

        slider = widg.IntSlider(min=0,
                                max=len(self.da.step) - 1,
                                step=1,
                                value=0,
                                description="step")
        slider.observe(self.change_step, 'value')
        self.m.add_control(
            ipyl.WidgetControl(widget=widg.VBox(
                [date_picker, slider, variable_picker, dept_picker]),
                               position="topright"))
        self.m.add_control(ipyl.FullScreenControl())
        self.render()
        super().__init__([self.m, self.legend])
Example #9
0
    def plot_network_dataset(network_dataset: NetworkDataset):
        """Creates map window with Network Dataset visualized

        Args:
            network_dataset (NetworkDataset):  pyincore Network Dataset object

        Returns:
            m (ipyleaflet.Map): ipyleaflet Map object

        """
        # get node file name path
        link_path = network_dataset.link.file_path
        link_file_name = os.path.basename(link_path)

        # get node file name path
        node_path = network_dataset.node.file_path
        node_file_name = os.path.basename(node_path)

        # read file using geopandas
        node_gdf = gpd.read_file(node_path)
        link_gdf = gpd.read_file(link_path)

        geo_data_list = []
        # (min_lat, min_lon, max_lat, max_lon)
        bbox_all = [9999, 9999, -9999, -9999]

        # add node data to list
        node_geo_data = ipylft.GeoData(geo_dataframe=node_gdf,
                                       name=node_file_name)
        geo_data_list.append(node_geo_data)

        # add link data to list
        link_geo_data = ipylft.GeoData(geo_dataframe=link_gdf,
                                       name=link_file_name)
        geo_data_list.append(link_geo_data)

        bbox = link_gdf.total_bounds
        bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

        m = GeoUtil.get_ipyleaflet_map(bbox_all)

        for entry in geo_data_list:
            m.add_layer(entry)

        m.add_control(ipylft.LayersControl())

        return m
Example #10
0
    def show(self, inspector=True):
        """ Show the Map on the Notebook """
        if not self.is_shown:
            # Layers Control
            lc = ipyleaflet.LayersControl()
            self.add_control(lc)
            self.is_shown = True

            if inspector:
                # Create Assets Tab
                self.create_assets_tab()
                # Display
                display(self, self.tabs)
            else:
                display(self)
        elif inspector:
            display(self, self.tabs)
        else:
            display(self)
Example #11
0
    def create_map_widgets(self, m, outfiles):
        self.dropdown1 = ipywgt.Dropdown(description='Outputfile - 1',
                                         options=outfiles,
                                         width=500)
        file_control1 = ipylft.WidgetControl(widget=self.dropdown1,
                                             position='bottomleft')

        # self.dropdown2 = ipywgt.Dropdown(description = 'Outputfile - 2', options = outfiles, width=500)
        # file_control2 = ipylft.WidgetControl(widget=self.dropdown2, position='bottomleft')

        button = ipywgt.Button(description='Generate Map', button_style='info')
        button.on_click(self.on_button_clicked)
        generatemap_control = ipylft.WidgetControl(widget=button,
                                                   position='bottomleft')

        m.add_control(ipylft.LayersControl(position='topright', style='info'))
        m.add_control(ipylft.FullScreenControl(position='topright'))
        m.add_control(generatemap_control)
        # m.add_control(file_control2)
        m.add_control(file_control1)
Example #12
0
def plot_isochrones(coordinates, isochrones, zoom_level=8):
    '''Initiate map and plot isochrones centered on coordinates.'''

    center = coord_to_tuple(coordinates)

    layer_color = 'brown'
    fill_color = 'orange'
    m = ipl.Map(center=center, zoom=zoom_level)
    for key in isochrones.keys():

        item = ipl.Polygon(locations=isochrones[key],
                           color=layer_color,
                           weight=1,
                           fill_color=fill_color,
                           fill_opacity=0.2,
                           name=key)
        m.add_layer(item)

    m.add_control(ipl.LayersControl())

    return m
Example #13
0
File: map.py Project: 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
Example #14
0
def plotLeaflet(geoJson: dict,
                idToValue: dict,
                worldMap: lf.Map = None,
                includeEmpty: bool = True,
                labelFormat: str = "Id={0} - Value={1}",
                mapArgs: dict = {},
                heatmapArgs: dict = {}) -> lf.Map:
    ''' Plot the choropleth on the map using the ipyleaflet library
      @idToValue: a dictionary containing mappings of ids to their associated values
      @worldMap: ipyleaflet Map object. If this is specified, the new heatmap will be addded
                 to this object. Else a new Map object will be created
      @includeEmpty: true if we want to display the regions that have value 0. False otherwise
      @labelFormat: the string format of the text that is displayed when the mouse hovers over a polygon.
                    The format must contain exactly 2 placeholders.
      Returns: map object
  '''
    updatedIdToValue = __syncIdToValueDict(geoJson, idToValue)

    # If we don't display empty regions, we need to
    # create a new geo JSON that does NOT contain the
    # ids that have 0 value
    if (not includeEmpty):
        origGeoJson = geoJson
        geoJson = {"type": "FeatureCollection", "features": []}

        for idValue, value in updatedIdToValue.items():
            if (value > 0):
                feature = getFeatureById(origGeoJson, idValue)
                geoJson["features"].append(feature)

    # Create the world map object if not specified
    if (worldMap is None):
        #basemap=lf.basemaps.CartoDB.DarkMatter, center=center, zoom=10
        worldMap = lf.Map(**mapArgs)
        worldMap.add_control(lf.FullScreenControl())
        worldMap.add_control(lf.LayersControl(position="topright"))

    # Default heatmap arguments
    minVal, maxVal = min(updatedIdToValue.values()), max(
        updatedIdToValue.values())
    defaultHeatmapArgs = {
        "key_on": "id",
        "border_color": "black",
        "value_min": minVal,
        "value_max": maxVal,
        "style": {
            'fillOpacity': 0.8,
            'dashArray': '5, 5'
        },
        "hover_style": {
            'fillColor': 'purple',
            'dashArray': '0',
            'fillOpacity': 0.5
        },
        "name": "Choropleth",
        "colormap": linear.OrRd_06
    }

    # Make a copy of the heatmapArgs, because we would add the default arguments
    # to this dict if the default arguments are not specified by the caller. Making
    # a copy prevents modifying the passed in dict object
    heatmapArgs = dict(heatmapArgs)
    for k, v in defaultHeatmapArgs.items():
        if (k not in heatmapArgs):
            heatmapArgs[k] = v

    # Create the choropleth layer
    choroplethLayer = lf.Choropleth(geo_data=geoJson,
                                    choro_data=updatedIdToValue,
                                    **heatmapArgs)

    # Create a label widget to display the currently hovered polygon id &
    # the value associated with that id
    labelWidget = widgets.Label(value="")
    widgetControl = lf.WidgetControl(widget=labelWidget,
                                     position="bottomright")
    worldMap.add_control(widgetControl)

    def mouseout(*args, **kwargs):
        ''' Set the label value to empty string when the mouse exits a region '''
        labelWidget.value = ""

    def hover(*args, **kwargs):
        ''' Set the label to the id & its associated value '''
        idValue = kwargs["id"]
        labelWidget.value = labelFormat.format(idValue,
                                               updatedIdToValue[idValue])

    # Register callbacks
    choroplethLayer.on_mouseout(mouseout)
    choroplethLayer.on_hover(hover)

    # Remove existing choropleth layer that has the same name
    choroplethName = heatmapArgs["name"] if ("name" in heatmapArgs) else ""
    removeLayerByType(worldMap, choroplethName, lf.Choropleth)

    worldMap.add_layer(choroplethLayer)
    return worldMap
Example #15
0
class measures(object):
    def __init__(self):

        measures.sheet = None
        measures.sheet2 = None
        measures.band_index1 = 4
        measures.band_index2 = 4
        measures.pyccd_flag = False
        measures.pyccd_flag2 = False
        measures.table = None
        conn = sqlite3.connect(measures.dbPath)
        measures.current_id = measures.current_id
        measures.c = conn.cursor()
        measures.minv = 0
        measures.maxv = 6000
        measures.b1 = 'SWIR1'
        measures.b2 = 'NIR'
        measures.b3 = 'RED'

    # Starting variables
    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', 'BRIGHTNESS',
        'GREENNESS', 'WETNESS'
    ]
    year_range = [1986, 2018]
    doy_range = [1, 365]
    step = 1  #in years
    current_id = 0

    # Set up database
    dbPath = os.getcwd() + '/measures_database'
    command = '''CREATE TABLE measures
                  (id text, lat text, lon text, year1 text, year2 text, direction text, coverType text,
                  condition text, change text, chaOther text, confCA text,
                  class text, water text, bare text, albedo text, use text,
                  height text, transport text, impervious text, density text,
                  vegType1 text, herbaceous text, shrub text, forestPhenology text,
                  leafType text, location text, confidence real, notes text,
                  byear text, brange1 text, brange2 text)'''
    conn = sql.make_db(dbPath, command)

    # Widgets

    # Sliders
    years = plots.make_range_slider([1990, 1991], 1990, 2018, 1, 'Years:')
    break_years = plots.make_range_slider([1990, 1991], 1990, 2018, 1,
                                          'Years:')
    break_year = plots.make_slider(1990, 1991, 2018, 1, 'Years:')
    confidence = plots.make_slider(0, 0, 3, 1, 'Confidence:')
    ca_confidence = plots.make_slider(0, 0, 3, 1, '')

    ylim = plots.make_range_slider([0, 4000], -10000, 10000, 500, 'YLim:')
    xlim = plots.make_range_slider([2000, 2018], 1984, 2019, 1, 'XLim:')

    ylim2 = plots.make_range_slider([0, 4000], -10000, 10000, 500, 'YLim:')
    xlim2 = plots.make_range_slider([2000, 2018], 1984, 2019, 1, 'XLim:')

    # Dropdown boxes
    drop1 = plots.make_drop('Persistant Ice?',
                            ['Persistant Ice?', 'Yes', 'No'], 'Decision 2')
    drop2 = plots.make_drop('Decision 3', ['Decision 3'], 'Decision 3')
    drop3 = plots.make_drop('Decision 4', ['Decision 4'], 'Decision 4')
    drop4 = plots.make_drop('Decision 5', ['Decision 5'], 'Decision 5')
    drop5 = plots.make_drop('Decision 6', ['Decision 6'], 'Decision 6')
    drop6 = plots.make_drop('Decision 7', ['Decision 7'], 'Decision 7')
    drop7 = plots.make_drop('Decision 8', ['Decision 8'], 'Decision 8')
    drop8 = plots.make_drop('Decision 9', ['Decision 9'], 'Decision 9')
    drop9 = plots.make_drop('Stable', ['Stable', 'Transitional', 'Break'],
                            'Label Type:')
    drop0 = plots.make_drop(
        'Dominant or Secondary?',
        ['Dominant or Secondary?', 'Dominant', 'Secondary'], 'Decision 1')

    band_selector1 = plots.make_drop('SWIR1', band_list, 'Select band')
    band_selector2 = plots.make_drop('SWIR1', band_list, 'Select band')
    image_band_1 = plots.make_drop('RED', band_list, 'Red:')
    image_band_2 = plots.make_drop('GREEN', band_list, 'Green:')
    image_band_3 = plots.make_drop('BLUE', band_list, 'Blue:')

    # Checkbox
    color_check = plots.make_checkbox(False, 'Color DOY', False)

    # Select multiple
    veg_selector = plots.make_selector(['Veg Type'], [
        'Veg Type', 'Cropland', 'Plantation', 'Wetland', 'Riparian/Flood',
        'Mangrove'
    ],
                                       'Veg Type:',
                                       disabled=True)
    change_selector = plots.make_selector(['None'], [
        'None', 'Deforestation/Logging', 'Fire', 'Insect damage', 'Urban Dev.',
        'Flooding', 'Decline/Degradation', 'Regrowth', 'Riparian/Water shift',
        'Other (Specify)'
    ], 'Change Agent:')
    direction = plots.make_selector(['None'], [
        'None', 'Veg Increase', 'Veg Decrease', 'Water Increase',
        'Water Decrease', 'Bare Increase', 'Bare Decrease', 'Urban Increase',
        'Urban Decrease', 'Albedo Increase', 'Albedo Decrease'
    ], 'Directional Change:')

    # Text boxes
    change_other = plots.make_text('Specify other', 'Specify other', 'Other:')
    notes = plots.make_text_large(
        'Enter any useful or interesting information about the land cover of this sample',
        '',
        'Notes',
        layout=widgets.Layout())  #,layout=widgets.Layout(width='70%'))
    spreadsheet = plots.make_text('Google Spreadsheet Credential JSON',
                                  'Google Spreadsheet Credential JSON',
                                  'Credentials:')
    spreadName = plots.make_text('Google Spreadsheet Name',
                                 'Google Spreadsheet Name', 'SS Name:')
    sampleWidget = plots.make_text('Path to sample feature collection',
                                   'Path to sample feature collection',
                                   'Path:')

    stretch_min = plots.make_text_float(0, 0, 'Min:')
    stretch_max = plots.make_text_float(1450, 1450, 'Max:')
    zoom_box = plots.make_text_float(12, 12, 'Zoom:')
    idBox = plots.make_text('0', '0', 'ID:')

    # Buttons
    validate = plots.make_button(False, 'Validate', icon='check')
    save_button = plots.make_button(False, 'Save', icon='')
    load_button = plots.make_button(False, 'Load', icon='')
    toggle_pyccd_button = plots.make_button(False, 'Clear Pyccd 1', icon='')
    toggle_pyccd_button2 = plots.make_button(False, 'Clear Pyccd 2', icon='')
    return_button = plots.make_button(False, 'Return to Sample', icon='')

    next_pt = plots.make_button(False, 'Next point', icon='')
    previous_pt = plots.make_button(False, 'Previous point', icon='')
    pyccd_button = plots.make_button(False, 'Run PyCCD 1', icon='')
    pyccd_button2 = plots.make_button(False, 'Run PyCCD 2', icon='')
    clear_layers = plots.make_button(False, 'Clear Map', icon='')

    delete_rows = plots.make_button(False, 'Delete Last', icon='')

    # Validate
    valid = plots.make_valid(False, 'Not Saved', '')
    valid_load = plots.make_valid(False, 'Not Loaded', '')

    # HTML
    pt_message = plots.make_html('Current ID: ')
    time_label = plots.make_html('')
    coord_message = plots.make_html('Lat, Lon: ')
    selected_label = plots.make_html('ID of selected point')
    hover_label = plots.make_html('Test Value')
    text_brush = plots.make_html('Selected year range:')
    kml_link = plots.make_html('KML:')
    error_label = plots.make_html('Load a point')

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

    # Plots

    # Scales
    # Dates
    lc1_x = plots.make_bq_scale('date', datetime.date(xlim.value[0], 2, 1),
                                datetime.date(xlim.value[1], 1, 1))
    lc1_x2 = plots.make_bq_scale('date', datetime.date(xlim.value[0], 2, 1),
                                 datetime.date(xlim.value[1], 1, 1))

    # DOY
    lc1_x3 = plots.make_bq_scale('linear', 0, 365)

    # Reflectance
    lc2_y = plots.make_bq_scale('linear', ylim.value[0], ylim.value[1])
    lc2_y2 = plots.make_bq_scale('linear', ylim.value[0], ylim.value[1])

    # plots
    lc2 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x,
        'y': lc2_y
    }, [1, 1], {
        'click': 'select',
        'hover': 'tooltip'
    }, {
        'opacity': 1.0,
        'fill': 'DarkOrange',
        'stroke': 'Red'
    }, {'opacity': 0.5},
                             display_legend=True,
                             labels=['Sample point'])

    lc3 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x2,
        'y': lc2_y2
    }, [1, 1], {
        'click': 'select',
        'hover': 'tooltip'
    }, {
        'opacity': 1.0,
        'fill': 'DarkOrange',
        'stroke': 'Red'
    }, {'opacity': 0.5},
                             display_legend=True,
                             labels=['Clicked point'])

    lc4 = plots.make_bq_plot('lines', [], [], {
        'x': lc1_x,
        'y': lc2_y
    }, [1, 1], {}, {}, {},
                             colors=['black'],
                             stroke_width=3)

    lc5 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x,
        'y': lc2_y
    }, [1, 1], {}, {}, {},
                             labels=['Model Endpoint'],
                             colors=['red'],
                             marker='triangle-up')

    lc6 = plots.make_bq_plot('lines', [], [], {
        'x': lc1_x2,
        'y': lc2_y2
    }, [1, 1], {}, {}, {},
                             colors=['black'],
                             stroke_width=3)

    lc7 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x2,
        'y': lc2_y2
    }, [1, 1], {}, {}, {},
                             labels=['Model Endpoint'],
                             colors=['red'],
                             marker='triangle-up')

    lc8 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x3,
        'y': lc2_y
    }, [1, 1], {
        'click': 'select',
        'hover': 'tooltip'
    }, {
        'opacity': 1.0,
        'fill': 'DarkOrange',
        'stroke': 'Red'
    }, {'opacity': 0.5},
                             display_legend=True,
                             labels=['Sample point'])

    # Axis
    x_ax1 = plots.make_bq_axis('Date',
                               lc1_x,
                               num_ticks=6,
                               tick_format='%Y',
                               orientation='horizontal')
    x_ax2 = plots.make_bq_axis('Date',
                               lc1_x2,
                               num_ticks=6,
                               tick_format='%Y',
                               orientation='horizontal')
    x_ax3 = plots.make_bq_axis('DOY',
                               lc1_x3,
                               num_ticks=6,
                               orientation='horizontal')

    y_ay1 = plots.make_bq_axis('SWIR1', lc2_y, orientation='vertical')
    y_ay2 = plots.make_bq_axis('SWIR1', lc2_y2, orientation='vertical')

    # Figures
    fig = plots.make_bq_figure([lc2, lc4, lc5], [x_ax1, y_ay1], {
        'height': '300px',
        'width': '100%'
    }, 'Sample TS')
    fig2 = plots.make_bq_figure([lc3, lc6, lc7], [x_ax2, y_ay2], {
        'height': '300px',
        'width': '100%'
    }, 'Clicked TS')
    fig3 = plots.make_bq_figure([lc8], [x_ax3, y_ay1], {
        'height': '300px',
        'width': '100%'
    }, 'Clicked TS')

    # Functions

    # Delete data highlighted in rows
    def delete_data_rows(a):
        measures.c.execute(
            "DELETE FROM measures WHERE id = (SELECT MAX(id) FROM measures)")
        measures.change_table(0)
        condition = measures.drop9.value

        if condition == 'Break':
            measures.sheet2.delete_row(2)
        else:
            measures.sheet.delete_row(2)

    # Reset dropdowns
    def reset_drops():

        measures.drop4.set_trait('options', ['Decision 4'])
        measures.drop5.set_trait('options', ['Decision 5'])
        measures.drop6.set_trait('options', ['Decision 6'])
        measures.drop7.set_trait('options', ['Decision 7'])
        measures.drop8.set_trait('options', ['Decision 8'])
        measures.veg_selector.disabled = True

    # Change dropdowns based on drop1 selection
    def drop1_clicked(selection):

        if selection.new == 'No':
            measures.drop2.set_trait('options',
                                     ['>30% Vegetated?', 'Yes', 'No'])
        elif selection.new == 'Yes':
            measures.drop2.set_trait('options', ['Ice/Snow'])
            measures.drop3.set_trait('options',
                                     ['No other information needed'])
            measures.reset_drops()

    # Change dropdowns based on drop2 selection
    def drop2_clicked(selection):

        if '>30% Vegetated?' in measures.drop2.options:
            if selection.new == 'Yes':
                measures.drop3.set_trait('options', [
                    'Density', 'Closed (60-70%)', 'Open (30-60%)',
                    'Sparse (<30%)'
                ])
                measures.veg_selector.disabled = False
                measures.drop4.set_trait('options', ['Trees?', 'Yes', 'No'])
            elif selection.new == 'No':
                measures.drop3.set_trait(
                    'options',
                    ['Dominant Cover?', 'Water', 'Bare', 'Developed'])
                measures.drop4.set_trait('options', ['Decision 4'])
                measures.drop5.set_trait('options', ['Decision 5'])
                measures.drop6.set_trait('options', ['Decision 6'])
                measures.drop7.set_trait('options', ['Decision 7'])
                measures.drop8.set_trait('options', ['Decision 8'])
                measures.veg_selector.disabled = True

        else:
            measures.drop3.set_trait('options',
                                     ['No Other Information Needed'])

    # Change dropdowns based on drop3 selection
    def drop3_clicked(selection):

        if 'Dominant Cover?' in measures.drop3.options:
            measures.veg_selector.disabled = True
            if selection.new == 'Water':
                measures.drop4.set_trait('options', [
                    'Water Type', 'Shore/Inter tidal', 'Shallows', 'River',
                    'Lake/Reservoir', 'Ocean'
                ])
            elif selection.new == 'Bare':
                measures.drop4.set_trait('options', [
                    'Bare Type', 'Soil', 'Rock', 'Quarry (Active)',
                    'Beach/Sand'
                ])
            elif selection.new == 'Developed':
                measures.drop4.set_trait(
                    'options', ['Surface Albedo', 'High', 'Low', 'Mixed'])
                measures.drop5.set_trait(
                    'options', ['Use', 'Residential', 'Commercial/Industrial'])
                measures.drop6.set_trait('options', [
                    'Building Height', 'No Buildings', '1-2 Stories',
                    '3-5 Stories', '5+ Stories'
                ])
                measures.drop7.set_trait(
                    'options', ['Transport', 'Road', 'Not Applicable'])
                measures.drop8.set_trait('options', [
                    '% Impervious', 'High (60-100)', 'Medium (30-60)',
                    'Low (<30)'
                ])

    # Change dropdowns based on drop4 selection
    def drop4_clicked(selection):

        if 'Trees?' in measures.drop4.options:
            if selection.new == 'Yes':
                measures.drop5.set_trait(
                    'options', ['Height >5m & Canopy >30%', 'Yes', 'No'])
            elif selection.new == 'No':
                measures.drop5.set_trait('options', [
                    'Herbaceous Type', 'Grassland', 'Pasture',
                    'Lawn/Urban Grass', 'Moss/Lichen'
                ])

    # Change dropdowns based on drop5 selection
    def drop5_clicked(selection):

        if 'Height >5m & Canopy >30%' in measures.drop5.options:
            if selection.new == 'Yes':
                measures.drop6.set_trait(
                    'options',
                    ['Forest Type', 'Evergreen', 'Deciduous', 'Mixed'])
                measures.drop7.set_trait(
                    'options', ['Leaf Type', 'Broad', 'Needle', 'Unsure'])
                measures.drop8.set_trait('options',
                                         ['Location', 'Interior', 'Edge'])

            elif selection.new == 'No':
                measures.drop6.set_trait(
                    'options',
                    ['Shrub Type', 'Evergreen', 'Deciduous', 'Mixed'])

    # Check validity of current sample
    def check_val_status(selection):

        selected_secondary_lc = False
        wrote_correct_lc = False
        if measures.second_class_drop.value != 'Secondary Class Information':
            selected_secondary_lc = True
        else:
            print("Must specify secondary class information!")
        if measures.lc.value.capitalize(
        ) == measures.textClass.value.capitalize():
            wrote_correct_lc = True
        if selected_secondary_lc and wrote_correct_lc:
            measures.valid.value = True
            measures.save_button.disabled = False

    # load the feature collection, database, and google sheet
    def load_everything(sender):

        measures.sheet = sheets.load_sheet(measures.spreadName.value, 0,
                                           measures.spreadsheet.value)
        measures.sheet2 = sheets.load_sheet(measures.spreadName.value, 1,
                                            measures.spreadsheet.value)

        # Load the sample as a feature collection
        sample_path = measures.sampleWidget.value
        fc_df = utils.fc2dfgeo(sample_path)
        measures.fc_df, first_index = utils.check_id(fc_df)
        measures.valid_load.value = True
        measures.valid_load.description = 'Loaded!'
        measures.current_id = first_index - 1

    # If the class type is 'break', turn on necessary widgets
    def turn_on_break_years(selection):

        if selection.new == 'Break':
            measures.break_years.disabled = False
            measures.break_year.disabled = False
        else:
            measures.break_years.disabled = True
            measures.break_year.disabled = True

    # Change yaxis for the sample time series
    def change_yaxis(value):

        measures.lc2_y.min = measures.ylim.value[0]
        measures.lc2_y.max = measures.ylim.value[1]

    # Change xaxis for the sample time series
    def change_xaxis(value):

        measures.lc1_x.min = datetime.date(measures.xlim.value[0], 2, 1)
        measures.lc1_x.max = datetime.date(measures.xlim.value[1], 2, 1)
        measures.year_range = [measures.xlim.value[0], measures.xlim.value[1]]

    # Change y axis for the clicked point
    def change_yaxis2(value):

        measures.lc2_y2.min = measures.ylim2.value[0]
        measures.lc2_y2.max = measures.ylim2.value[1]

    # Change x axis for the clicked point
    def change_xaxis2(value):

        measures.lc1_x2.min = datetime.date(measures.xlim2.value[0], 2, 1)
        measures.lc1_x2.max = datetime.date(measures.xlim2.value[1], 2, 1)

    # Display date of observation when hovering on scatterplot
    def hover_event(self, target):

        measures.hover_label.value = str(target['data']['x'])

    # Advance to next sample
    def advance(b):

        measures.lc4.x = []
        measures.lc4.y = []
        measures.lc5.x = []
        measures.lc5.y = []
        measures.lc5.display_legend = False
        measures.pyccd_flag = False
        measures.current_id += 1
        measures.pt_message.value = "Point ID: {}".format(measures.current_id)
        measures.map_point()
        measures.get_ts()
        measures.plot_ts(measures.lc2, 'ts')
        measures.plot_ts(measures.lc8, 'doy')
        measures.change_table(0)
        measures.valid.value = False
        measures.description = 'Not Saved'

    # Go to previous sample
    def decrease(b):

        measures.lc4.x = []
        measures.lc4.y = []
        measures.lc5.x = []
        measures.lc5.y = []
        measures.lc5.display_legend = False
        measures.pyccd_flag = False
        measures.current_id -= 1
        measures.pt_message.value = "Point ID: {}".format(measures.current_id)
        measures.map_point()
        measures.get_ts()
        #measures.plot_ts()
        measures.plot_ts(measures.lc2, 'ts')
        measures.plot_ts(measures.lc8, 'doy')
        measures.change_table(0)
        measures.valid.value = False
        measures.description = 'Not Saved'

    # Go to a specific sample
    def go_to_sample(b):

        measures.lc4.x = []
        measures.lc4.y = []
        measures.lc5.x = []
        measures.lc5.y = []
        measures.lc5.display_legend = False
        measures.pyccd_flag = False
        measures.current_id = int(b.value)
        measures.pt_message.value = "Point ID: {}".format(measures.current_id)
        measures.valid.value = False
        measures.description = 'Not Saved'
        measures.map_point()
        measures.get_ts()
        #measures.plot_ts()
        measures.plot_ts(measures.lc2, 'ts')
        measures.plot_ts(measures.lc8, 'doy')

    # Return to sample location
    def return_to_sample(b):
        measures.map_point()

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

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

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

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

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

    # Band selection for sample point
    def on_band_selection1(change):
        band_index = change['owner'].index
        measures.band_index1 = band_index
        new_band = change['new']
        measures.y_ay1.label = new_band
        #measures.plot_ts()
        measures.plot_ts(measures.lc2, 'ts')
        measures.plot_ts(measures.lc8, 'doy')

    # Band selection for clicked point
    def on_band_selection2(change):
        new_band = change['new']
        band_index = change['owner'].index
        measures.band_index2 = band_index
        measures.lc3.x = measures.click_df['datetime']
        measures.lc3.y = measures.click_df[new_band]
        #measures.plot_ts(measures.lc3, 'ts')
        measures.y_ay2.label = new_band
        if measures.pyccd_flag2:
            measures.do_pyccd2(0)

    # Clear everything on map besides current sample
    def clear_map(b):

        lft.clear_map(measures.m, streets=True)
        if hasattr(measures, 'fc_df'):
            measures.map_point()

    # Add an image to the map when clicked on time series
    def add_image(self, target):

        m = measures.m
        df = measures.sample_df
        current_band = measures.band_list[measures.band_index1]
        sample_col = measures.sample_col
        stretch_min = measures.stretch_min
        stretch_max = measures.stretch_max
        b1 = measures.b1
        b2 = measures.b2
        b3 = measures.b3
        lft.click_event(target, m, current_band, df, sample_col, stretch_min,
                        stretch_max, b1, b2, b3)

    def add_image2(self, target):
        m = measures.m
        df = measures.click_df
        current_band = measures.band_list[measures.band_index2]
        sample_col = measures.click_col
        stretch_min = measures.minv
        stretch_max = measures.maxv
        b1 = measures.b1
        b2 = measures.b2
        b3 = measures.b3
        lft.click_event(target, m, current_band, df, sample_col, stretch_min,
                        stretch_max, b1, b2, b3)

    # Plot ts for point
    def do_draw(self, action, geo_json):

        current_band = measures.band_list[measures.band_index2]
        year_range = measures.year_range
        doy_range = measures.doy_range
        _col, _df = utils.handle_draw(action, geo_json, current_band,
                                      year_range, doy_range)
        measures.click_df = _df
        measures.click_col = _col
        measures.lc6.x = []
        measures.lc6.y = []
        measures.lc7.x = []
        measures.lc7.y = []

        measures.lc3.x = measures.click_df['datetime']
        measures.lc3.y = measures.click_df[current_band]

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

    # Add point location to map
    def map_point():
        zoom = int(measures.zoom_box.value)
        kml = measures.kml_link
        name = 'Sample point'
        data = measures.fc_df['geometry'][measures.current_id]
        coord1 = data['coordinates'][0]
        coord2 = data['coordinates'][1]
        measures.coord_message.value = "Lat, Lon: {}, {}".format(
            coord2, coord1)
        lft.add_map_point(data, zoom, measures.m, kml, name)

    # Get time series data for location.
    def get_ts():

        measures.error_label.value = 'Loading'
        coords = measures.fc_df['geometry'][measures.current_id]['coordinates']
        year_range = measures.year_range
        doy_range = measures.doy_range

        measures.current_band = measures.band_list[measures.band_index1]
        measures.sample_col = utils.get_full_collection(
            coords, year_range, doy_range)
        measures.sample_df = utils.get_df_full(measures.sample_col,
                                               coords).dropna()
        measures.error_label.value = 'Point Loaded!'

    # TODO: how is this different from handle_draw?
    def plot_ts(plot, plottype):
        df = measures.sample_df

        if measures.color_check.value == True:
            color_marks = list(measures.sample_df['color'].values)
        else:
            color_marks = None

        band = measures.band_list[measures.band_index1]

        if plottype == 'ts':
            plots.add_plot_ts(df, plot, band=band, color_marks=color_marks)
        else:
            plots.add_plot_doy(df, plot, band=band, color_marks=color_marks)

        if measures.pyccd_flag:
            measures.do_pyccd(0)

    # Run pyccd for the sample location
    def do_pyccd(b):

        pyccd_flag = measures.pyccd_flag
        display_legend = measures.lc5.display_legend
        dfPyCCD = measures.sample_df
        band_index = measures.band_index1
        results = ccd_tools.run_pyccd(pyccd_flag, display_legend, dfPyCCD,
                                      band_index)

        ccd_tools.plot_pyccd(dfPyCCD, results, band_index, (0, 4000),
                             measures.lc4, measures.lc5)

    # Run pyccd for the clicked location
    def do_pyccd2(b):

        pyccd_flag = measures.pyccd_flag2
        display_legend = measures.lc7.display_legend
        dfPyCCD = measures.click_df
        band_index = measures.band_index1
        results = ccd_tools.run_pyccd(pyccd_flag, display_legend, dfPyCCD,
                                      band_index)

        ccd_tools.plot_pyccd(dfPyCCD, results, band_index, (0, 4000),
                             measures.lc6, measures.lc7)

    def clear_pyccd(b):
        measures.lc4.x = []
        measures.lc5.y = []

    def clear_pyccd2(b):
        measures.lc6.x = []
        measures.lc7.y = []

    # Save sample
    def save_sample():
        # Connect to the database
        conn = sqlite3.connect(measures.dbPath)
        c = conn.cursor()

        # Get everything in right format
        year1 = measures.years.value[0]
        year2 = measures.years.value[1]

        waterType = 'N/A'
        bareType = 'N/A'
        albedo = 'N/A'
        use = 'N/A'
        height = 'N/A'
        transport = 'N/A'
        impervious = 'N/A'
        density = 'N/A'
        vegType1 = 'N/A'
        herbaceousType = 'N/A'
        shrubType = 'N/A'
        forestPhenology = 'N/A'
        leafType = 'N/A'
        location = 'N/A'

        condition = measures.drop9.value
        coverType = measures.drop0.value
        changeAgent = measures.change_selector.value
        changeAgent = [str(i) for i in changeAgent]
        changeAgent = ', '.join(changeAgent)
        if changeAgent != 'None':
            confCA = measures.ca_confidence.value
            break_year = measures.break_year.value
            break_range1 = measures.break_years.value[0]
            break_range2 = measures.break_years.value[1]
        else:
            confCA = 'N/A'
            break_year = 'N/A'
            break_range1 = 'N/A'
            break_range2 = 'N/A'
        ca_other = measures.change_other.value
        if ca_other == 'Specify other':
            ca_other = 'N/A'

        direction = measures.direction.value
        direction = [str(i) for i in direction]
        direction = ', '.join(direction)

        class1 = 'Unfilled'

        # Ice/Snow
        if measures.drop1.value == 'Yes':
            class1 = 'Snow/Ice'
        else:
            if measures.drop2.value == 'No':  #Non-Veg
                class1 = measures.drop3.value
                if class1 == 'Water':
                    waterType = measures.drop4.value
                elif class1 == 'Bare':
                    bareType = measures.drop4.value
                else:
                    albedo = measures.drop4.value  #HERE
                    use = measures.drop5.value
                    height = measures.drop6.value
                    transport = measures.drop7.value
                    impervious = measures.drop8.value
            elif measures.drop2.value == 'Yes':  #Veg
                density = measures.drop3.value
                vegType1 = measures.veg_selector.value
                vegType1 = [str(i) for i in vegType1]
                vegType1 = ', '.join(vegType1)
                if measures.drop5.value == 'No':  #Herbaceous
                    class1 = 'Herbaceous'
                    herbaceousType = measures.drop6.value
                elif measures.drop5.value == 'Yes':
                    class1 = 'Forest'
                    forestPhenology = measures.drop6.value
                    leafType = measures.drop7.value
                    location = measures.drop8.value

        conf = measures.confidence.value
        notes_value = measures.notes.value
        idSample = measures.current_id
        lat = measures.m.center[0]
        lon = measures.m.center[1]

        sampleInput = (idSample, lat, lon, year1, year2, direction, coverType,
                       condition, changeAgent, ca_other, confCA, class1,
                       waterType, bareType, albedo, use, height, transport,
                       impervious, density, vegType1, herbaceousType,
                       shrubType, forestPhenology, leafType, location, conf,
                       notes_value, break_year, break_range1, break_range2)

        # Put sample information into database
        c.execute("""insert into measures
                  values {i}""".format(i=sampleInput))

        # Save (commit) the changes
        conn.commit()

        # Close the cursor
        c.close()

        # Save to drive
        sampleInputList = [
            str(idSample),
            str(lat),
            str(lon),
            str(year1),
            str(year2), direction, coverType, condition, changeAgent, ca_other,
            confCA, class1, waterType, bareType, albedo, use, height,
            transport, impervious, density, vegType1, herbaceousType,
            shrubType, forestPhenology, leafType, location, conf, notes_value
        ]

        sampleInputListFull = sampleInputList

        # Save break information to second sheet
        if condition == 'Break':
            breakList = [
                str(idSample),
                str(lat),
                str(lon), changeAgent, ca_other, confCA, break_year,
                break_range1, break_range2
            ]
            measures.sheet2.insert_row(breakList, 2)
            count = len(measures.sheet2.col_values(1))
            time.sleep(3)
            count_new = len(measures.sheet2.col_values(1))
        else:
            count = len(measures.sheet.col_values(1))
            measures.sheet.insert_row(sampleInputListFull, 2)
            time.sleep(3)
            count_new = len(measures.sheet.col_values(1))

        if count_new > count:
            # Change save validity state
            measures.valid.value = True
            measures.valid.description = 'Saved!'
            measures.reset_everything()
        else:
            time.sleep(10)
            if condition == 'Break':
                count_new = len(measures.sheet2.col_values(1))
            else:
                count_new = len(measures.sheet.col_values(1))
            if count_new > count:
                # Change save validity state
                measures.valid.value = True
                measures.valid.description = 'Saved!'
                measures.reset_everything()

    # Reset all widgets
    def reset_everything():

        measures.drop1.set_trait('value', 'Persistant Ice?')
        measures.drop2.set_trait('options', ['Decision 3'])
        measures.drop3.set_trait('options', ['Decision 4'])
        measures.drop5.set_trait('options', ['Decision 5'])
        measures.drop6.set_trait('options', ['Decision 6'])
        measures.drop7.set_trait('options', ['Decision 7'])
        measures.drop8.set_trait('options', ['Decision 8'])
        measures.veg_selector.disabled = True
        measures.years.set_trait('value', [1990, 1991])
        measures.confidence.set_trait('value', 0)
        measures.ca_confidence.set_trait('value', 0)

    # Interaction function for saving sample
    def do_save_sample(a):
        measures.save_sample()
        measures.change_table(0)

    # Widget interactions

    delete_rows.on_click(delete_data_rows)
    return_button.on_click(return_to_sample)
    save_button.on_click(do_save_sample)
    validate.on_click(check_val_status)
    drop1.observe(drop1_clicked, 'value')
    drop2.observe(drop2_clicked, 'value')
    drop3.observe(drop3_clicked, 'value')
    drop4.observe(drop4_clicked, 'value')
    drop5.observe(drop5_clicked, 'value')
    drop9.observe(turn_on_break_years, 'value')

    load_button.on_click(load_everything)

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

    zoom = 5
    layout = widgets.Layout(width='50%')
    center = (3.3890701010382958, -67.32297252983098)
    m = lft.make_map(zoom, layout, center)
    lft.add_basemap(m, ipyleaflet.basemaps.Esri.WorldImagery)

    # Display controls
    ylim.observe(change_yaxis)
    xlim.observe(change_xaxis)
    ylim2.observe(change_yaxis2)
    xlim2.observe(change_xaxis2)
    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')

    # Samples
    next_pt.on_click(advance)
    previous_pt.on_click(decrease)

    # pyccd
    pyccd_button.on_click(do_pyccd)
    pyccd_button2.on_click(do_pyccd2)
    toggle_pyccd_button.on_click(clear_pyccd)
    toggle_pyccd_button2.on_click(clear_pyccd2)

    # Plots
    lc2.on_element_click(add_image)
    lc2.tooltip = hover_label
    lc2.on_hover(hover_event)

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

    idBox.on_submit(go_to_sample)

    # Mapping
    dc.on_draw(do_draw)
    m.add_control(dc)
    m.add_control(ipyleaflet.LayersControl())
Example #16
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>"
         )
Example #17
0
 def __init__(self, projection='Global', **kwargs):
     # set default keyword arguments
     kwargs.setdefault('attribution', True)
     kwargs.setdefault('zoom', 1)
     kwargs.setdefault('zoom_control', False)
     kwargs.setdefault('scale_control', False)
     kwargs.setdefault('cursor_control', True)
     kwargs.setdefault('layer_control', True)
     kwargs.setdefault('center', (39, -108))
     # create basemap in projection
     if (projection == 'Global'):
         self.map = ipyleaflet.Map(
             center=kwargs['center'],
             zoom=kwargs['zoom'],
             max_zoom=15,
             attribution_control=kwargs['attribution'],
             basemap=ipyleaflet.basemaps.Esri.WorldTopoMap)
         self.crs = 'EPSG:3857'
     elif (projection == 'North'):
         self.map = ipyleaflet.Map(
             center=kwargs['center'],
             zoom=kwargs['zoom'],
             max_zoom=24,
             attribution_control=kwargs['attribution'],
             basemap=ipyleaflet.basemaps.Esri.ArcticOceanBase,
             crs=projections.EPSG5936.Basemap)
         self.map.add_layer(ipyleaflet.basemaps.Esri.ArcticOceanReference)
         self.crs = 'EPSG:5936'
     elif (projection == 'South'):
         self.map = ipyleaflet.Map(
             center=kwargs['center'],
             zoom=kwargs['zoom'],
             max_zoom=9,
             attribution_control=kwargs['attribution'],
             basemap=ipyleaflet.basemaps.Esri.AntarcticBasemap,
             crs=projections.EPSG3031.Basemap)
         self.crs = 'EPSG:3031'
     # add control for layers
     if kwargs['layer_control']:
         self.layer_control = ipyleaflet.LayersControl(position='topleft')
         self.map.add_control(self.layer_control)
         self.layers = self.map.layers
     # add control for zoom
     if kwargs['zoom_control']:
         zoom_slider = ipywidgets.IntSlider(description='Zoom level:',
                                            min=self.map.min_zoom,
                                            max=self.map.max_zoom,
                                            value=self.map.zoom)
         ipywidgets.jslink((zoom_slider, 'value'), (self.map, 'zoom'))
         zoom_control = ipyleaflet.WidgetControl(widget=zoom_slider,
                                                 position='topright')
         self.map.add_control(zoom_control)
     # add control for spatial scale bar
     if kwargs['scale_control']:
         scale_control = ipyleaflet.ScaleControl(position='topright')
         self.map.add_control(scale_control)
     # add control for cursor position
     if kwargs['cursor_control']:
         self.cursor = ipywidgets.Label()
         cursor_control = ipyleaflet.WidgetControl(widget=self.cursor,
                                                   position='bottomleft')
         self.map.add_control(cursor_control)
         # keep track of cursor position
         self.map.on_interaction(self.handle_interaction)
     # add control for marker
     if kwargs['marker_control']:
         # add marker with default location
         self.marker = ipyleaflet.Marker(location=kwargs['center'],
                                         draggable=True)
         self.map.add_layer(self.marker)
         # add text with marker location
         self.marker_text = ipywidgets.Text(
             value='{0:0.8f},{1:0.8f}'.format(*kwargs['center']),
             description='Lat/Lon:',
             disabled=False)
         # watch marker widgets for changes
         self.marker.observe(self.set_marker_text)
         self.marker_text.observe(self.set_marker_location)
         self.map.observe(self.set_map_center)
         # add control for marker location
         marker_control = ipyleaflet.WidgetControl(widget=self.marker_text,
                                                   position='bottomright')
         self.map.add_control(marker_control)
Example #18
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
Example #19
0
class TSTools(object):

    def __init__(self):

        TSTools.band_index2 = 4
        TSTools.pyccd_flag2 = False
        TSTools.minv = 0
        TSTools.maxv = 6000
        TSTools.b1 = 'SWIR1'
        TSTools.b2 = 'NIR'
        TSTools.b3 = 'RED'


    ####### Starting Variables #######

    pyccd_flag2 = False
    current_band = ''
    band_index2 = 4
    click_col = ''
    point_color = ['#43a2ca']
    click_df = pd.DataFrame()
    click_geojson = ''
    PyCCDdf = pd.DataFrame()
    results = ''
    band_list = ['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2', 'BRIGHTNESS',
                 'GREENNESS', 'WETNESS', 'NDVI', 'NDFI', 'EVI', 'GV', 'Shade',
                 'NPV', 'Soil', ]
    doy_range = [1, 365]
    step = 1  #in years


    ###### Widgets ######
    ylim2 = plots.make_range_slider([0, 4000], -10000, 10000, 500, 'YLim:')
    xlim2 = plots.make_range_slider([2000, 2020], 1984, 2020, 1, 'XLim:')

    band_selector2 = plots.make_drop('SWIR1', band_list, 'Select band')
    image_band_1 = plots.make_drop('SWIR1', band_list, 'Red:')
    image_band_2 = plots.make_drop('NIR', band_list, 'Green:')
    image_band_3 = plots.make_drop('RED', band_list, 'Blue:')

    # Checkbox
    color_check = plots.make_checkbox(False, 'Color DOY', False)

    stretch_min = plots.make_text_float(0, 0, 'Min:')
    stretch_max = plots.make_text_float(6000, 6000, 'Max:')

    # Buttons
    pyccd_button2 = plots.make_button(False, 'Run PyCCD 2', icon='')
    toggle_pyccd_button2 = plots.make_button(False, 'Clear PyCCD', icon='')
    clear_layers = plots.make_button(False, 'Clear Map', icon='')

    # HTML
    hover_label = plots.make_html('Test Value')

    ###### Plots ######

    # Scales
    # Dates
    lc1_x2 = plots.make_bq_scale('date', datetime.date(xlim2.value[0], 2, 1),
                                 datetime.date(xlim2.value[1], 1, 1))

    # DOY
    lc1_x3 = plots.make_bq_scale('linear', 0, 365)

    # Reflectance
    lc2_y2 = plots.make_bq_scale('linear', ylim2.value[0], ylim2.value[1])

    # plots
    lc3 = plots.make_bq_plot('scatter', [], [], {'x': lc1_x2, 'y': lc2_y2},
                             [1, 1],
                             {'click': 'select', 'hover': 'tooltip'},
                             {'opacity': 1.0, 'fill': 'DarkOrange',
                              'stroke': 'Red'},
                             {'opacity': 0.5}, display_legend=True,
                             labels=['Clicked point'])

    lc6 = plots.make_bq_plot('lines', [], [], {'x': lc1_x2, 'y': lc2_y2},
                             [1, 1], {}, {}, {}, colors=['black'],
                             stroke_width=3, labels=['PyCCD Model'],
                             display_legend=False)

    lc7 = plots.make_bq_plot('scatter', [], [], {'x': lc1_x2, 'y': lc2_y2},
                             [1, 1], {}, {}, {}, labels=['Model Endpoint'],
                             colors=['red'], marker='triangle-up')

    lc8 = plots.make_bq_plot('scatter', [], [], {'x': lc1_x3, 'y': lc2_y2},
                             [1, 1],
                             {'click': 'select', 'hover': 'tooltip'},
                             {'opacity': 1.0, 'fill': 'DarkOrange',
                              'stroke': 'Red'},
                             {'opacity': 0.5}, display_legend=True,
                             labels=['Clicked point'])

    # Axis
    x_ax2 = plots.make_bq_axis('Date', lc1_x2, num_ticks=6, tick_format='%Y',
                               orientation='horizontal')
    x_ax3 = plots.make_bq_axis('DOY', lc1_x3, num_ticks=6,
                               orientation='horizontal')

    y_ay2 = plots.make_bq_axis('SWIR1', lc2_y2, orientation='vertical')

    # Figures
    fig2 = plots.make_bq_figure([lc3, lc6, lc7], [x_ax2, y_ay2],
                                {'height': '300px', 'width': '100%'},
                                'Clicked TS')
    fig3 = plots.make_bq_figure([lc8], [x_ax3, y_ay2], {'height': '300px',
                                'width': '100%'}, 'Clicked DOY')

    ###### Functions ######

    # Change y axis for the clicked point
    def change_yaxis2(value):

        TSTools.lc2_y2.min = TSTools.ylim2.value[0]
        TSTools.lc2_y2.max = TSTools.ylim2.value[1]

    # Change x axis for the clicked point
    def change_xaxis2(value):

        TSTools.lc1_x2.min = datetime.date(TSTools.xlim2.value[0], 2, 1)
        TSTools.lc1_x2.max = datetime.date(TSTools.xlim2.value[1], 2, 1)

    # Display date of observation when hovering on scatterplot
    def hover_event(self, target):

        TSTools.hover_label.value = str(target['data']['x'])

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

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

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

   # Band selection for clicked point
    def on_band_selection2(change):
        new_band = change['new']
        band_index = change['owner'].index
        TSTools.band_index2 = band_index
        TSTools.lc3.x = TSTools.click_df['datetime'].values
        TSTools.lc3.y = TSTools.click_df[new_band]
        TSTools.plot_ts(TSTools.lc3, 'ts')
        TSTools.plot_ts(TSTools.lc8, 'doy')
        TSTools.y_ay2.label = new_band
        if TSTools.pyccd_flag2:
            TSTools.do_pyccd2(0)

    # Clear everything on map
    def clear_map(b):
        lft.clear_map(TSTools.m, streets=True)

    def add_image2(self, target):
        m = TSTools.m
        df = TSTools.click_df
        current_band = TSTools.band_list[TSTools.band_index2]
        sample_col = TSTools.click_col
        stretch_min = TSTools.stretch_min.value
        stretch_max = TSTools.stretch_max.value
        b1 = TSTools.b1
        b2 = TSTools.b2
        b3 = TSTools.b3
        lft.click_event(target, m, current_band, df, sample_col, stretch_min,
                        stretch_max, b1, b2, b3)

    # Plot ts for point
    def do_draw(self, action, geo_json):
        current_band = TSTools.band_list[TSTools.band_index2]
        doy_range = TSTools.doy_range
        _col, _df = utils.handle_draw(action, geo_json, current_band,
                                      list(TSTools.xlim2.value), doy_range)
        TSTools.click_geojson = geo_json
        TSTools.click_df = _df
        TSTools.click_col = _col

        TSTools.plot_ts(TSTools.lc3, 'ts')
        TSTools.plot_ts(TSTools.lc8, 'doy')

    # Add time series data to plots
    def plot_ts(plot, plottype):
        df = TSTools.click_df

        if TSTools.color_check.value is True:
            color_marks = list(df['color'].values)
        else:
            color_marks = None

        band = TSTools.band_list[TSTools.band_index2]

        if plottype == 'ts':
            plots.add_plot_ts(df, plot, band=band, color_marks=color_marks)
        else:
            plots.add_plot_doy(df, plot, band=band, color_marks=color_marks)

        if TSTools.pyccd_flag2:
            TSTools.do_pyccd2(0)

    # Run pyccd for the clicked location
    def do_pyccd2(b):

        TSTools.pyccd_flag2 = True
        display_legend = TSTools.lc7.display_legend
        dfPyCCD = TSTools.click_df
        band_index = TSTools.band_index2
        TSTools.results = ccd_tools.run_pyccd(display_legend, dfPyCCD, band_index)
        if band_index > 5:
            TSTools.lc6.y = []
            TSTools.lc6.x = []
            TSTools.lc7.y = []
            TSTools.lc7.x = []
            TSTools.lc7.display_legend = False
            return
        else:
            ccd_tools.plot_pyccd(dfPyCCD, TSTools.results, band_index, (0, 4000),
                                 TSTools.lc6, TSTools.lc7)
            TSTools.lc7.display_legend = True


    # Clear pyccd results
    def clear_pyccd2(b):
        TSTools.lc6.x = []
        TSTools.lc7.y = []

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

    zoom = 5
    layout = widgets.Layout(width='50%')
    center = (3.3890701010382958, -67.32297252983098)
    m = lft.make_map(zoom, layout, center)

    # Display controls
    ylim2.observe(change_yaxis2)
    xlim2.observe(change_xaxis2)
    clear_layers.on_click(clear_map)
    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')

    # pyccd
    pyccd_button2.on_click(do_pyccd2)
    toggle_pyccd_button2.on_click(clear_pyccd2)

    # Plots
    lc3.on_element_click(add_image2)
    lc3.tooltip = hover_label
    lc3.on_hover(hover_event)
    lc8.on_element_click(add_image2)
    lc8.tooltip = hover_label
    lc8.on_hover(hover_event)

    # Mapping
    measure = ipyleaflet.MeasureControl(position='bottomleft',
                                        active_color = 'orange',
                                        primary_length_unit = 'kilometers'
                                        )
    measure.completed_color = 'red'

    dc.on_draw(do_draw)
    m.add_control(dc)
    m.add_control(measure)
    m.add_control(ipyleaflet.LayersControl())
def plot_geo_data_cluster(data, geom_column, title_columns):
    def date_filter(df, date_range, timestamp_column: str):
        dates = pd.to_datetime(df[timestamp_column]).apply(pd.Timestamp.date)
        return df[(date_range[0] <= dates) & (dates <= date_range[1])]

    def toggle_tweets_table_visibility(change):
        app_state['is_in_bounds'] = None
        if change['old'] and not change['new']:
            tweets_table.value, app_state['is_in_bounds'] = '', None
        else:
            update_range()

    def update_range(*_):
        def in_bounds(loc):
            return all(bounds[0] < loc) and all(loc < bounds[1])

        if len(m.bounds) == 0:
            return

        bounds = np.array(m.bounds)
        locs = app_state['filtered_data'][geom_column].apply(_wkb_hex_to_point)
        is_in_bounds = locs.apply(in_bounds)
        if app_state['is_in_bounds'] is None or not np.array_equal(
                is_in_bounds, app_state['is_in_bounds']):
            if is_in_bounds.sum() > 0:
                ts_plot = _get_ts_count_plot(
                    app_state['full_data'],
                    app_state['filtered_data'][is_in_bounds],
                    app_state['timestamp_column'])
                time_slider_box.children = [
                    ts_plot, *time_slider_box.children[1:]
                ]

                if tweets_table_cb.value:
                    tweets_table.value = app_state['filtered_data'].loc[
                        is_in_bounds,
                        title_columns].reset_index(drop=True).to_html(
                            formatters={'media': _to_html},
                            escape=False,
                            na_rep='',
                            index=False)
            else:
                tweets_table.value = ''

        tweets_table_cb.description = 'Show {} Tweets'.format(
            is_in_bounds.sum())
        app_state['is_in_bounds'] = is_in_bounds

    def change_date_range(change):
        def filter_markers(marker_cluster: ipyleaflet.MarkerCluster, min_date,
                           max_date):
            marker_cluster.markers = [
                m for m in app_state['markers']
                if min_date <= m.timestamp.date() <= max_date
            ]

        filtered_data = date_filter(
            app_state['full_data'],
            change['new'],
            timestamp_column=app_state['timestamp_column'])
        app_state['filtered_data'] = filtered_data
        heatmap.locations = list(
            filtered_data[geom_column].apply(_wkb_hex_to_point).values)
        filter_markers(marker_clusters, *change['new'])
        update_range()

    m = ipyleaflet.Map(center=(51, 10),
                       zoom=4,
                       scroll_wheel_zoom=True,
                       zoom_control=False)
    m.layout.height = '900px'

    app_state = dict(is_in_bounds=None,
                     full_data=data.dropna(subset=[geom_column]),
                     filtered_data=data.dropna(subset=[geom_column]),
                     timestamp_column=_get_timestap_column(data))

    info_box_default_text = 'Hover over a marker'
    info_box = widgets.HTML(info_box_default_text,
                            layout=Layout(margin='10px',
                                          overflow='scroll_hidden'))
    m.add_control(
        ipyleaflet.WidgetControl(widget=widgets.HBox(
            [info_box], layout=Layout(max_height='300px')),
                                 position='topright'))

    loading_wrapper = _loading_wrapper_factory(info_box, info_box_default_text)

    tweets_table = widgets.HTML(layout=widgets.Layout(
        overflow='scroll_hidden'))
    tweets_table_box = widgets.HBox([tweets_table],
                                    layout=Layout(max_height='500px',
                                                  overflow_y='auto',
                                                  max_width='900px'))
    tweets_table_cb = widgets.Checkbox(value=False)
    tweets_table_cb.observe(toggle_tweets_table_visibility,
                            type='change',
                            names=('value', ))
    tweets_box = widgets.VBox([tweets_table_cb, tweets_table_box])
    m.add_control(
        ipyleaflet.WidgetControl(widget=tweets_box, position='bottomleft'))

    time_slider = get_time_slider(app_state['full_data'])
    time_slider.observe(loading_wrapper(change_date_range),
                        type='change',
                        names=('value', ))
    time_slider.layout.margin, time_slider.description = '0px 5px 0px 5px', ''
    ts_plot = _get_ts_count_plot(data, app_state['filtered_data'],
                                 app_state['timestamp_column'])
    time_slider_box = widgets.VBox([ts_plot, time_slider])
    m.add_control(
        ipyleaflet.WidgetControl(widget=time_slider_box, position='topleft'))

    marker_clusters = get_marker_cluster(
        app_state['filtered_data'],
        geom_column,
        title_columns=title_columns,
        info_box=info_box,
        timestamp_column=app_state['timestamp_column'])
    app_state['markers'] = marker_clusters.markers

    heatmap_locations = list(app_state['filtered_data'][geom_column].apply(
        _wkb_hex_to_point).values)
    heatmap = ipyleaflet.Heatmap(name='Heatmap',
                                 min_opacity=.1,
                                 blur=20,
                                 radius=20,
                                 max_zoom=12,
                                 locations=heatmap_locations)
    m.add_layer(heatmap)
    m.add_layer(marker_clusters)

    change_date_range(dict(new=time_slider.value))
    m.add_control(ipyleaflet.LayersControl())
    m.add_control(ipyleaflet.FullScreenControl())
    m.observe(update_range)

    display(m)
def plot_geo_shapes_vis(data, nuts_shapes, nuts_ids_columns, color_column,
                        timestamp_column):
    def plot_cbar(name, logarithmic=False):
        vmin, vmax = app_state['vmin'], app_state['vmax']
        if vmin == vmax or any(pd.isna([vmin, vmax])):
            return
        fig, ax = plt.subplots(figsize=(.3, 10))
        norm = matplotlib.colors.LogNorm(
            vmin, vmax) if logarithmic else matplotlib.colors.Normalize(
                vmin, vmax)
        cbar = matplotlib.colorbar.ColorbarBase(ax,
                                                cmap=plt.get_cmap(name),
                                                norm=norm,
                                                orientation='vertical')
        return cbar

    def change_date_range(change):
        data = _date_filter(app_state['data'],
                            change['new'],
                            timestamp_column=timestamp_column).dropna(
                                subset=nuts_ids_columns, how='all')
        merged_dfs = [
            merge_df(data=data,
                     nuts_shapes=nuts_shapes,
                     nuts_ids_column=nuts_ids_column,
                     color_column=color_column,
                     level=level_selector.value,
                     levels=app_state['nuts_levels'])
            for nuts_ids_column in nuts_ids_columns
        ]
        app_state['vmax'] = np.max(
            [df[color_column].max() for df in merged_dfs])
        interactive_output(
            plot_cbar, dict(name=cmap_selector, logarithmic=logarithmic_cbox))

        m.layers = [l for l in m.layers if type(l) != ipyleaflet.LayerGroup]
        for merged_df, nuts_ids_column in zip(merged_dfs, nuts_ids_columns):
            table_columns = [
                '_timestamp', 'text_translated', 'num_persons', 'mode',
                *[col for col in nuts_ids_columns if col != nuts_ids_column]
            ]
            layer = get_shapes_heatmap(data=merged_df,
                                       nuts_ids_column=nuts_ids_column,
                                       color_column=color_column,
                                       info_widget_html=info_widget,
                                       vmin=app_state['vmin'],
                                       vmax=app_state['vmax'],
                                       full_data=app_state['full_data'],
                                       time_hist=time_hist,
                                       date_limits=change['new'],
                                       tweets_table=tweets_table,
                                       cmap=app_state['cmap'],
                                       table_columns=table_columns,
                                       logarithmic=app_state['logarithmic'])
            m.add_layer(layer)

        if 'full_groups' not in app_state:
            app_state['full_groups'] = [
                l.layers for l in m.layers if type(l) is ipyleaflet.LayerGroup
            ]

        cbar_widget.children = [
            interactive_output(
                plot_cbar,
                dict(name=cmap_selector, logarithmic=logarithmic_cbox))
        ]

    def change_level_layers(change={}):
        def change_layers(layer_group: ipyleaflet.LayerGroup,
                          all_layers: list):
            new_layers = [
                l for l in all_layers if l.data['features'][0]['properties']
                ['LEVL_CODE'] == app_state['level']
            ]
            layer_group.layers = new_layers if app_state[
                'level'] != 'all' else all_layers

        layer_groups = [
            l for l in m.layers if type(l) is ipyleaflet.LayerGroup
        ]
        if 'new' in change:
            app_state['level'] = change['new']
        for layer_group, full_group in zip(layer_groups,
                                           app_state['full_groups']):
            change_layers(layer_group, full_group)

    def change_colormap():
        cmap, logarithmic = app_state['cmap'], app_state['logarithmic']

        def update_layer(l):
            val = l.data['features'][0]['properties'][color_column]
            color = get_color(val,
                              cmap=cmap,
                              vmin=app_state['vmin'],
                              vmax=app_state['vmax'],
                              logarithmic=logarithmic)
            l.style.update({'fillColor': color, 'color': color})
            l.hover_style.update({'fillColor': color, 'color': color})
            new_layer = ipyleaflet.GeoJSON(data=l.data,
                                           style=l.style,
                                           hover_style=l.hover_style)
            new_layer._hover_callbacks = l._hover_callbacks
            new_layer._click_callbacks = l._click_callbacks
            return new_layer

        app_state['full_groups'] = [[update_layer(l) for l in layers]
                                    for layers in app_state['full_groups']]

        change_level_layers()

    def change_colormap_name(change):
        app_state['cmap'] = change['new']
        change_colormap()

    def change_colormap_log(change):
        app_state['logarithmic'] = change['new']
        change_colormap()

    def add_widget(widget, pos, margin='0px 0px 0px 0px'):
        widget.layout.margin = margin
        widget_control = ipyleaflet.WidgetControl(widget=widget, position=pos)
        m.add_control(widget_control)

    def on_zoom(change, offset=-5):
        if m.zoom != app_state['zoom']:
            app_state['zoom'] = m.zoom
            if level_on_zoom.value:
                min_level, max_level = np.min(
                    app_state['nuts_levels']), np.max(app_state['nuts_levels'])
                level = min(max_level, max(min_level, m.zoom + offset))
                app_state['level'] = level
                level_selector.value = level

    app_state = dict(zoom=4,
                     data=data.dropna(subset=nuts_ids_columns, how='all'),
                     cmap='viridis',
                     logarithmic=False,
                     vmin=1,
                     vmax=1,
                     full_data=data.copy(),
                     level='all',
                     nuts_levels=sorted(nuts_shapes['LEVL_CODE'].unique()))
    m = ipyleaflet.Map(center=(51, 10),
                       zoom=app_state['zoom'],
                       scroll_wheel_zoom=True,
                       zoom_control=False)
    m.layout.height = '900px'

    info_widget_default_text = 'Hover over a Region<br>Click it to see tweets'
    info_widget = widgets.HTML(info_widget_default_text)
    add_widget(info_widget, pos='topright', margin='0px 5px 0px 5px')

    loading_wrapper = _loading_wrapper_factory(info_widget,
                                               info_widget_default_text)

    time_hist = widgets.HBox([])
    add_widget(time_hist, pos='bottomleft')

    tweets_table = widgets.HTML(layout=widgets.Layout(
        overflow='scroll_hidden'))
    tweets_box = widgets.HBox([tweets_table],
                              layout=Layout(max_height='400px',
                                            overflow_y='auto',
                                            max_width='900px'))
    add_widget(tweets_box, pos='bottomleft')

    time_slider = get_time_slider(app_state['data'])
    time_slider.observe(loading_wrapper(change_date_range),
                        type='change',
                        names=('value', ))
    add_widget(time_slider, 'topleft', margin='0px 5px 0px 5px')

    level_selector = widgets.Dropdown(
        options=['all', *app_state['nuts_levels']],
        description='NUTS levels',
        layout=Layout(max_width='180px'))
    level_selector.observe(handler=loading_wrapper(change_level_layers),
                           type='change',
                           names=('value', ))
    level_on_zoom = widgets.Checkbox(value=True,
                                     description='with zoom',
                                     layout=Layout(max_width='180px'))
    level_control = widgets.VBox([level_selector, level_on_zoom])

    cmap_selector = widgets.Dropdown(
        options=['viridis', 'inferno', 'magma', 'winter', 'cool'],
        description='colormap',
        layout=Layout(max_width='180px'))
    logarithmic_cbox = widgets.Checkbox(description='logarithmic',
                                        layout=Layout(max_width='180px'))
    cmap_control = widgets.VBox([cmap_selector, logarithmic_cbox])
    cmap_selector.observe(handler=loading_wrapper(change_colormap_name),
                          type='change',
                          names=('value', ))
    logarithmic_cbox.observe(handler=loading_wrapper(change_colormap_log),
                             type='change',
                             names=('value', ))
    add_widget(widgets.HBox([level_control, cmap_control]),
               pos='topleft',
               margin='5px 5px 0px 5px')

    cbar_widget = widgets.HBox([
        interactive_output(
            plot_cbar, dict(name=cmap_selector, logarithmic=logarithmic_cbox))
    ])
    add_widget(cbar_widget, pos='bottomright')

    m.add_control(ipyleaflet.LayersControl())
    m.add_control(ipyleaflet.FullScreenControl())
    m.observe(handler=on_zoom)

    change_date_range(dict(new=time_slider.value))
    display(m)
Example #22
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())
Example #23
0
    def plot_maps_dataset_list(dataset_list,
                               client,
                               column='guid',
                               category=False,
                               basemap=True):
        """Create map window using dataset list. Should be okay whether it is shapefile or geotiff

            Args:
                dataset_list (list):  A list of dataset to be mapped.
                column (str): column name to be plot
                client (Client): pyincore service Client Object
                category (boolean): turn on/off category option
                basemap (boolean): turn on/off base map (e.g. openstreetmap)

            Returns:
                map(ipyleaflet.Map): ipyleaflet map obejct

        """
        layer_list = []
        bbox_all = [9999, 9999, -9999, -9999]

        for dataset in dataset_list:
            # check if dataset is shapefile or raster
            try:
                if dataset.metadata['format'].lower() == 'shapefile':
                    gdf = gpd.read_file(dataset.local_file_path)
                    geodata = GeoUtil.create_geodata_from_geodataframe(
                        gdf, dataset.metadata['title'])
                    bbox = gdf.total_bounds
                    bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

                    layer_list.append(geodata)
                elif dataset.metadata['format'].lower(
                ) == 'table' or dataset.metadata['format'] == 'csv':
                    # check source dataset
                    gdf = GeoUtil.join_table_dataset_with_source_dataset(
                        dataset, client)
                    if gdf is None:
                        print(dataset.metadata['title'] + "'s  data format" +
                              dataset.metadata['format'] +
                              " is not supported.")
                    else:
                        geodata = GeoUtil.create_geodata_from_geodataframe(
                            gdf, dataset.metadata['title'])
                        bbox = gdf.total_bounds
                        bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

                        layer_list.append(geodata)
                elif dataset.metadata['format'].lower() == 'raster' \
                        or dataset.metadata['format'].lower() == 'geotif' \
                        or dataset.metadata['format'].lower() == 'geotif':
                    input_path = dataset.get_file_path('tif')
                    bbox = GeoUtil.get_raster_boundary(input_path)
                    bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)
                    image_url = GeoUtil.create_data_img_url_from_geotiff_for_ipyleaflet(
                        input_path)
                    image = ImageOverlay(url=image_url,
                                         bounds=((bbox[1], bbox[0]),
                                                 (bbox[3], bbox[2])))
                    layer_list.append(image)
                else:
                    print(dataset.metadata['title'] + "'s  data format" +
                          dataset.metadata['format'] + " is not supported.")
            except Exception:
                print(
                    "There is a problem in dataset format for ' + dataset.metadata['title']  + '."
                )

        map = GeoUtil.get_ipyleaflet_map(bbox_all)

        for layer in layer_list:
            map.add_layer(layer)

        map.add_control(ipylft.LayersControl())

        return map
Example #24
0
    def get_wms_map(datasets: list,
                    wms_url=globals.INCORE_GEOSERVER_WMS_URL,
                    layer_check=True):
        """Get a map with WMS layers from list of datasets

        Args:
            datasets (list): list of pyincore Dataset objects
            wms_url (str): URL of WMS server
            layer_check (bool): boolean for checking the layer availability in wms server

        Returns:
            obj: A ipylfealet Map object

        """
        # TODO: how to add a style for each WMS layers (pre-defined styles on WMS server)
        wms_layers = []
        # (min_lat, min_lon, max_lat, max_lon)
        bbox_all = [9999, 9999, -9999, -9999]
        # the reason for checking this layer_check on/off is that
        # the process could take very long time based on the number of layers in geoserver.
        # the process could be relatively faster if there are not many layers in the geoserver
        # but the processing time could increase based upon the increase of the layers in the server
        # by putting on/off for this layer checking, it could make the process faster.
        if layer_check:
            wms = WebMapService(wms_url + "?", version='1.1.1')
        for dataset in datasets:
            wms_layer_name = 'incore:' + dataset.id
            # check availability of the wms layer
            # TODO in here, the question is the, should this error quit whole process
            # or just keep going and show the error message for only the layer with error
            # if it needs to throw an error and exit the process, use following code block
            # if layer_check:
            #     wms[dataset.id].boundingBox
            # else:
            #     raise KeyError(
            #         "Error: The layer " + str(dataset.id) + " does not exist in the wms server")
            # if it needs to keep going with showing all the layers, use following code block
            if layer_check:
                try:
                    wms[dataset.id].boundingBox
                except KeyError:
                    print("Error: The layer " + str(dataset.id) +
                          " does not exist in the wms server")
            wms_layer = ipylft.WMSLayer(url=wms_url,
                                        layers=wms_layer_name,
                                        format='image/png',
                                        transparent=True,
                                        name=dataset.metadata['title'])
            wms_layers.append(wms_layer)

            bbox = dataset.metadata['boundingBox']
            bbox_all = GeoUtil.merge_bbox(bbox_all, bbox)

        m = GeoUtil.get_ipyleaflet_map(bbox_all)

        for layer in wms_layers:
            m.add_layer(layer)

        m.add_control(ipylft.LayersControl())

        return m
Example #25
0
class pyccd_explorer(object):
    def __init__(self):
        measures.band_index1 = 4
        measures.band_index2 = 4
        measures.pyccd_flag = False
        measures.pyccd_flag2 = False
        measures.minv = 0
        measures.maxv = 6000
        measures.b1 = 'SWIR1'
        measures.b2 = 'NIR'
        measures.b3 = 'RED'

    # Starting variables
    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
    current_id = 0

    ylim = plots.make_range_slider([0, 4000], -10000, 10000, 500, 'YLim:')
    xlim = plots.make_range_slider([2000, 2018], 1984, 2019, 1, 'XLim:')

    ylim2 = plots.make_range_slider([0, 4000], -10000, 10000, 500, 'YLim:')
    xlim2 = plots.make_range_slider([2000, 2018], 1984, 2019, 1, 'XLim:')

    band_selector1 = plots.make_drop('SWIR1', band_list, 'Select band')
    band_selector2 = plots.make_drop('SWIR1', band_list, 'Select band')
    image_band_1 = plots.make_drop('RED', band_list, 'Red:')
    image_band_2 = plots.make_drop('GREEN', band_list, 'Green:')
    image_band_3 = plots.make_drop('BLUE', band_list, 'Blue:')

    # Checkbox
    color_check = plots.make_checkbox(False, 'Color DOY', False)

    stretch_min = plots.make_text_float(0, 0, 'Min:')
    stretch_max = plots.make_text_float(1450, 0, 'Max:')
    idBox = plots.make_text('0', '0', 'ID:')

    load_button = plots.make_button(False, 'Load', icon='')

    next_pt = plots.make_button(False, 'Next point', icon='')
    previous_pt = plots.make_button(False, 'Previous point', icon='')
    pyccd_button = plots.make_button(False, 'Run PyCCD 1', icon='')
    pyccd_button2 = plots.make_button(False, 'Run PyCCD 2', icon='')
    clear_layers = plots.make_button(False, 'Clear Map', icon='')

    # HTML
    pt_message = plots.make_html('Current ID: ')
    coord_message = plots.make_html('Lat, Lon: ')
    time_label = plots.make_html('')
    selected_label = plots.make_html('ID of selected point')
    hover_label = plots.make_html('Test Value')
    text_brush = plots.make_html('Selected year range:')
    kml_link = plots.make_html('KML:')
    error_label = plots.make_html('Load a point')

    # Plots

    # Scales
    # Dates
    lc1_x = plots.make_bq_scale('date', datetime.date(xlim.value[0], 2, 1),
                                datetime.date(xlim.value[1], 1, 1))
    lc1_x2 = plots.make_bq_scale('date', datetime.date(xlim.value[0], 2, 1),
                                 datetime.date(xlim.value[1], 1, 1))

    # DOY
    lc1_x3 = plots.make_bq_scale('linear', 0, 365)

    # Reflectance
    lc2_y = plots.make_bq_scale('linear', ylim.value[0], ylim.value[1])
    lc2_y2 = plots.make_bq_scale('linear', ylim.value[0], ylim.value[1])

    # plots
    lc2 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x,
        'y': lc2_y
    }, [1, 1], {
        'click': 'select',
        'hover': 'tooltip'
    }, {
        'opacity': 1.0,
        'fill': 'DarkOrange',
        'stroke': 'Red'
    }, {'opacity': 0.5},
                             display_legend=True,
                             labels=['Sample point'])

    lc3 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x2,
        'y': lc2_y2
    }, [1, 1], {
        'click': 'select',
        'hover': 'tooltip'
    }, {
        'opacity': 1.0,
        'fill': 'DarkOrange',
        'stroke': 'Red'
    }, {'opacity': 0.5},
                             display_legend=True,
                             labels=['Clicked point'])

    lc4 = plots.make_bq_plot('lines', [], [], {
        'x': lc1_x,
        'y': lc2_y
    }, [1, 1], {}, {}, {},
                             colors=['black'],
                             stroke_width=3)

    lc5 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x,
        'y': lc2_y
    }, [1, 1], {}, {}, {},
                             labels=['Model Endpoint'],
                             colors=['red'],
                             marker='triangle-up')

    lc6 = plots.make_bq_plot('lines', [], [], {
        'x': lc1_x2,
        'y': lc2_y2
    }, [1, 1], {}, {}, {},
                             colors=['black'],
                             stroke_width=3)

    lc7 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x2,
        'y': lc2_y2
    }, [1, 1], {}, {}, {},
                             labels=['Model Endpoint'],
                             colors=['red'],
                             marker='triangle-up')

    lc8 = plots.make_bq_plot('scatter', [], [], {
        'x': lc1_x3,
        'y': lc2_y
    }, [1, 1], {
        'click': 'select',
        'hover': 'tooltip'
    }, {
        'opacity': 1.0,
        'fill': 'DarkOrange',
        'stroke': 'Red'
    }, {'opacity': 0.5},
                             display_legend=True,
                             labels=['Sample point'])

    x_ax1 = plots.make_bq_axis('Date',
                               lc1_x,
                               num_ticks=6,
                               tick_format='%Y',
                               orientation='horizontal')
    x_ax2 = plots.make_bq_axis('Date',
                               lc1_x2,
                               num_ticks=6,
                               tick_format='%Y',
                               orientation='horizontal')
    x_ax3 = plots.make_bq_axis('DOY',
                               lc1_x3,
                               num_ticks=6,
                               orientation='horizontal')

    y_ay1 = plots.make_bq_axis('SWIR1', lc2_y, orientation='vertical')
    y_ay2 = plots.make_bq_axis('SWIR1', lc2_y2, orientation='vertical')

    # Figures
    fig = plots.make_bq_figure([lc2, lc4, lc5], [x_ax1, y_ay1], {
        'height': '300px',
        'width': '100%'
    }, 'Sample TS')
    fig2 = plots.make_bq_figure([lc3, lc6, lc7], [x_ax2, y_ay2], {
        'height': '300px',
        'width': '100%'
    }, 'Clicked TS')
    fig3 = plots.make_bq_figure([lc8], [x_ax3, y_ay1], {
        'height': '300px',
        'width': '100%'
    }, 'Clicked TS')

    # Functions

    def load_everything(sender):
        # Load the sample as a feature collection
        sample_path = measures.sampleWidget.value
        fc_df = utils.fc2dfgeo(sample_path)
        measures.fc_df, first_index = utils.check_id(fc_df)
        measures.current_id = first_index - 1
        measures.reset_everything()

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

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

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

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

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

    def advance(b):
        # Plot point in map
        measures.lc4.x = []
        measures.lc4.y = []
        measures.lc5.x = []
        measures.lc5.y = []
        measures.lc5.display_legend = False
        measures.pyccd_flag = False
        measures.current_id += 1
        measures.pt_message.value = "Point ID: {}".format(measures.current_id)
        measures.map_point()
        measures.get_ts()
        measures.plot_ts()

    def decrease(b):
        # Plot point in map
        measures.lc4.x = []
        measures.lc4.y = []
        measures.lc5.x = []
        measures.lc5.y = []
        measures.lc5.display_legend = False
        measures.pyccd_flag = False
        measures.current_id -= 1
        measures.pt_message.value = "Point ID: {}".format(measures.current_id)
        measures.map_point()
        measures.get_ts()
        measures.plot_ts()

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

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

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

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

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

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

    def clear_map(b):
        lft.clear_map(measures.m, streets=True)
        measures.map_point()

    def add_image(self, target):
        m = measures.m
        df = measures.sample_df
        current_band = measures.band_list[measures.band_index1]
        sample_col = measures.sample_col
        stretch_min = measures.stretch_min
        stretch_max = measures.stretch_max
        b1 = measures.b1
        b2 = measures.b2
        b3 = measures.b3
        lft.click_event(target, m, current_band, df, sample_col, stretch_min,
                        stretch_max, b1, b2, b3)

    def add_image2(self, target):
        m = measures.m
        df = measures.click_df
        current_band = measures.band_list[measures.band_index2]
        sample_col = measures.click_col
        stretch_min = measures.minv
        stretch_max = measures.maxv
        b1 = measures.b1
        b2 = measures.b2
        b3 = measures.b3
        lft.click_event(target, m, current_band, df, sample_col, stretch_min,
                        stretch_max, b1, b2, b3)

    def do_draw(self, action, geo_json):
        current_band = measures.band_list[measures.band_index2]
        year_range = measures.year_range
        doy_range = measures.doy_range
        _col, _df = utils.handle_draw(action, geo_json, current_band,
                                      year_range, doy_range)
        measures.click_df = _df
        measures.click_col = _col
        measures.lc6.x = []
        measures.lc6.y = []
        measures.lc7.x = []
        measures.lc7.y = []

        measures.lc3.x = measures.click_df['datetime']
        measures.lc3.y = measures.click_df[current_band]

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

    def map_point():
        zoom = 12
        kml = measures.kml_link
        name = 'Sample point'
        data = measures.fc_df['geometry'][measures.current_id]
        measures.coord_message.value = "Lat, Lon: {}".format(
            data['coordinates'])
        lft.add_map_point(data, zoom, measures.m, kml, name)

    def get_ts():

        measures.error_label.value = 'Loading'
        coords = measures.fc_df['geometry'][measures.current_id]['coordinates']
        year_range = measures.year_range
        doy_range = measures.doy_range

        measures.current_band = measures.band_list[measures.band_index1]
        measures.sample_col = utils.get_full_collection(
            coords, year_range, doy_range)
        measures.sample_df = utils.get_df_full(measures.sample_col,
                                               coords).dropna()
        measures.error_label.value = 'Point Loaded!'

    def plot_ts():
        df = measures.sample_df

        if measures.color_check.value == True:
            color_marks = list(measures.sample_df['color'].values)
        else:
            color_marks = list(measures.point_color)

        band = measures.band_list[measures.band_index1]

        plots.add_plot_ts(df, measures.lc2, band, color_marks)

        plots.add_plot_doy(df, measures.lc8, band, color_marks)

        if measures.pyccd_flag:
            measures.do_pyccd(0)

    def do_pyccd(b):
        pyccd_flag = measures.pyccd_flag
        display_legend = measures.lc5.display_legend
        dfPyCCD = measures.sample_df
        band_index = measures.band_index1
        results = ccd_tools.run_pyccd(pyccd_flag, display_legend, dfPyCCD,
                                      band_index)

        ccd_tools.plot_pyccd(dfPyCCD, results, band_index, (0, 4000),
                             measures.lc4, measures.lc5)

    def do_pyccd2(b):
        pyccd_flag = measures.pyccd_flag2
        display_legend = measures.lc7.display_legend
        dfPyCCD = measures.click_df
        band_index = measures.band_index1
        results = ccd_tools.run_pyccd(pyccd_flag, display_legend, dfPyCCD,
                                      band_index)

        ccd_tools.plot_pyccd(dfPyCCD, results, band_index, (0, 4000),
                             measures.lc6, measures.lc7)

    # Load database and sample
    load_button.on_click(load_everything)

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

    zoom = 5
    layout = widgets.Layout(width='50%')
    center = (3.3890701010382958, -67.32297252983098)
    m = lft.make_map(zoom, layout, center)
    m = lft.add_basemap(m, ipyleaflet.basemaps.Esri.WorldImagery)

    # Display controls
    ylim.observe(change_yaxis)
    xlim.observe(change_xaxis)
    ylim2.observe(change_yaxis2)
    xlim2.observe(change_xaxis2)
    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')

    # .samples
    next_pt.on_click(advance)
    previous_pt.on_click(decrease)

    # PyCCD
    pyccd_button.on_click(do_pyccd)
    pyccd_button2.on_click(do_pyccd2)

    # Plots
    lc2.on_element_click(add_image)
    lc2.tooltip = hover_label
    lc2.on_hover(hover_event)

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

    idBox.on_submit(go_to_sample)

    # Mapping
    dc.on_draw(do_draw)
    m.add_control(dc)
    m.add_control(ipyleaflet.LayersControl())
Example #26
0
    def controls_on_Map(self):
        control_layer = ipyleaflet.LayersControl(position='topright')
        self.m01.add_control(control_layer)

        control_fullscreen = ipyleaflet.FullScreenControl()
        self.m01.add_control(control_fullscreen)

        self.control_draw = ipyleaflet.DrawControl()
        self.m01.add_control(self.control_draw)

        control_scale = ipyleaflet.ScaleControl(position='bottomleft')
        self.m01.add_control(control_scale)

        slider_heatmap_radius = ipywidgets.IntSlider(description='Radius',
                                                     min=1,
                                                     max=50,
                                                     value=15)
        ipywidgets.jslink((slider_heatmap_radius, 'value'),
                          (self.heatmap_all, 'radius'))
        widget_control01 = ipyleaflet.WidgetControl(
            widget=slider_heatmap_radius, position='bottomright')
        self.m01.add_control(widget_control01)

        self.date_slider = ipywidgets.SelectionSlider(options=pd.date_range(
            start='2000-01-01', end='2020-01-01', freq='M').to_numpy())
        self.date_slider.observe(self.date_location, names='value')
        ipywidgets.jslink((slider_heatmap_radius, 'value'),
                          (self.heatmap_byLast, 'radius'))
        widget_control02 = ipyleaflet.WidgetControl(widget=self.date_slider,
                                                    position='topright')
        self.m01.add_control(widget_control02)

        self.control_selectDownload = ipywidgets.Dropdown(
            options=['Watershed', 'All', 'byDate'],
            value=None,
            description='Select type:')
        self.control_selectDownload.observe(self.dropdown_shapefile,
                                            names='value')
        self.control_selectDownload.observe(self.shapefile_buttom,
                                            names='value')

        box_layout = ipywidgets.Layout(display='flex',
                                       flex_flow='column',
                                       align_items='stretch',
                                       width='100%')

        self.control_pathDownload = ipywidgets.Text(
            placeholder='Write your PATH to Download HERE.')
        vbox01 = ipywidgets.VBox(
            [self.control_selectDownload, self.control_pathDownload])
        self.control_buttonDownload = ipywidgets.Button(description='Download')
        self.control_loadingDownload = ipywidgets.FloatProgress(min=0,
                                                                max=1,
                                                                value=0)

        self.control_choiceDownload = ipywidgets.RadioButtons(
            options=['Rain', 'Flow'])
        hbox01 = ipywidgets.HBox(
            [self.control_choiceDownload, self.control_buttonDownload],
            layout=box_layout)

        vbox02 = ipywidgets.VBox(
            [vbox01, hbox01, self.control_loadingDownload], layout=box_layout)

        widget_control03 = ipyleaflet.WidgetControl(widget=vbox02,
                                                    position='bottomright')
        self.m01.add_control(widget_control03)
        # control_progressDownload = ipywidgets.FloatProgress()
        self.control_shapefileButtom = ipywidgets.Button(
            description='Visualizar')