Esempio n. 1
0
    def _from_vector(self, vector_json):
        """set the object output from a vector json"""

        if not (vector_json['pathname']):
            raise Exception('Please select a file.')

        if vector_json['column'] != 'ALL':
            if vector_json['value'] is None:
                raise Exception('Please select a value.')

        # cast the pathname to pathlib Path
        vector_file = Path(vector_json['pathname'])

        # create the gdf
        self.gdf = gpd.read_file(vector_file).to_crs("EPSG:4326")

        # set the name using the file stem
        self.name = vector_file.stem

        # filter it if necessary
        if vector_json['value']:
            self.gdf = self.gdf[self.gdf[vector_json['column']] ==
                                vector_json['value']]
            self.name = f"{self.name}_{vector_json['column']}_{vector_json['value']}"

        if self.ee:
            # transform the gdf to ee.FeatureCollection
            self.feature_collection = geemap.geojson_to_ee(
                self.gdf.__geo_interface__)

            # export as a GEE asset
            self.export_to_asset()

        return self
Esempio n. 2
0
    def _from_geo_json(self, geo_json):
        """set the gdf output from a geo_json"""

        if not geo_json:
            raise Exception('Please draw a shape in the map')

        # remove the style property from geojson as it's not recognize by geopandas and gee
        for feat in geo_json['features']:
            if 'style' in feat['properties']:
                del feat['properties']['style']

        # create the gdf
        self.gdf = gpd.GeoDataFrame.from_features(geo_json).set_crs(epsg=4326)

        # normalize the name
        self.name = su.normalize_str(self.name)

        if self.ee:
            # transform the gdf to ee.FeatureCollection
            self.feature_collection = geemap.geojson_to_ee(
                self.gdf.__geo_interface__)

            # export as a GEE asset
            self.export_to_asset()
        else:
            # save the geojson in downloads
            path = Path('~', 'downloads', 'aoi').expanduser()
            path.mkdir(
                exist_ok=True, parents=True
            )  # if nothing have been run the downloads folder doesn't exist
            self.gdf.to_file(path / f'{self.name}.geojson', driver='GeoJSON')

        return self
Esempio n. 3
0
    def _from_points(self, point_json):
        """set the object output from a csv json"""

        if not all(point_json.values()):
            raise Exception('All fields are required, please fill them.')

        # cast the pathname to pathlib Path
        point_file = Path(point_json['pathname'])

        # check that the columns are well set
        values = [v for v in point_json.values()]
        if not len(values) == len(set(values)):
            raise Exception(ms.aoi_sel.duplicate_key)

        # create the gdf
        df = pd.read_csv(point_file, sep=None, engine='python')
        self.gdf = gpd.GeoDataFrame(df,
                                    crs='EPSG:4326',
                                    geometry=gpd.points_from_xy(
                                        df[point_json['lng_column']],
                                        df[point_json['lat_column']]))

        # set the name
        self.name = point_file.stem

        if self.ee:
            # transform the gdf to ee.FeatureCollection
            self.feature_collection = geemap.geojson_to_ee(
                self.gdf.__geo_interface__)

            # export as a GEE asset
            self.export_to_asset()

        return self
Esempio n. 4
0
    def on_draw(self, action, geo_json, obj, variable, output):
        geom = geemap.geojson_to_ee(geo_json, False)
        feature = ee.Feature(geom)
        setattr(obj, variable, ee.FeatureCollection(feature))

        if output:
            utils.displayIO(output, 'A shape have been drawn')

        return
Esempio n. 5
0
def build_aoi(aoi_file):
    if aoi_file.endswith('shp'):
        aoi = geemap.shp_to_ee(aoi_file)
    elif aoi_file.endswith('json'):
        aoi = geemap.geojson_to_ee(aoi_file)

    print('Loaded {} successfully'.format(aoi_file))

    return aoi.geometry()
Esempio n. 6
0
def set_grid(aoi, grid_size, grid_batch, output):
    """compute a grid around a given aoi (ee.FeatureCollection)"""

    # get the shape of the aoi in mercator proj
    aoi_json = geemap.ee_to_geojson(aoi)
    aoi_shp = unary_union(
        [shape(feat['geometry']) for feat in aoi_json['features']])
    aoi_gdf = gpd.GeoDataFrame({
        'geometry': [aoi_shp]
    }, crs="EPSG:4326").to_crs('EPSG:3857')

    output.add_live_msg('Digest the selected AOI')

    # extract the aoi shape in mercator projection
    aoi_shp_proj = aoi_gdf['geometry'][0]

    # extract bounds from gdf
    min_lon, min_lat, max_lon, max_lat = aoi_gdf.total_bounds

    # mercator is in metter so we change unit
    buffer_size = grid_size * 1000

    # compute the longitudes and latitudes top left corner coordinates
    longitudes = np.arange(min_lon, max_lon, buffer_size)
    latitudes = np.arange(min_lat, max_lat, buffer_size)

    output.add_live_msg('Building the grid')

    #create the grid
    points = []
    batch = []
    for i, coords in enumerate(product(longitudes, latitudes)):

        # create grid geometry
        points.append(Point(coords[0], coords[1]))

        # add a batch number
        batch.append(int(i / grid_batch))

    # create a buffer grid in lat-long
    grid = gpd.GeoDataFrame({'batch': batch, 'geometry':points}, crs='EPSG:3857') \
        .buffer(buffer_size) \
        .envelope \
        .intersection(aoi_shp_proj) \
        .to_crs('EPSG:4326')

    # filter empty geometries
    grid = grid[np.invert(grid.is_empty)]

    # convert gdp to GeoJson
    json_df = json.loads(grid.to_json())

    output.add_live_msg('Grid build completed', 'success')

    return geemap.geojson_to_ee(json_df)
Esempio n. 7
0
def preview_square(geometry, grid_size):

    # get the center of the aoi
    center = geometry.centroid().getInfo()['coordinates']

    # create the square
    square = gpd.GeoDataFrame({'geometry': [Point(center[0], center[1])]}, crs='EPSG:4326') \
        .to_crs('EPSG:3857') \
        .buffer(grid_size*1000) \
        .envelope \
        .to_crs('EPSG:4326')

    # convert gpd to GeoJson
    json_df = json.loads(square.to_json())

    return geemap.geojson_to_ee(json_df)
Esempio n. 8
0
def get_stats(wlc_outputs, layer_model, aoi_model, features, names):

    # create the final featureCollection
    # the first one is the aoi and the rest are sub areas
    ee_aoi_list = [aoi_model.feature_collection]
    for feat in features["features"]:
        ee_aoi_list.append(geemap.geojson_to_ee(feat))

    # create the stats dictionnary
    stats = [
        get_summary_statistics(wlc_outputs, names[i], geom, layer_model.layer_list)
        for i, geom in enumerate(ee_aoi_list)
    ]

    area_dashboard = get_area_dashboard(stats)
    theme_dashboard = get_theme_dashboard(stats)

    return area_dashboard, theme_dashboard
Esempio n. 9
0
    def __init__(self,
                 roi=None,
                 start_year=2016,
                 end_year=2020,
                 sat='Sentinel',
                 key='max'):

        # Here we get the roi. Valid inputs are draws on the map, shapefiles or geojson
        self.roi = roi
        if self.roi is None:
            # When no geometry is passed we use a default area over Donana Natural Space
            self.roi = ee.Geometry.Polygon(
                [[[-6.766047, 36.776586], [-6.766047, 37.202186],
                  [-5.867729, 37.202186], [-5.867729, 36.776586],
                  [-6.766047, 36.776586]]], None, False)

        elif isinstance(self.roi, str):
            if self.roi.endswith('.shp'):
                self.roi = geemap.shp_to_ee(self.roi).geometry()
            elif self.roi.endswith('.geojson'):
                self.roi = geemap.geojson_to_ee(self.roi).geometry()
            else:
                print(
                    'It seems that your path is broken. Remember that await for shapefiles or geojson'
                )

        else:

            if not isinstance(roi, ee.Geometry):

                try:
                    self.roi = self.roi.geometry()
                except Exception as e:
                    print('Could not convert the provided roi to ee.Geometry')
                    print(e)
                    return

        self.start_year = start_year
        self.end_year = end_year
        if sat not in ['Sentinel', 'Landsat', 'MODIS', 'sar']:
            print('You should choose one from Sentinel, Landsat, MODIS or sar')
        else:
            self.sat = sat

        self.sat = sat
        if key not in ['max', 'median', 'perc_90']:
            print(
                'Please choose between max, median or perc_90 as available stats'
            )
        else:
            self.key = key
        self.imagelist = []
        # Here we define the periods, feel free to change the dates in case your are looking for different seasons
        self.winter = ['-01-01', '-03-31']
        self.spring = ['-04-01', '-06-30']
        self.summer = ['-07-01', '-09-30']
        self.autumn = ['-10-01', '-12-31']
        # Here we define one dict for each season, in order to have the choice to choose the stat (max and median for the moment, it could be whatever supported for GEE)
        self.dwinter = {}
        self.dspring = {}
        self.dsummer = {}
        self.dautumn = {}

        # Here we defined the collections to generate the ndvi
        # Just need Red and NIR bandas, so avoid and rename them to apply the ndvi formula...
        # ...to all sensors in the same way
        # Get Landsat surface reflectance collections for OLI, ETM+ and TM sensors.

        LC08col = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR").select(
            ['B4', 'B5'], ['Red', 'Nir'])
        LE07col = ee.ImageCollection("LANDSAT/LE07/C01/T1_SR").select(
            ['B3', 'B4'], ['Red', 'Nir'])
        LT05col = ee.ImageCollection("LANDSAT/LT05/C01/T1_SR").select(
            ['B3', 'B4'], ['Red', 'Nir'])
        LT04col = ee.ImageCollection("LANDSAT/LT04/C01/T1_SR").select(
            ['B3', 'B4'], ['Red', 'Nir'])

        # Notice that S2 is not in Surface Reflectance but in TOA, this because otherwise only
        # had data starting in 2017. Using BOA we have 2 extra years, starting at 2015
        # We use the wide 8 band instead of the 8A narrower badn, that is also more similar to landsat NIR
        # But this way we have NDVI at 10 m instead of 20. And we are using TOA instead of SR, so who cares?

        S2col = ee.ImageCollection("COPERNICUS/S2").select(['B4', 'B8'],
                                                           ['Red', 'Nir'])

        # Get MODIS MOD09Q1.006 Terra Surface Reflectance 8-Day Global 250m
        # This is going to be the coarse resolution we will add (250 m) but it cold be a good choice
        # for large areas. And we good pretty good data from 2000 until present
        MOD09Q1 = ee.ImageCollection("MODIS/006/MOD09Q1").select(
            ['sur_refl_b01', 'sur_refl_b02'], ['Red', 'Nir'])

        # Let's try to add Sentinel 1 to have some SAR data analysis capabilities
        s1 = ee.ImageCollection('COPERNICUS/S1_GRD').filter(
            ee.Filter.listContains('transmitterReceiverPolarisation',
                                   'VH')).filter(
                                       ee.Filter.eq('instrumentMode', 'IW'))
        s1Ascending = s1.filter(
            ee.Filter.eq('orbitProperties_pass', 'ASCENDING'))
        s1Descending = s1.filter(
            ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
        s1SAR = s1Ascending.select('VH').merge(s1Descending.select('VH'))

        # Set the collection that will be used
        if self.sat == 'Sentinel':
            self.ndvi_col = S2col
        elif self.sat == 'Landsat':
            self.ndvi_col = LC08col.merge(LE07col).merge(LT05col).merge(
                LT04col)
        elif self.sat == 'MODIS':
            self.ndvi_col = MOD09Q1
        elif self.sat == 'sar':
            self.ndvi_col = s1SAR
        else:
            print('Not a valid satellite')
            pass