Exemplo n.º 1
0
def get_gridded_boundary(shapefile, cell_size=1000):
    # Get its bounds from new projected
    bbox = shapefile.geometry.bounds
    # Get the bounding box of the area
    area_bbox = sentinelhub.BBox(bbox=[(bbox['minx'], bbox['miny']),
                                       (bbox['maxx'], bbox['maxy'])],
                                 crs=sentinelhub.CRS.WGS84)

    # Convert into UTM projection (in meters)
    area_bbox = sentinelhub.geo_utils.to_utm_bbox(area_bbox)
    shapefile = shapefile.to_crs(str(area_bbox.crs))
    bbox = shapefile.geometry.bounds

    ###Build the grid
    def get_shape_area(bbox, distance=cell_size):
        ##Would like division into 100*100 patches
        # Number of vertical patch xmin - xmax
        c1 = int((bbox['maxx'] - bbox['minx']) /
                 distance)  # + int((bbox['maxx'] - bbox['minx'])%distance)
        # Number of horizontal patch xmin - xmax
        c2 = int((bbox['maxy'] - bbox['miny']) /
                 distance)  # + int((bbox['maxy'] - bbox['miny'])%distance)
        return ((c1, c2))

    split_shape = get_shape_area(bbox, distance=cell_size)

    bbox_splitter = BBoxSplitter([area_bbox.geometry], area_bbox.crs,
                                 split_shape)

    bbox_list = np.array(bbox_splitter.get_bbox_list())
    info_list = np.array(bbox_splitter.get_info_list())

    # Prepare info of selected EOPatches
    geometry = [Polygon(bbox.get_polygon()) for bbox in bbox_list]
    # idxs = [info['index'] for info in info_list]
    idxs_x = [info['index_x'] for info in info_list]
    idxs_y = [info['index_y'] for info in info_list]

    gdf = gpd.GeoDataFrame({
        'index_x': idxs_x,
        'index_y': idxs_y
    },
                           crs=shapefile.crs,
                           geometry=geometry)
    gdf.reset_index(inplace=True)

    # Get the intersection of the contours from shapefile with the grid
    gdf['results'] = gdf.geometry.apply(
        lambda x: shapefile.geometry.intersection(x))
    # Construct a boolean associated
    booleans = np.array([(1 - k.is_empty) for k in gdf.results])
    gdf['check'] = booleans
    valid_obs = gdf.check.astype(bool)
    gdf = gdf.drop(['check'], axis=1)

    return gdf[valid_obs]
Exemplo n.º 2
0
    def setUpClass(cls):
        geojson = read_data(os.path.join(cls.INPUT_FOLDER,
                                         'cies_islands.json'))
        cls.area = shape(geojson)

        cls.test_cases = [
            cls.SplitterTestCase('BBoxSplitter',
                                 BBoxSplitter([cls.area],
                                              CRS.WGS84,
                                              5,
                                              reduce_bbox_sizes=True),
                                 bbox_len=19),
            cls.SplitterTestCase('OsmSplitter',
                                 OsmSplitter([cls.area],
                                             CRS.WGS84,
                                             15,
                                             reduce_bbox_sizes=True),
                                 bbox_len=24),
            cls.SplitterTestCase('TileSplitter',
                                 TileSplitter(
                                     [cls.area],
                                     CRS.WGS84, ('2017-10-01', '2018-03-01'),
                                     tile_split_shape=40,
                                     data_source=DataSource.SENTINEL2_L1C,
                                     reduce_bbox_sizes=True),
                                 bbox_len=13)
        ]
Exemplo n.º 3
0
    def setUpClass(cls):
        super().setUpClass()

        geojson = read_data(os.path.join(cls.INPUT_FOLDER, 'cies_islands.json'))
        cls.area = shapely.geometry.shape(geojson)

        bbox_grid = [BBox((x / 10, y / 100, (x + 1) / 10, (y + 1) / 100), CRS.WGS84)
                     for x, y in itertools.product(range(-90, -87), range(4200, 4250))]

        cls.test_cases = [
            cls.SplitterTestCase('BBoxSplitter',
                                 BBoxSplitter([cls.area], CRS.WGS84, 5, reduce_bbox_sizes=True), bbox_len=19),
            cls.SplitterTestCase('OsmSplitter',
                                 OsmSplitter([cls.area], CRS.WGS84, 15, reduce_bbox_sizes=True), bbox_len=24),
            cls.SplitterTestCase('TileSplitter',
                                 TileSplitter([cls.area], CRS.WGS84, ('2017-10-01', '2018-03-01'), tile_split_shape=40,
                                              data_source=DataSource.SENTINEL2_L1C, reduce_bbox_sizes=True),
                                 bbox_len=13),
            cls.SplitterTestCase('CustomGridSplitter',
                                 CustomGridSplitter([cls.area], CRS.WGS84, bbox_grid, bbox_split_shape=(3, 4),
                                                    reduce_bbox_sizes=False),
                                 bbox_len=41),
            cls.SplitterTestCase('UTMGridSplitter',
                                 UtmGridSplitter([cls.area], CRS.WGS84, bbox_size=(1200, 1200)), bbox_len=16),
            cls.SplitterTestCase('UTMZoneSplitter',
                                 UtmZoneSplitter([cls.area], CRS.WGS84, bbox_size=(1000, 1000)), bbox_len=19)
        ]
Exemplo n.º 4
0
def get_satellite_images(resolution, crs_output, time_interval, img_size, output_bucket, **kwargs):
    """
    Main function for generating satellite images (patches) using the EO-Learn API
    """

    path_land_cover = 'gcs/data/land_cover.geojson'
    path_aoi = 'gcs/data/aoi.geojson'

    # Get aoi dimensions in meters
    aoi_shape, aoi_width, aoi_height = get_aoi_dimensions(path_aoi, crs_output)

    # Load labels geodata
    labels_data = gpd.read_file(path_land_cover)
    labels_data = labels_data.to_crs(crs={'init': crs_output})

    # Compute number of columns and rows based on expected image dimensions output
    columns = int((aoi_width / img_size) / resolution)
    rows = int((aoi_height / img_size) / resolution)

    # Create splitter to obtain list of bounding boxes
    bbox_splitter = BBoxSplitter([aoi_shape], crs_output, (columns, rows))

    # Create and execute workflow
    workflow, input_task, save_task = create_workflow(resolution, labels_data, output_bucket)

    total_patches_created = execute_workflow(workflow,
                                             input_task,
                                             save_task,
                                             bbox_splitter,
                                             time_interval)

    return total_patches_created
Exemplo n.º 5
0
def generate_slo_shapefile(path):
    DATA_FOLDER = os.path.join('data')

    area = gpd.read_file(os.path.join(DATA_FOLDER, 'svn_buffered.geojson'))
    # area = gpd.read_file(os.path.join(DATA_FOLDER, 'austria.geojson'))

    # Convert CRS to UTM_33N
    country_crs = CRS.UTM_33N
    area = area.to_crs(crs={'init': CRS.ogc_string(country_crs)})

    # Get the country's shape in polygon format
    country_shape = area.geometry.values.tolist()[-1]

    # Plot country
    area.plot()
    plt.axis('off')

    # Create the splitter to obtain a list of bboxes
    bbox_splitter = BBoxSplitter([country_shape], country_crs,
                                 (25 * 3, 17 * 3))

    bbox_list = np.array(bbox_splitter.get_bbox_list())
    info_list = np.array(bbox_splitter.get_info_list())

    path_out = path + '/shapefiles'
    if not os.path.isdir(path_out):
        os.makedirs(path_out)

    geometry = [Polygon(bbox.get_polygon()) for bbox in bbox_list]
    idxs_x = [info['index_x'] for info in info_list]
    idxs_y = [info['index_y'] for info in info_list]

    gdf = gpd.GeoDataFrame({
        'index_x': idxs_x,
        'index_y': idxs_y
    },
                           crs={'init': CRS.ogc_string(country_crs)},
                           geometry=geometry)

    shapefile_name = path_out + '/slovenia.shp'
    gdf.to_file(shapefile_name)

    return gdf, bbox_list
Exemplo n.º 6
0
 def split_box(self, bbox_epsg4326, res):
     """
     splits WGS84 box coordinates into as many boxes as needed for Sentinel Hub
     :param bbox_epsg4326: list or tuple of length 4 with xmin, ymin, xmax, ymax
     :param res: float spatial resolution
     :return: list of Bbox instances in UTM
     """
     try:
         upper_left_utm = utm.from_latlon(bbox_epsg4326[3], bbox_epsg4326[0])
     except TypeError:  # is already of class Bbox
         return [bbox_epsg4326]
     lower_right_utm = utm.from_latlon(bbox_epsg4326[1], bbox_epsg4326[2], upper_left_utm[2])  # same zone number
     sizes = self.calc_bbox_size(upper_left_utm, lower_right_utm, res)
     # split into several boxes
     hemisphere = "N" if bbox_epsg4326[3] >= 0 else "S"
     bbox_utm = Polygon(box(upper_left_utm[0], lower_right_utm[1], lower_right_utm[0], upper_left_utm[1]))
     crs = CRS["UTM_" + str(upper_left_utm[2]) + hemisphere]  # use UTM
     y = int(np.clip(np.round(sizes["x"] / 2400 + 0.5), 1, np.inf))  # + 0.5 in order to ensure rounding upwards
     x = int(np.clip(np.round(sizes["y"] / 2400 + 0.5), 1, np.inf))
     bbox_splitter = BBoxSplitter([bbox_utm], crs, (y, x), reduce_bbox_sizes=True)
     return bbox_splitter.get_bbox_list()
Exemplo n.º 7
0
def main():
    args = parse_args()

    grid = args.grid.split(",")
    coords = [float(x.strip()) for x in args.coords.split(",")]

    # if args.geo_json_file:
    #     INPUT_FILE = args.data_file
    #
    #     geo_json = read_data(INPUT_FILE)

    area = Polygon([[coords[0], coords[1]], [coords[0], coords[3]], [coords[2], coords[3]], [coords[2], coords[1]]])
    bbox_splitter = BBoxSplitter([area], CRS.WGS84,
                                 (int(grid[0]), int(grid[1])), reduce_bbox_sizes=True)

    img_dict = make_request(bbox_splitter, args.instance_id, args.util, args.width, args.height, args.maxcc, args.time, args.start_time, args.end_time)

    if args.util == 'info':
        print_info(img_dict, args.maxcc, args.start_time, args.end_time)
Exemplo n.º 8
0
    #INSTANCE_ID = instance
    INSTANCE_ID = os.environ.get('INSTANCE_ID')
    print(INSTANCE_ID)
    # global image request parameters
    time_interval = (time_start, time_end)
    img_width = width
    img_height = height
    maxcc = max_accuracy
    # input location for the example: example_data/eastern_france.geojson
    # get the AOI and split into bboxes
    crs = CRS.UTM_31N
    aoi = geopandas.read_file(os.path.join(input_path, filename))
    aoi = aoi.to_crs(crs=crs.pyproj_crs())
    aoi_shape = aoi.geometry.values[-1]

    bbox_splitter = BBoxSplitter([aoi_shape], crs, (19, 10))

    # set raster_value conversions for our Geopedia task
    # see more about how to do this here:

    raster_value = {
        '0%': (0, [0, 0, 0, 0]),
        '10%': (1, [163, 235, 153, 255]),
        '30%': (2, [119, 195, 118, 255]),
        '50%': (3, [85, 160, 89, 255]),
        '70%': (4, [58, 130, 64, 255]),
        '90%': (5, [36, 103, 44, 255])
    }

    import matplotlib as mpl
Exemplo n.º 9
0
#%% Section 2
#Defining AOI and making Bboxes

country = gpd.read_file('./DK.geojson')

# Convert CRS to UTM_32N
country_crs = CRS.UTM_32N
country = country.to_crs(crs={'init': CRS.ogc_string(country_crs)})

# Get the country's shape in polygon format
country_shape = country.geometry.values.tolist()[-1]
#country.plot()
#plt.axis('off');

# Create the splitter to obtain a list of bboxes
bbox_splitter_large = BBoxSplitter([country_shape], country_crs, (45, 35))
bbox_splitter_small = BBoxSplitter([country_shape], country_crs,
                                   (45 * 3, 35 * 3))

bbox_splitter = bbox_splitter_large

bbox_list = np.array(bbox_splitter.get_bbox_list())
info_list = np.array(bbox_splitter.get_info_list())

#Prepare info of selected patch IDs
geometry = [Polygon(bbox.get_polygon()) for bbox in bbox_list[patchIDs]]
idxs_x = [info['index_x'] for info in info_list[patchIDs]]
idxs_y = [info['index_y'] for info in info_list[patchIDs]]
df = pd.DataFrame({'index_x': idxs_x, 'index_y': idxs_y})
gdf = gpd.GeoDataFrame(df,
                       crs={'init': CRS.ogc_string(country_crs)},
import os


def get_current_folder(str):
    return os.path.abspath(str)


if __name__ == '__main__':

    img = OBSImage('obs://obs-tiff-test/retile_china/ng47_05_41.tif')
    print("bounds: {}".format(img.bounds))
    print("shape {}".format(img.shape))
    image_box = box(img.bounds[0], img.bounds[1], img.bounds[2], img.bounds[3])

    # Split the image into 3 * 3 tiles
    bbox_splitter = BBoxSplitter([image_box], img.proj, (3, 3))

    bbox_list = np.array(bbox_splitter.get_bbox_list())
    info_list = np.array(bbox_splitter.get_info_list())

    # Obtain patchIDs
    patchIDs = []
    for idx, [bbox, info] in enumerate(zip(bbox_list, info_list)):
        patchIDs.append(idx)

    # Check if final size is 3x3
    if len(patchIDs) != 9:
        print(
            'Warning! Use a different central patch ID, this one is on the border.'
        )
Exemplo n.º 11
0
                        facecolor='red',
                        edgecolor='red'))

    plt.tight_layout()
    plt.show()


show_area(hawaii_area)
"""
We want to split the area into smaller bounding boxes which can then be used to obtain data with WMS/WCS requests.
There are different ways to split the area implemented in sentinelhub.

The first way is to split the bounding box into smaller parts of equal size. For inputs we must provide: list of 
geometries, their CRS, and an int/tuple specifying how many parts the bounding box will be split into.
"""
bbox_splitter = BBoxSplitter([hawaii_area], CRS.WGS84,
                             (5, 4))  # will produce 5x4 grid of bboxes

print('Area bounding box: {}\n'.format(
    bbox_splitter.get_area_bbox().__repr__()))

bbox_list = bbox_splitter.get_bbox_list()
info_list = bbox_splitter.get_info_list()

print(
    'Each bounding box also has some info about how it was created.\nExample:\n'
    'bbox: {}\ninfo: {}\n'.format(bbox_list[0].__repr__(), info_list[0]))

# get a list of geometries
geometry_list = bbox_splitter.get_geometry_list()
print(geometry_list[0])
def download_data(self, dataset, orbit_dates, total_width, total_height, bbox, temporal_extent, bands, dataFilter_params, max_chunk_size=1000):
    auth_token = SHProcessingAuthTokenSingleton.get()
    url = 'https://services.sentinel-hub.com/api/v1/process'
    headers = {
        'Accept': 'image/tiff',
        'Authorization': f'Bearer {auth_token}'
    }

    n_width = math.ceil(total_width/max_chunk_size)
    n_height = math.ceil(total_height/(max_chunk_size*max_chunk_size/(total_width//n_width + 1)))
    bbox_list = BBoxSplitter([bbox.geometry], CRS.WGS84, (n_width, n_height)).get_bbox_list()
    x_image_shapes = [total_width//n_width + 1 if w < total_width % n_width else total_width//n_width for w in range(n_width)]
    y_image_shapes = [total_height//n_height + 1 if h < total_height % n_height else total_height//n_height for h in range(n_height)]

    adapter_kwargs = dict(pool_maxsize=len(orbit_dates)*n_width*n_height)
    executor = ThreadPoolExecutor(max_workers=len(orbit_dates)*n_width*n_height)
    requests_session = FuturesSession(executor=executor, adapter_kwargs=adapter_kwargs)
    response_futures = {}

    orbit_times_middle,shapes = [],{}

    tmp_folder = f"/tmp-{self.job_id}"
    if os.path.exists(tmp_folder):
        os.rmdir(tmp_folder)
    os.mkdir(tmp_folder)

    for i, date in enumerate(orbit_dates):
        mean_time = date["from"] + (date["to"] - date["from"]) / 2
        tile_from = mean_time - timedelta(minutes=25)
        tile_to = mean_time + timedelta(minutes=25)
        orbit_times_middle.append(mean_time)
        shapes[i] = []

        for j, bbox_section in enumerate(bbox_list):
            request_params = {
                "input": {
                    "bounds": {
                        "bbox": [bbox_section.min_x, bbox_section.min_y, bbox_section.max_x, bbox_section.max_y],
                        "properties": {
                            "crs": "http://www.opengis.net/def/crs/EPSG/0/4326",
                        }
                    },
                    "data": [
                        {
                            "type": dataset,
                            "dataFilter": {
                                "timeRange": {
                                    "from": tile_from.strftime("%Y-%m-%dT%H:%M:%S+00:00"),
                                    "to": tile_to.strftime("%Y-%m-%dT%H:%M:%S+00:00"),
                                },
                                **dataFilter_params,
                            }
                        },
                    ],
                },
                "output": {
                    "width": x_image_shapes[j//n_height],
                    "height": y_image_shapes[j%n_height],
                },
                "evalscript": f"""//VERSION=3

                    function setup() {{
                        return {{
                            input: [{', '.join([f'"{b}"' for b in bands])}, "dataMask"],
                            output: {{
                                bands: {len(bands) + 1},
                                sampleType: "FLOAT32",
                            }}
                        }}
                    }}

                    function evaluatePixel(sample) {{
                        return [{", ".join(['sample.' + b for b in bands])}, sample.dataMask]
                    }}
                """
            }
            shapes[i].append((y_image_shapes[j%n_height],x_image_shapes[j//n_height],len(bands)+1))
            r = requests_session.post(url, headers=headers, json=request_params)
            response_futures[r] = {"date":i,"bbox":j}

    dates_filenames = {}

    for r_future, indices in response_futures.items():
        r = r_future.result()
        if r.status_code != 200:
            raise Internal(r.content)
        self.logger.debug('Image received.')

        tmp_filename = f'{tmp_folder}/image-{indices["date"]}-{indices["bbox"]}.tiff'
        if dates_filenames.get(indices["date"]) is None:
            dates_filenames[indices["date"]] = [tmp_filename]
        else:
            dates_filenames[indices["date"]].append(tmp_filename)
        with open(tmp_filename, 'wb') as f:
            f.write(r.content)

    response_data = []
    for i in range(len(orbit_dates)):
        images = [delayed(imageio.imread)(filename) for filename in dates_filenames[i]]
        images = [da.from_delayed(image, shape=shapes[i][j], dtype=np.float32) for j,image in enumerate(images)]
        image_gdal = construct_image(images, n_width, n_height)
        response_data.append(image_gdal)

    response_data = da.stack(response_data)
    self.logger.debug('Images created.')
    return response_data, orbit_times_middle
Exemplo n.º 13
0
def download_region(base_dir,
                    minx,
                    miny,
                    maxx,
                    maxy,
                    time_range,
                    target_tiles=None):
    ''' Defines a workflow that will download and process all EOPatces in a defined region.

        This workflow will download all EOPatches in a given larger region. 

        The pipline has the folowing steps 
            - Download data 
            - Calculate NDVI 
            - Calculate NDWI
            - Calculate FDI
            - Add cloud mask
            - Add water mask
            - Combine all masks
            - Perform local noramalization
            - Save the results.

        Parameters:
            
            - base_dir: the directory to save the patches to 
            - minx: Min Longitude of the region 
            - miny: Min Latitude of the region 
            - maxx: Max Longitude of the region 
            - maxy: Max Latitude of the region
            - time_range: An array of [start_time,end_time]. Any satelite pass in that range will be procesed.
            - target_tiles: A list of tiles to manually include (not used right now)
       
        Returns:
            Nothing.
    '''

    region = box(minx, miny, maxx, maxy)
    bbox_splitter = BBoxSplitter([region], CRS.WGS84, (20, 20))

    bbox_list = np.array(bbox_splitter.get_bbox_list())
    info_list = np.array(bbox_splitter.get_info_list())

    # Prepare info of selected EOPatches
    geometry = [Polygon(bbox.get_polygon()) for bbox in bbox_list]
    idxs_x = [info['index_x'] for info in info_list]
    idxs_y = [info['index_y'] for info in info_list]
    ids = range(len(info_list))

    gdf = gp.GeoDataFrame({
        'index': ids,
        'index_x': idxs_x,
        'index_y': idxs_y
    },
                          crs='EPSG:4326',
                          geometry=geometry)

    ax = gdf.to_crs('EPSG:3857').plot(facecolor='w',
                                      edgecolor='r',
                                      figsize=(20, 20),
                                      alpha=0.3)

    for idx, row in gdf.to_crs("EPSG:3857").iterrows():
        geo = row.geometry
        xindex = row['index_x']
        yindex = row['index_y']
        index = row['index']
        ax.text(geo.centroid.x,
                geo.centroid.y,
                f'{index}',
                ha='center',
                va='center')

    cx.add_basemap(ax=ax)
    plt.savefig(f'{base_dir}/region.png')

    total = len(target_tiles) if target_tiles else len(bbox_list)

    for index, patch_box in enumerate(bbox_list):
        if (target_tiles and index not in target_tiles):
            continue
        print("Getting patch ", index, ' of ', total)
        try:
            patch = get_and_process_patch(patch_box, time_range, base_dir,
                                          index)
            fig, ax = plot_masks_and_vals(patch)
            fig.savefig(f'{base_dir}/feature_{index}/bands.png')
            plt.close(fig)

            fig, ax = plot_ndvi_fid_plots(patch)
            fig.savefig(f'{base_dir}/feature_{index}/ndvi_fdi.png')
            plt.close(fig)
        except:
            print("Failed to process ", index)
Exemplo n.º 14
0
 def split_large_polygon_epsg4326(self, polygon_epsg4326, res):
     bounds = polygon_epsg4326.bounds
     x_size, y_size = abs(bounds[0] - bounds[2]) * 111000, abs(bounds[1] - bounds[3]) * 111000  # meters
     x_nboxes, y_nboxes = int((x_size / res) / 2400), int((y_size / res) / 2400)  # 2400 max. n pixels
     bbox_splitter = BBoxSplitter([polygon_epsg4326], CRS.WGS84, (x_nboxes, y_nboxes), reduce_bbox_sizes=True)
     return bbox_splitter.get_bbox_list()
Exemplo n.º 15
0
# Convert CRS to WGS84
country_crs = CRS.WGS84
country = country.to_crs(crs={'init': CRS.ogc_string(country_crs)})

# Get the country's shape in polygon format
country_shape = country.geometry.values.tolist()[-1]

# Print size
print('Dimension of the area is {0:.0f} x {1:.0f} m2'.format(
    country_shape.bounds[2] - country_shape.bounds[0],
    country_shape.bounds[3] - country_shape.bounds[1]))

use_smaller_patches = False

# Create the splitter to obtain a list of bboxes
bbox_splitter_large = BBoxSplitter([country_shape], country_crs, (10, 10))
bbox_splitter_small = BBoxSplitter([country_shape], country_crs,
                                   (15 * 3, 15 * 3))

bbox_splitter = bbox_splitter_small if use_smaller_patches else bbox_splitter_large

bbox_list = np.array(bbox_splitter.get_bbox_list())
info_list = np.array(bbox_splitter.get_info_list())

# For the future examples, we will be using a specific set of patches,
# but you are free to change the patch ID numbers in the scope of this example
# Select a central patch
# ID = 1549 if use_smaller_patches else 190

# Obtain surrounding patches
patchIDs = []