Beispiel #1
0
def slider(aoi, pid, chipsize=512, extend=512, tms=['Google']):

    workdir = config.get_value(['paths', 'temp'])
    path = f'{workdir}/{aoi}/{pid}/'
    bg_path = f'{path}/backgrounds/'

    for t in tms:
        if not os.path.isfile(f'{bg_path}{t.lower()}.tif'):
            bg.by_pid(aoi, pid, chipsize, extend, t, True)

    with open(f'{path}info.json', "r") as f:
        json_data = json.load(f)

    def overlay_parcel(img, geom):
        patche = [
            PolygonPatch(feature,
                         edgecolor="yellow",
                         facecolor="none",
                         linewidth=2) for feature in geom['geom']
        ]
        return patche

    with rasterio.open(f'{bg_path}{tms[0].lower()}.tif') as img:
        img_epsg = img.crs.to_epsg()
        geom = spatial_utils.transform_geometry(json_data, img_epsg)
        patches = overlay_parcel(img, geom)

    selection = SelectionSlider(options=tms,
                                value=tms[0],
                                disabled=False,
                                continuous_update=False,
                                orientation='horizontal',
                                readout=True)
    output = Output()

    fig, ax = plt.subplots(figsize=(10, 10))
    with output:
        with rasterio.open(f'{bg_path}{selection.value.lower()}.tif') as img:
            for patch in patches:
                ax.add_patch(copy(patch))
            show(img, ax=ax)
        plt.show()

    def on_value_change(change):
        with output:
            output.clear_output()
            fig, ax = plt.subplots(figsize=(10, 10))
            with rasterio.open(
                    f'{bg_path}{selection.value.lower()}.tif') as im:
                for patch in patches:
                    ax.add_patch(copy(patch))
                show(im, ax=ax)
            plt.show()

    selection.observe(on_value_change, names='value')
    return VBox([selection, output])
Beispiel #2
0
 def overlay_parcel(img, geom):
     with open(file_info, 'r') as f:
         info_data = json.loads(f.read())
     img_epsg = img.crs.to_epsg()
     geo_json = spatial_utils.transform_geometry(info_data, img_epsg)
     patche = [
         PolygonPatch(feature,
                      edgecolor="yellow",
                      facecolor="none",
                      linewidth=2) for feature in [geo_json['geom'][0]]
     ]
     return patche[0]
Beispiel #3
0
def by_location(aoi,
                year,
                lon,
                lat,
                dates,
                band,
                chipsize,
                columns=5,
                quiet=True):
    from cbm.datas import api
    """Plot chip image with parcel polygon overlay.

    Examples:
        import cbm
        cbm.get.chip_images.by_pid(aoi, pid, start_date, end_date,
                                    band, chipsize)

    Arguments:
        aoi, the area of interest and year e.g.: es2020, cat2020 (str)
        pid, the parcel id (int).
        dates, the date of the image (str) or start_date and end_date (list)
            '2019-06-01' or ['2019-06-01', '2019-06-30']
        band, 3 Sentinel-2 band names. One of [‘B02’, ‘B03’, ‘B04’, ‘B08’]
            (10 m bands) or [‘B05’, ‘B06’, ‘B07’, ‘B8A’, ‘B11’, ‘B12’]
            (20 m bands). 10m and 20m bands can be combined.
            The first band determines the resolution in the output
            composite. Defaults to B08_B04_B03.
        chipsize, size of the chip in pixels (int).
        columns, (int)
    """

    if type(dates) is list:
        start_date, end_date = dates[0], dates[1]
    else:
        start_date, end_date = dates, dates

    json_data = json.loads(api.parcel_by_loc(aoi, lon, lat, True))
    if type(json_data['ogc_fid']) is list:
        pid = json_data['ogc_fid'][0]
    else:
        pid = json_data['ogc_fid']

    workdir = normpath(join(config.get_value(['paths', 'temp']), aoi,
                            str(pid)))
    chip_imgs.by_pid(aoi, pid, start_date, end_date, band, chipsize, quiet)

    chips_dir = normpath(join(workdir, 'chip_images'))
    if type(dates) is list:
        chips = normpath(join(chips_dir, f"*{band}.tif"))
    else:
        chips = normpath(
            join(chips_dir, f"*{start_date.replace('-', '')}*{band}.tif"))

    chips_list = glob.glob(chips)

    if len(chips_list) > 0:
        if len(chips_list) < columns:
            columns = len(chips_list)

        with rasterio.open(chips_list[0]) as img:
            img_epsg = img.crs.to_epsg()
            geom = spatial_utils.transform_geometry(json_data, img_epsg)
            patches = overlay_parcel(img, geom)

        if not quiet:
            for chip in chips_list:
                print(chip)

        rows = int(
            len(chips_list) // columns + (len(chips_list) % columns > 0))
        fig = plt.figure(figsize=(30, 10 * rows))
        grid = ImageGrid(
            fig,
            111,  # similar to subplot(111)
            nrows_ncols=(rows, columns),  # creates grid of axes
            axes_pad=0.4,  # pad between axes in inch.
        )

        for ax, t in zip(grid, chips_list):
            with rasterio.open(t) as img:
                for patch in patches:
                    ax.add_patch(copy(patch))
                show(img, ax=ax, cmap=data_options.cmaps(band))
                ax.set_title(t.split('_')[-1].split('.')[0], fontsize=20)

        if len(chips_list) > columns:
            for ax in grid[-((columns * rows - len(chips_list))):]:
                ax.remove()

        plt.show()
    else:
        print("! No images to show.")
Beispiel #4
0
def by_location(aoi,
                year,
                lon,
                lat,
                chipsize=512,
                extend=512,
                tms=['google'],
                ptype=None,
                columns=4,
                debug=False):
    """Show the background image with parcels polygon overlay by selected
    parcel id. This function will get an image from the center of the polygon.

    Examples:
        from cbm.view import background
        background.by_location(aoi, year, lon, lat, 512, 512, 'Google',
                                True, True)

    Arguments:
        aoi, the area of interest (str)
        year, the year of parcels table
        lon, lat, longitude and latitude in decimal degrees (float).
        chipsize, size of the chip in pixels (int).
        extend, size of the chip in meters  (float).
        tms, tile map server Google or Bing (str).
        columns, the number of columns of the grid
        debug, print or not procedure information (Boolean).
    """
    if type(tms) is str:
        tms = [tms]

    try:
        parcel = parcel_info.by_location(aoi, year, lon, lat, ptype, True,
                                         False, debug)
        if type(parcel['pid']) is list:
            pid = parcel['pid'][0]
        else:
            pid = parcel['pid']

        workdir = normpath(
            join(config.get_value(['paths', 'temp']), aoi, str(year),
                 str(pid)))
        parcel_id = True
    except Exception as err:
        workdir = normpath(
            join(config.get_value(['paths', 'temp']), aoi, str(year),
                 f'_{lon}_{lat}'.replace('.', '_')))
        parcel_id = False
        if debug:
            print("No parcel information found.", err)

    if len(tms) < columns:
        columns = len(tms)

    bg_path = normpath(join(workdir, 'backgrounds'))

    same_args = check_args(bg_path, chipsize, extend, debug)

    if debug:
        print('path: ', bg_path)
        print('same args: ', same_args)
        print('aoi-year-lon-lat-chipsize-extend-tms-ptype-columns-debug')
        print(aoi, year, lon, lat, chipsize, extend, tms, ptype, columns,
              debug)

    for t in tms:
        if not isfile(normpath(join(bg_path,
                                    f'{t.lower()}.tif'))) or not same_args:
            if parcel_id:
                get_bg.by_pid(aoi, year, pid, chipsize, extend, t, ptype, True,
                              debug)
            else:
                get_bg.by_location(aoi, year, lon, lat, chipsize, extend, t,
                                   ptype, True, debug)

    if parcel_id:
        with open(normpath(join(workdir, 'info.json')), 'r') as f:
            parcel = json.load(f)

        with rasterio.open(normpath(join(bg_path,
                                         f'{tms[0].lower()}.tif'))) as img:
            img_epsg = img.crs.to_epsg()
            geom = spatial_utils.transform_geometry(parcel, img_epsg)
            patches = overlay_parcel(img, geom)

    rows = int(len(tms) // columns + (len(tms) % columns > 0))
    fig = plt.figure(figsize=(30, 10 * rows))
    grid = ImageGrid(
        fig,
        111,  # similar to subplot(111)
        nrows_ncols=(rows, columns),  # creates grid of axes
        axes_pad=0.4,  # pad between axes in inch.
    )

    def overlay_title(img, date):
        date_text = ax.text(
            img.bounds.left + ((img.bounds.right - img.bounds.left) / 9),
            img.bounds.bottom + ((img.bounds.top - img.bounds.bottom) / 1.15),
            date,
            color='yellow',
            weight='bold',
            size=32 - columns * 2,
            bbox=dict(boxstyle="round", ec='yellow', fc='black', alpha=0.2))
        return date_text

    for ax, t in zip(grid, tms):
        with rasterio.open(normpath(join(bg_path, f'{t.lower()}.tif'))) as img:
            if parcel_id:
                for patch in patches:
                    ax.add_patch(copy(patch))
            overlay_title(img, t)
            show(img, ax=ax)


#            ax.xaxis.set_major_locator(ticker.MultipleLocator(200))

    if len(tms) > columns and columns * rows > len(tms):
        for ax in grid[-((columns * rows - len(tms))):]:
            ax.remove()

    plt.show()
Beispiel #5
0
    def show_m():

        multipoly = []
        multycent = []
        geom = spatial_utils.transform_geometry(info_data)
        poly = geom['geom'][0]['coordinates'][0]
        #     poly = spatial_utils.swap_xy(geom['coordinates'][0])[0]
        multipoly.append(poly)
        centroid = spatial_utils.centroid(poly)
        multycent.append(centroid)

        centroid = spatial_utils.centroid(multycent)
        m = Map(center=centroid,
                zoom=16,
                basemap=basemaps.OpenStreetMap.Mapnik)

        polygon = Polygon(locations=multipoly,
                          name='Parcel polygon',
                          color="yellow",
                          fill_color=None)

        m.add_layer(polygon)
        basemap2 = basemap_to_tiles(basemaps.Esri.WorldImagery)

        poly_text = HTML()
        poly_text.value = f"""Parcel ID: {pid}<br>
                                    Crop name: {crop_name}<br>
                                    Area: {area:.2f} sqm<br>
                                    Coordinates: {centroid}
                                    """
        poly_text.placeholder = "HTML"
        poly_text.description = ""

        # Popup with a given location on the map:
        poly_popup = Popup(child=poly_text,
                           close_button=False,
                           auto_close=False,
                           close_on_escape_key=False)
        m.add_layer(poly_popup)

        polygon.popup = poly_popup  # Popup associated to a layer

        # Layers control
        show_poly = Checkbox(value=True,
                             description='Polygon',
                             indent=False,
                             layout=Layout(width='140px'))
        show_sat = Checkbox(value=False,
                            description='High res basemap',
                            indent=False,
                            layout=Layout(width='140px'))

        def polygon_changed(b):
            try:
                if show_poly.value is True:
                    m.add_layer(polygon)
                else:
                    m.remove_layer(polygon)
            except Exception:
                pass

        show_poly.observe(polygon_changed)

        def show_sat_changed(b):
            try:
                if show_sat.value is True:
                    m.add_layer(basemap2)
                else:
                    m.remove_layer(basemap2)
            except Exception:
                pass

        show_sat.observe(show_sat_changed)

        try:
            df = raster_utils.create_df(ci_path, pid, ci_band.value)

            geotiff = normpath(
                join(ci_path, f"{df['imgs'][0]}.{ci_band.value[0]}.tif"))
            bounds = raster_utils.bounds(geotiff)

            images = {}
            for i, row in df.iterrows():
                str_date = str(row['date'].date()).replace('-', '')
                img_tc = normpath(
                    join(ci_path,
                         f"{('').join(ci_band.value)}_{str_date}.png"))

                # Create false color image if it does not exist
                # Merge bands (images path, export image path, bands list)
                if not isfile(img_tc):
                    imgs_path = normpath(join(ci_path, row['imgs']))
                    raster_utils.merge_bands(imgs_path, img_tc, ci_band.value)

                if bool(config.get_value(['set', 'jupyterlab'])) is True:
                    jlab_path = os.getcwd().replace(os.path.expanduser("~"),
                                                    '')
                    image_path = normpath(join(f'files{jlab_path}', img_tc))
                else:
                    image_path = img_tc

                # print('image_path: ', image_path)
                images[i] = ImageOverlay(url=image_path,
                                         name=str_date,
                                         bounds=(bounds))

            # Time slider
            slider = IntSlider(value=1,
                               min=1,
                               max=len(images),
                               step=1,
                               description=str(df['date'][0].date()),
                               continuous_update=False,
                               orientation='horizontal',
                               readout=True,
                               readout_format='d')
            show_chip = Checkbox(value=True,
                                 description='Chip image',
                                 indent=False,
                                 layout=Layout(width='140px'))

            def on_ci_band_change(change):
                pass

            ci_band.observe(on_ci_band_change, 'value')

            def show_chip_changed(b):
                try:
                    if show_chip.value is True:
                        m.add_layer(images[slider.value - 1])
                    else:
                        m.remove_layer(images[slider.value - 1])
                except Exception:
                    pass

            show_chip.observe(show_chip_changed)

            # Slider control
            play = Play(
                value=1,
                min=1,
                max=len(images),
                step=1,
                interval=1000,
                description="Press play",
            )

            def slider_changed(b):
                if show_chip.value is True:
                    try:
                        m.substitute_layer(images[b['old'] - 1],
                                           images[b['new'] - 1])
                    except Exception:
                        pass
                    slider.description = str(df['date'][slider.value -
                                                        1].date())

            slider.observe(slider_changed)
            jslink((play, 'value'), (slider, 'value'))
            time_box = HBox([slider, play])
            time_control = WidgetControl(widget=time_box,
                                         position='bottomleft')
            m.add_control(time_control)
            m.add_layer(images[0])

            map_options = VBox([show_poly, show_chip, show_sat])
        except Exception as err:
            map_options = VBox([show_poly, show_sat])
            print(err)

        layers_control = WidgetControl(widget=map_options,
                                       position='topright',
                                       max_width=150)
        m.add_control(layers_control)
        return m
Beispiel #6
0
def by_pid(aoi,
           year,
           pid,
           chipsize=512,
           extend=512,
           tms=['Google'],
           ptype=None,
           columns=4,
           debug=False):
    """Show the background image with parcels polygon overlay by selected
    parcel id. This function will get an image from the center of the polygon.

    Examples:
        from cbm.view import background
        background.by_location(aoi, year, lon, lat, 512, 512, 'Google',
                                True, True)

    Arguments:
        aoi, the area of interest (str)
        year, the year of parcels table
        pid, the parcel id (str).
        chipsize, size of the chip in pixels (int).
        extend, size of the chip in meters  (float).
        tms, tile map server Google or Bing (str).
        columns, the number of columns of the grid
        debug, print or not procedure information (Boolean).
    """

    if type(tms) is str:
        tms = [tms]
    if len(tms) < columns:
        columns = len(tms)

    workdir = normpath(
        join(config.get_value(['paths', 'temp']), aoi, str(year), str(pid)))
    bg_path = normpath(join(workdir, 'backgrounds'))

    same_args = check_args(bg_path, chipsize, extend)

    if debug:
        print('path: ', bg_path)
        print('same args: ', same_args)
        print('aoi, year, pid, chipsize, extend, tms, columns, debug')
        print(aoi, year, pid, chipsize, extend, tms, columns, debug)

    for t in tms:
        if not isfile(normpath(join(
                bg_path, f'{t.lower()}.tif'))) or same_args is False:
            get_bg.by_pid(aoi, year, pid, chipsize, extend, t, ptype, True,
                          debug)

    with open(normpath(join(workdir, 'info.json')), 'r') as f:
        parcel = json.load(f)

    with rasterio.open(normpath(join(bg_path,
                                     f'{tms[0].lower()}.tif'))) as img:
        img_epsg = img.crs.to_epsg()
        geom = spatial_utils.transform_geometry(parcel, img_epsg)
        patches = overlay_parcel(img, geom)

    rows = int(len(tms) // columns + (len(tms) % columns > 0))
    fig = plt.figure(figsize=(30, 10 * rows))
    grid = ImageGrid(
        fig,
        111,  # similar to subplot(111)
        nrows_ncols=(rows, columns),  # creates grid of axes
        axes_pad=0.4)  # pad between axes in inch.

    for ax, t in zip(grid, tms):
        with rasterio.open(normpath(join(bg_path, f'{t.lower()}.tif'))) as img:
            for patch in patches:
                ax.add_patch(copy(patch))


#             ax.xaxis.set_major_locator(ticker.MultipleLocator(200))
            show(img, ax=ax)
            ax.set_title(t, fontsize=20)

    if len(tms) > columns and columns * rows > len(tms):
        for ax in grid[-((columns * rows - len(tms))):]:
            ax.remove()

    plt.show()
Beispiel #7
0
def by_pid(aoi, year, pid, ptype=None, tms='osm', debug=False):
    """Show parcel information with an image with polygon overlay by selected
    parcel id. This function will get an image from the center of the polygon.

    Examples:
        from cbm.show import parcel_info
        parcel_info.by_id(aoi, year, pid)

    Arguments:
        aoi, the area of interest (str)
        year, the year of parcels table
        pid, the parcel id (str).
        ptype, parcel type
        debug, print or not procedure information (Boolean).
    """

    workdir = normpath(
        join(config.get_value(['paths', 'temp']), aoi, str(year), str(pid)))
    bg_path = normpath(join(workdir, 'backgrounds'))

    if debug:
        print('path: ', bg_path)
        print('aoi, year, pid, debug')
        print(aoi, year, pid, debug)

    file_info = normpath(join(workdir, 'info.json'))
    if not isfile(file_info):
        parcel_info.by_pid(aoi, str(year), str(pid), ptype, True)
    with open(normpath(join(workdir, 'info.json')), 'r') as f:
        parcel = json.load(f)

    plt.rcParams['font.size'] = 14
    plt.figure(figsize=(10, 3))
    gs = gridspec.GridSpec(1, 2)
    ax1 = plt.subplot(gs[0, 0])
    ax2 = plt.subplot(gs[0, 1])

    try:
        if not isfile(normpath(join(bg_path, f'{tms}.tif'))):
            get_bg.by_pid(aoi, year, pid, 256, 1024, tms, ptype, True, debug)
        elif getsize(normpath(join(bg_path, f'osm.tif'))) < 1000:
            get_bg.by_pid(aoi, year, pid, 256, 1024, tms, ptype, True, debug)
        with rasterio.open(normpath(join(bg_path, f'{tms}.tif'))) as img:
            img_epsg = img.crs.to_epsg()
            geom = spatial_utils.transform_geometry(parcel, img_epsg)
            patches = overlay_parcel(geom)
            for patch in patches:
                ax2.add_patch(copy(patch))
            show(img, ax=ax2)
    except Exception as err:
        print("Could not get image. ", err)

    text = [
        f"AOI: {aoi}", f"Year: {year}", f"Parcel ID: {pid}",
        f"Crop type: {parcel['cropname'][0]}",
        f"Crop type code: {parcel['cropcode'][0]}",
        f"Area: {parcel['area'][0]} sqm",
        f"Centroid (Lat/Lon): {parcel['clat'][0]:.6f}, {parcel['clon'][0]:.6f}",
        f"Geometry SRID: {parcel['srid'][0]}"
    ]
    first_line = 0.9
    for t in text:
        ax1.text(0, first_line, t)
        first_line -= 0.12

    ax1.axis('off')
    ax2.axis('off')
    plt.show()