def setUpClass(cls): super().setUpClass() with open(os.path.join(cls.INPUT_FOLDER, "test_fis_results.txt"), 'r') as file: results = [ast.literal_eval(line.strip()) for line in file] bbox = BBox([14.00, 45.00, 14.03, 45.03], crs=CRS.WGS84) geometry1 = Geometry(Polygon([(465888.877326859, 5079639.436138632), (465885.3413983975, 5079641.524618266), (465882.9542217017, 5079647.166043535), (465888.8780175466, 5079668.703676634), (465888.877326859, 5079639.436138632)]), CRS(32633)) geometry2 = Geometry('POLYGON((-5.13 48, -5.23 48.09, -5.13 48.17, -5.03 48.08, -5.13 48))', CRS.WGS84) cls.test_cases = [ cls.FisTestCase('geometry', FisRequest(layer='TRUE-COLOR-S2-L1C', geometry_list=[geometry1], time=('2017-1-1', '2017-2-1'), resolution="50m", histogram_type=HistogramType.STREAMING, bins=5), raw_result=results[0], result_length=1), cls.FisTestCase('bbox', FisRequest(layer='BANDS-S2-L1C', geometry_list=[bbox], time='2017-1-1', resolution="50m", maxcc=0.2, custom_url_params={ CustomUrlParam.ATMFILTER: "ATMCOR", CustomUrlParam.DOWNSAMPLING: "BICUBIC", CustomUrlParam.UPSAMPLING: "BICUBIC"} ), raw_result=results[1], result_length=1), cls.FisTestCase('list', FisRequest(data_source=DataSource.LANDSAT8, layer='BANDS-L8', geometry_list=[bbox, geometry1], time=('2017-1-1', '2017-1-10'), resolution="100m", bins=32, data_folder=cls.OUTPUT_FOLDER), raw_result=results[2], result_length=2, save_data=True), cls.FisTestCase('Polygon in WGS84', FisRequest(layer='TRUE-COLOR-S2-L1C', geometry_list=[geometry2], time=('2017-10-1', '2017-10-2'), resolution="60m", bins=11, histogram_type=HistogramType.EQUALFREQUENCY), raw_result=results[3], result_length=1), ] for test_case in cls.test_cases: test_case.collect_data()
def get_sampling_geometry(self, tile_info): tile_geometry = Geometry(tile_info['geometry'], crs=self.area_of_interest.crs) utm_crs = ShOgcSampling.get_crs(tile_info) tile_geometry = tile_geometry.transform(utm_crs) utm_aoi_geometry = self.area_of_interest.transform(utm_crs) # Warning: This intersection can be too small for sampling, that is why __next__ method is retrying the process return Geometry( tile_geometry.geometry.intersection(utm_aoi_geometry.geometry), utm_crs)
def plot_batch_splitter(splitter: BatchSplitter): """ Plots tiles and area geometry from a splitter class """ gdf = gpd.GeoDataFrame(dict( status=[info['status'] for info in splitter.get_info_list()], geometry=splitter.get_bbox_list()), crs=CRS.WGS84.pyproj_crs()) ax = gdf.plot(column='status', legend=True, figsize=(10, 10)) geometry = Geometry(splitter.get_area_shape(), splitter.crs) geometry = geometry.transform(CRS.WGS84) area_series = gpd.GeoSeries([geometry.geometry], crs=geometry.crs.pyproj_crs()) area_series.plot(ax=ax, facecolor='none', edgecolor='black')
def execute(self, eopatch=None, *, bbox=None, time_interval=None): """Execute method that adds new Meteoblue data into an EOPatch :param eopatch: An EOPatch in which data will be added. If not provided a new EOPatch will be created. :type eopatch: EOPatch or None :param bbox: A bounding box of a request. Should be provided if eopatch parameter is not provided. :type bbox: BBox or None :param time_interval: An interval for which data should be downloaded. If not provided then timestamps from provided eopatch will be used. :type time_interval: (dt.datetime, dt.datetime) or (str, str) or None """ eopatch = eopatch or EOPatch() eopatch.bbox = self._prepare_bbox(eopatch, bbox) time_intervals = self._prepare_time_intervals(eopatch, time_interval) bbox = eopatch.bbox geometry = Geometry(bbox.geometry, bbox.crs).transform(CRS.WGS84) geojson = shapely.geometry.mapping(geometry.geometry) query = { "units": self.units, "geometry": geojson, "format": "protobuf", "timeIntervals": time_intervals, "queries": [self.query], } result_data, result_timestamp = self._get_data(query) if not eopatch.timestamp and result_timestamp: eopatch.timestamp = result_timestamp eopatch[self.feature] = result_data return eopatch
def test_search_geometry_and_iterator_methods(catalog): """ Tests search with a geometry and test methods of CatalogSearchIterator """ search_geometry = Geometry(TEST_BBOX.geometry, crs=TEST_BBOX.crs) search_iterator = catalog.search(collection=DataCollection.SENTINEL2_L1C, time=('2021-01-01', '2021-01-5'), geometry=search_geometry, query={'eo:cloud_cover': { 'lt': 40 }}) results = list(search_iterator) assert len(results) == 1 assert search_iterator.get_timestamps() == [ dt.datetime(2021, 1, 3, 7, 14, 7, tzinfo=dateutil.tz.tzutc()) ] assert search_iterator.get_ids() == [ 'S2A_MSIL1C_20210103T071211_N0209_R020_T38LPH_20210103T083459' ] geometries = search_iterator.get_geometries() assert len(geometries) == 1 assert isinstance(geometries[0], Geometry) assert geometries[0].geometry.intersects(search_geometry.geometry)
def setUpClass(cls): super().setUpClass() polygon = shapely.geometry.Polygon([(465888.8773268595, 5079639.43613863), (465885.3413983975, 5079641.52461826), (465882.9542217017, 5079647.16604353), (465888.8780175466, 5079668.70367663), (465888.877326859, 5079639.436138632)]) cls.wkt_string = 'MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), ' \ '(30 20, 20 15, 20 25, 30 20)))' cls.geometry1 = Geometry(polygon, CRS(32633)) cls.geometry2 = Geometry(cls.wkt_string, CRS.WGS84) cls.bbox = BBox(bbox=[14.00, 45.00, 14.03, 45.03], crs=CRS.WGS84) cls.bbox_collection = BBoxCollection([cls.bbox, BBox('46,13,47,20', CRS.WGS84)]) cls.geometry_list = [cls.geometry1, cls.geometry2, cls.bbox, cls.bbox_collection]
def test_wkt(self): for geometry in [self.geometry1, self.geometry2]: self.assertEqual( geometry, Geometry(geometry.wkt, geometry.crs), 'Transforming geometry to geojson and back should preserve it') self.assertEqual(self.geometry2.wkt, self.wkt_string, 'New WKT string doesnt match the original')
def geometry(self): """ Helper function to return a WKT polygon from a Geopedia geometry Given a geometry field from a Geopedia table, return a WKT polygon in POP_WEB CRS :param geometry: Dictionary describing a Geopedia geometry feature :return: WKT polygon in popular web-mercator """ geometry_payload = self.payload['geometry'] return Geometry( shapely.geometry.shape(geometry_payload), crs=geometry_payload['crs']['properties']['name'].split(':')[-1])
def cloud_map(self): """ Download cloud map from API. """ if not isinstance(self._cloud_map, pd.DataFrame): geometry = Geometry(Polygon(self.external_polygon), CRS.WGS84) request = get_request( self, evalscript=evalscript_cloud_mask, geometry=geometry ) self._cloud_map = pd.DataFrame(request.get_data()[0]) return self._cloud_map
def _decode(self, file, path): """Loads from a file and decodes content.""" file_format = MimeType(fs.path.splitext(path)[1].strip(".")) if file_format is MimeType.NPY: return np.load(file) if file_format is MimeType.GPKG: dataframe = gpd.read_file(file) if dataframe.crs is not None: # Trying to preserve a standard CRS and passing otherwise try: with warnings.catch_warnings(): warnings.simplefilter("ignore", category=SHUserWarning) dataframe.crs = CRS(dataframe.crs).pyproj_crs() except ValueError: pass if "TIMESTAMP" in dataframe: dataframe.TIMESTAMP = pd.to_datetime(dataframe.TIMESTAMP) return dataframe if file_format in [MimeType.JSON, MimeType.GEOJSON]: json_data = json.load(file) if self.feature_type is FeatureType.BBOX: return Geometry.from_geojson(json_data).bbox return json_data if file_format is MimeType.PICKLE: warnings.warn( f"File {self.path} with data of type {self.feature_type} is in pickle format which is deprecated " "since eo-learn version 1.0. Please re-save this EOPatch with the new eo-learn version to " "update the format. In newer versions this backward compatibility will be removed.", EODeprecationWarning, ) data = pickle.load(file) # There seems to be an issue in geopandas==0.8.1 where unpickling GeoDataFrames, which were saved with an # old geopandas version, loads geometry column into a pandas.Series instead geopandas.GeoSeries. Because # of that it is missing a crs attribute which is only attached to the entire GeoDataFrame if isinstance(data, GeoDataFrame) and not isinstance( data.geometry, GeoSeries): data = data.set_geometry("geometry") return data raise ValueError(f"Unsupported data type for file {path}.")
def test_bbox_geometry(self): """ Test intersection between bbox and geometry """ evalscript = """ //VERSION=3 function setup() { return { input: [{ bands: ["B02", "B03", "B04"], units: "REFLECTANCE" }], output: { bands: 3 } }; } function evaluatePixel(sample) { return [2.5 * sample.B04, 2.5 * sample.B03, 2.5 * sample.B02]; } """ delta = 0.2 bbox = BBox(bbox=[46.16, -16.15, 46.51, -15.58], crs=CRS.WGS84) geometry = Geometry(bbox.geometry, crs=bbox.crs) bbox_translated = BBox(bbox=[ 46.16 + delta, -16.15 + delta, 46.51 + delta, -15.58 + delta ], crs=CRS.WGS84) request = SentinelHubRequest( evalscript=evalscript, input_data=[ SentinelHubRequest.input_data( data_collection=DataCollection.SENTINEL2_L1C, time_interval=('2017-12-15T07:12:03', '2017-12-15T07:12:04'), maxcc=0.8) ], responses=[ SentinelHubRequest.output_response('default', MimeType.JPG) ], geometry=geometry, bbox=bbox_translated, size=(512, 856)) img = request.get_data(max_threads=3)[0] self.assertEqual(img.shape, (856, 512, 3)) self.test_numpy_data(img, exp_min=0, exp_max=255, exp_mean=22.625)
def simplify_geometry(aoi: Geometry, tolerance: float = 0.004, max_count: int = 1500) -> Geometry: """ Simplify input geometry such that number of vertices can be processed by batch process API """ vertex_count = get_number_of_vertices(aoi) LOGGER.info(f'Number of vertices of original geometry: {vertex_count}') if vertex_count > max_count: geometry = aoi.geometry.simplify(tolerance, preserve_topology=True) aoi = Geometry(geometry, crs=aoi.crs) LOGGER.info( f'Number of vertices after simplification: {get_number_of_vertices(aoi)}' ) return aoi
def create_batch_request( config: DownloadConfig, output_responses: List[dict], description: str = 'Batch request') -> SentinelHubBatch: """ Helper function that creates a SH batch request """ LOGGER.info('Read and simplify AOI geometry') aoi_gdf = gpd.read_file(config.aoi_filename) assert aoi_gdf.crs.name == 'WGS 84' aoi = Geometry(aoi_gdf.geometry.values[0], crs=CRS.WGS84) aoi = simplify_geometry(aoi) LOGGER.info('\nSet up SH and AWS credentials') _ = set_sh_config(config) LOGGER.info('\nThis evalscript is executed') evalscript = load_evalscript() sentinelhub_request = SentinelHubRequest( evalscript=evalscript, input_data=[ SentinelHubRequest.input_data( data_collection=config.data_collection, time_interval=config.time_interval, maxcc=config.maxcc, mosaicking_order=config.mosaicking_order) ], responses=output_responses, geometry=aoi) batch_request = SentinelHubBatch.create( sentinelhub_request, tiling_grid=SentinelHubBatch.tiling_grid(**config.grid_definition), output=SentinelHubBatch.output( default_tile_path= f's3://{config.bucket_name}/{config.tiles_path}/<tileName>/<outputId>.<format>' ), description=description) return batch_request
for idx, (image, time) in enumerate(zip(images, wcs_request.get_dates())): axs.flat[idx].imshow(image) axs.flat[idx].set_title(time.date().isoformat()) fig.tight_layout() """ Comparing Histograms: FIS can also provide histograms of calues split into a specified number of binds which will allows us to analyse the distribution of values without having to download entire images. Compare NDVI value distributions of the following bboxes and polygons. We will divide values into 20 equally-sized bins and use Landsat 8 data. For simplification, we select a time interval for which there is only one acquisition available. """ bbox1 = BBox([46.16, -16.15, 46.51, -15.58], CRS.WGS84) bbox2 = BBox((1292344.0, 5195920.0, 1310615.0, 5214191.0), CRS.POP_WEB) geometry1 = Geometry( Polygon([(-5.13, 48), (-5.23, 48.09), (-5.13, 48.17), (-5.03, 48.08), (-5.13, 48)]), CRS.WGS84) geometry2 = Geometry( Polygon([(1292344.0, 5205055.5), (1301479.5, 5195920.0), (1310615.0, 5205055.5), (1301479.5, 5214191.0), (1292344.0, 5205055.5)]), CRS.POP_WEB) print(list(HistogramType)) ndvi_script = 'return [(B05 - B04) / (B05 + B04)]' histogram_request = FisRequest( data_collection=DataCollection.LANDSAT8, layer='TRUE-COLOR-L8', geometry_list=[bbox1, bbox2, geometry1, geometry2], time=('2018-06-10', '2018-06-15'),
# 1. Create a batch request # 1.1 Define a Processing API request CLIENT_ID = 'ac45629f-3b23-4a8d-a579-0a30bbfbaa0e' CLIENT_SECRET = 'd,w~E#IpJJ6eTfEUd$A*q<bU5hNivI!jANtt<7WP' config = SHConfig() if CLIENT_ID and CLIENT_SECRET: config.sh_client_id = CLIENT_ID config.sh_client_secret = CLIENT_SECRET SHAPE_PATH = os.path.join('.', 'data', 'california_crop_fields.geojson') area_gdf = gpd.read_file(SHAPE_PATH) # Geometry of entire area full_geometry = Geometry(area_gdf.geometry.values[0], crs=CRS.WGS84) # BBox of a test sub-area test_bbox = Geometry(area_gdf.geometry.values[1], crs=CRS.WGS84).bbox area_gdf.plot(column='name') # Check a true-colour satellite image of the entire area evalscript_true_colour = """ //VERSION=3 function setup() { return { input: [{ bands: ["B02", "B03", "B04"] }], output: { bands: 3 } }
def test_geojson(self): for geometry in [self.geometry1, self.geometry2]: self.assertEqual(geometry, Geometry(geometry.geojson, geometry.crs), 'Transforming geometry to geojson and back should preserve it')
def test_multipart_geometry(self): evalscript = """ //VERSION=3 function setup() { return { input: ["B02", "B03", "B04", "dataMask"], output: { id:"default", bands: 3} } } function updateOutputMetadata(scenes, inputMetadata, outputMetadata) { var sum = (r_count + g_count + b_count); var r_rat = r_count / sum; var g_rat = g_count / sum; var b_rat = b_count / sum; outputMetadata.userData = { "rgb_ratios": [r_rat, g_rat, b_rat] } } var r_count = 0; var g_count = 0; var b_count = 0; function evaluatePixel(sample) { b_count += sample.B02; g_count += sample.B03; r_count += sample.B04; if (sample.dataMask == 0) { return [1,1,1]; } return [sample.B04*2.5, sample.B03*2.5, sample.B02*2.5]; } """ points = [(3983945.16471594, 4455475.78793186), (3983888.00256275, 4455757.47439827), (3983881.86585896, 4455756.21837259), (3983806.23113651, 4456128.92147268), (3983795.43856837, 4456181.52922753), (3983782.49665288, 4456243.16761979), (3983769.24786918, 4456304.74059236), (3983755.69254332, 4456366.24660331), (3983741.83100914, 4456427.68411298), (3983731.89973217, 4456470.84795843), (3983633.33670483, 4456895.81023678), (3983639.43692276, 4456897.23726002), (3983537.58701916, 4457336.35298979), (3983531.486563, 4457334.92584801), (3983451.81567033, 4457678.40439185), (3983444.09684707, 4457713.91738361), (3983433.21703553, 4457774.95105094), (3983425.2423303, 4457836.4359853), (3983420.19086095, 4457898.23280495), (3983418.07413054, 4457960.2014162), (3983418.89698951, 4458022.20133071), (3983422.65762374, 4458084.09198476), (3983429.05535825, 4458143.30899922), (3983435.27377231, 4458142.55298424), (3983439.97457434, 4458175.43769638), (3983450.97468474, 4458236.14788553), (3983466.88315168, 4458303.87476693), (3983460.83517165, 4458305.51224157), (3983466.80900589, 4458327.76588705), (3983484.9991527, 4458387.02138291), (3983505.97749719, 4458445.340412), (3983538.67409472, 4458522.43435024), (3983584.70089337, 4458635.18822735), (3983780.40768297, 4459048.67824218), (3983801.72985096, 4459096.84527808), (3983883.42859759, 4459278.64097453), (3984316.01202946, 4460214.51826613), (3984398.97672295, 4460080.53793049), (3984534.50220822, 4459799.86484374), (3984577.77550522, 4459774.02321167), (3984491.40157364, 4459687.94895666), (3984776.22996932, 4459142.13379129), (3984819.68594039, 4459029.12887873), (3984907.71921624, 4458981.665405), (3984888.9490588, 4458770.02890185), (3985209.2168573, 4458503.41559024), (3985821.45298221, 4458006.99923219), (3985788.76207523, 4457880.30735337), (3985793.50611539, 4457877.12247581), (3985784.68739608, 4457859.48509427), (3985732.13693102, 4457697.05635426), (3985820.89433686, 4457656.86419316), (3985677.94930497, 4457315.34906349), (3985611.18897298, 4457337.80151946), (3985327.61285454, 4457451.86990929), (3985146.68294768, 4456972.64460213), (3985446.37981687, 4456852.84034971), (3985488.11295695, 4456837.9565739), (3985384.27368677, 4456550.32595766), (3985005.77351172, 4455718.96868536), (3984372.83691021, 4455665.6888113), (3984231.62160324, 4455623.03272949), (3984096.30921154, 4455487.68759209), (3983945.16471594, 4455475.78793186)] sgeo = Polygon(points) crs = CRS('epsg:3857') geo = Geometry(sgeo, crs=crs) bbox = BBox(sgeo.bounds, crs=crs) size = bbox_to_dimensions(bbox, 10) request = SentinelHubRequest( evalscript=evalscript, input_data=[ SentinelHubRequest.input_data( data_source=DataSource.SENTINEL2_L1C, time_interval=('2017-11-15T07:12:03', '2017-12-15T07:12:04'), ) ], responses=[ SentinelHubRequest.output_response('default', MimeType.TIFF), SentinelHubRequest.output_response('userdata', MimeType.JSON) ], bbox=bbox, geometry=geo, size=size) tar = request.get_data(max_threads=3)[0] img = tar['default.tif'] self.assertEqual(img.shape, (382, 181, 3)) self.test_numpy_data(img, exp_min=25, exp_max=255, exp_mean=144.89) json_data = tar['userdata.json'] self.assertTrue('rgb_ratios' in json_data) expected_ratios = [ 0.29098381560041126, 0.3227735909047216, 0.3862425934948671 ] self.assertTrue(np.allclose(json_data['rgb_ratios'], expected_ratios))
class WMSRequest: # ************** True color (PNG) on a specific date ************** # bbox = [ 6887893.492833803, 5009377.085697314, 7200979.560689886, 5322463.153553395 ] # bbox = [46.16, -16.15, 46.51, -15.58] _bbox = BBox(bbox=bbox, crs=CRS.POP_WEB) geometry = Geometry( Polygon([(6887893.0, 5422463.0), (7200979.0, 5009377.0), (7210979, 5422463.0), (7200979.0, 5209377.0), (6887893.0, 5422463.0)]), CRS.POP_WEB) def request1(self): wms_request = FisRequest( layer='TRUE_COLOR', geometry_list=[self._bbox, self.geometry], # bbox=self._bbox, custom_url_params={CustomUrlParam.SHOWLOGO: False}, width=512, height=512, config=config) img = wms_request.get_data() # print(len(img)) # print(type(img)) # print(img) plot_image(img[-1]) # ************** True color of the latest acquisition ************** # def request2(self): wms_true_color_request = WmsRequest(layer='TRUE-COLOR', bbox=betsiboka_bbox, time='latest', width=512, height=856, config=config) wms_true_color_img = wms_true_color_request.get_data() plot_image(wms_true_color_img[-1]) print( 'The latest Sentinel-2 image of this area was taken on {}.'.format( wms_true_color_request.get_dates()[-1])) # ************** True color of the multiple acquisitions in certain time window ************** # def request3(self): wms_true_color_request = WmsRequest(layer='TRUE-COLOR', bbox=betsiboka_bbox, time=('2017-12-01', '2017-12-31'), width=512, height=856, config=config) wms_true_color_img = wms_true_color_request.get_data() print('There are %d Sentinel-2 images available for December 2017.' % len(wms_true_color_img)) plot_image(wms_true_color_img[2]) print('These %d images were taken on the following dates:' % len(wms_true_color_img)) for index, date in enumerate(wms_true_color_request.get_dates()): print(' - image %d was taken on %s' % (index, date)) # ************** True color of the multiple acquisitions in certain time window with cloud coverage less than 30% ************** # def request4(self): wms_true_color_request = WmsRequest(layer='TRUE-COLOR', bbox=betsiboka_bbox, time=('2017-12-01', '2017-12-31'), width=512, height=856, maxcc=0.3, config=config) wms_true_color_img = wms_true_color_request.get_data() print( 'There are %d Sentinel-2 images available for December 2017 with cloud coverage less ' 'than %1.0f%%.' % (len(wms_true_color_img), wms_true_color_request.maxcc * 100.0)) plot_image(wms_true_color_img[-1]) print('These %d images were taken on the following dates:' % len(wms_true_color_img)) for index, date in enumerate(wms_true_color_request.get_dates()): print(' - image %d was taken on %s' % (index, date)) # ************** All Sentinel-2’s raw band values ************** # def request5(self): wms_bands_request = WmsRequest(layer='BANDS-S2-L1C', bbox=betsiboka_bbox, time='2017-12-15', width=512, height=856, image_format=MimeType.TIFF_d32f, config=config) wms_bands_img = wms_bands_request.get_data() print("Shape:", wms_bands_img[-1][:, :, 12].shape) plot_image(wms_bands_img[-1][:, :, 12]) plot_image(wms_bands_img[-1][:, :, [3, 2, 1]], 2.5) # ************** All Sentinel-2’s raw band values ************** # def request6(self): wms_bands_request = WmsRequest(data_folder='test_dir', layer='BANDS-S2-L1C', bbox=betsiboka_bbox, time='2017-12-15', width=512, height=856, image_format=MimeType.TIFF_d32f, config=config) wms_bands_img = wms_bands_request.get_data(save_data=True) import os for folder, _, filenames in os.walk(wms_bands_request.data_folder): for filename in filenames: print(os.path.join(folder, filename)) wms_bands_request_from_disk = WmsRequest( data_folder='test_dir', layer='BANDS-S2-L1C', bbox=betsiboka_bbox, time='2017-12-15', width=512, height=856, image_format=MimeType.TIFF_d32f, config=config) wms_bands_img_from_disk = wms_bands_request_from_disk.get_data() if np.array_equal(wms_bands_img[-1], wms_bands_img_from_disk[-1]): print('Arrays are equal.') else: print('Arrays are different.') wms_bands_img_redownload = wms_bands_request_from_disk.get_data( redownload=True) # ************** Save downloaded data directly to disk ************** # def request7(self): wms_true_color_request = WmsRequest(data_folder='test_dir_tiff', layer='TRUE-COLOR', bbox=betsiboka_bbox, time=('2017-12-01', '2017-12-31'), width=512, height=856, image_format=MimeType.TIFF, config=config) wms_true_color_request.save_data() os.listdir(wms_true_color_request.data_folder) # ************** Merging two or more download requests into one ************** # def request8(self): print("asdasd") betsiboka_bbox_large = BBox([45.88, -16.12, 47.29, -15.45], crs=CRS.WGS84) wms_true_color_request = WmsRequest(layer='AGRICULTURE', bbox=betsiboka_bbox_large, time='2015-12-01', width=960, image_format=MimeType.PNG, config=config) wms_true_color_img = wms_true_color_request.get_data() plot_image(wms_true_color_img[0]) plot_image(wms_true_color_img[1]) wms_true_color_request_with_deltat = WmsRequest( layer='AGRICULTURE', bbox=betsiboka_bbox_large, time='2015-12-01', width=960, image_format=MimeType.PNG, time_difference=datetime.timedelta(hours=2), config=config) wms_true_color_img = wms_true_color_request_with_deltat.get_data() print('These %d images were taken on the following dates:' % len(wms_true_color_img)) for index, date in enumerate( wms_true_color_request_with_deltat.get_dates()): print(' - image %d was taken on %s' % (index, date)) plot_image(wms_true_color_img[-1])
def get_sampling_geometry(tile_info): return Geometry(shapely.geometry.shape(tile_info['coverGeometry']), crs=ShIndexSampling.get_crs(tile_info))