def download_timeseries_from_polygon(polygon: Polygon, start, end, num, evalscript=true_color, maxcc=None, size=None, resolution=None): slots = create_slots(start, end, num) if size and resolution: print( "Both size and resolution parameters can't be used together. Using size." ) if resolution and size is None: bbox = polygon.exterior.bounds size = bbox_to_dimensions(BBox(bbox, CRS.WGS84), resolution) polygon = geometry.Geometry(polygon, CRS.WGS84) return download_image_series(slots, evalscript, maxcc=maxcc, size=size, polygon=polygon)
def main(): # set configuration CLIENT_ID = '' CLIENT_SECRET = '' config = SHConfig() if CLIENT_ID and CLIENT_SECRET: config.sh_client_id = CLIENT_ID config.sh_client_secret = CLIENT_SECRET if config.sh_client_id == '' or config.sh_client_secret == '': print( "Warning! To use Sentinel Hub services, please provide the credentials (client ID and client secret)." ) # set coordinates, bounding box and a resolution (Naklo) TODO -> use input coordinates # [Longitude (x1), Latitude (y1) ... ] # betsiboka_coords_wgs84 = [14.2864, 46.2335, 14.3741, 46.2912] # Naklo betsiboka_coords_wgs84 = [14.3964, 46.2369, 14.4555, 46.2744] resolution = 10 betsiboka_bbox = BBox(bbox=betsiboka_coords_wgs84, crs=CRS.WGS84) betsiboka_size = bbox_to_dimensions(betsiboka_bbox, resolution=resolution) print(f'Image shape at {resolution} m resolution: {betsiboka_size} pixels') # get snow and vegetation data weatherDragons(betsiboka_coords_wgs84)
def execute(self, eopatch=None, bbox=None, time_interval=None): """ Main execute method for the Processing API tasks """ if eopatch is not None and (bbox or time_interval): raise ValueError( 'Either an eopatch must be provided or bbox and time interval, not both.' ) if eopatch is None: eopatch = EOPatch() eopatch.bbox = bbox if self.size is not None: size_x, size_y = self.size elif self.resolution is not None: size_x, size_y = bbox_to_dimensions(eopatch.bbox, self.resolution) if time_interval: time_interval = parse_time_interval(time_interval) timestamp = self._get_timestamp(time_interval, bbox) else: timestamp = None if eopatch.timestamp: self.check_timestamp_difference(timestamp, eopatch.timestamp) elif timestamp: eopatch.timestamp = timestamp payloads = self._build_payloads(bbox, size_x, size_y, timestamp, time_interval) requests = [ DownloadRequest(post_values=payload, **self.request_args) for payload in payloads ] LOGGER.debug('Downloading %d requests of type %s', len(requests), str(self.data_source)) client = SentinelHubDownloadClient(config=self.config) images = client.download(requests, max_threads=self.max_threads) LOGGER.debug('Downloads complete') temporal_dim = len(timestamp) if timestamp else 1 shape = temporal_dim, size_y, size_x self._extract_data(eopatch, images, shape) eopatch.meta_info['size_x'] = size_x eopatch.meta_info['size_y'] = size_y eopatch.meta_info['time_interval'] = time_interval eopatch.meta_info['service_type'] = 'processing' self._add_meta_info(eopatch) return eopatch
def sentinel_request(coords, date_range): resolution = 30 fire_bbox = BBox(bbox=coords, crs=CRS.WGS84) fire_box_size = bbox_to_dimensions(fire_bbox, resolution=resolution) print(f'Image shape at {resolution} m resolution: {fire_box_size} pixels') evalscript_true_color = """ //VERSION=3 function setup() { return { input: [{ bands: ["B02", "B03", "B04"] }], output: { bands: 3 } }; } function evaluatePixel(sample) { return [sample.B04, sample.B03, sample.B02]; } """ request_true_color = SentinelHubRequest( evalscript=evalscript_true_color, input_data=[ SentinelHubRequest.input_data(data_source=DataSource.LANDSAT8_L1C, time_interval=date_range, mosaicking_order='leastCC') ], responses=[ SentinelHubRequest.output_response('default', MimeType.PNG) ], bbox=fire_bbox, size=fire_box_size, config=config) true_color_imgs = request_true_color.get_data() print( f'Returned data is of type = {type(true_color_imgs)} and length {len(true_color_imgs)}.' ) print( f'Single element in the list is of type {type(true_color_imgs[-1])} and has shape {true_color_imgs[-1].shape}' ) image = true_color_imgs[0] print(f'Image type: {image.dtype}') return image
def _get_size(self, eopatch): """Get the size (width, height) for the request either from inputs, or from the (existing) eopatch""" if self.size is not None: return self.size if self.resolution is not None: return bbox_to_dimensions(eopatch.bbox, self.resolution) if eopatch.meta_info and eopatch.meta_info.get( 'size_x') and eopatch.meta_info.get('size_y'): return eopatch.meta_info.get('size_x'), eopatch.meta_info.get( 'size_y') raise ValueError( 'Size or resolution for the requests should be provided!')
def execute(self, eopatch=None, bbox=None, time_interval=None): """ Main execute method for the Processing API tasks """ eopatch = eopatch or EOPatch() self._check_and_set_eopatch_bbox(bbox, eopatch) if self.size is not None: size_x, size_y = self.size elif self.resolution is not None: size_x, size_y = bbox_to_dimensions(eopatch.bbox, self.resolution) if time_interval: time_interval = parse_time_interval(time_interval) timestamp = self._get_timestamp(time_interval, eopatch.bbox) else: timestamp = eopatch.timestamp if eopatch.timestamp: self.check_timestamp_difference(timestamp, eopatch.timestamp) elif timestamp: eopatch.timestamp = timestamp requests = self._build_requests(eopatch.bbox, size_x, size_y, timestamp, time_interval) requests = [request.download_list[0] for request in requests] LOGGER.debug('Downloading %d requests of type %s', len(requests), str(self.data_source)) client = SentinelHubDownloadClient(config=self.config) images = client.download(requests, max_threads=self.max_threads) LOGGER.debug('Downloads complete') temporal_dim = len(timestamp) if timestamp else 1 shape = temporal_dim, size_y, size_x self._extract_data(eopatch, images, shape) eopatch.meta_info['size_x'] = size_x eopatch.meta_info['size_y'] = size_y eopatch.meta_info['time_interval'] = time_interval eopatch.meta_info['service_type'] = 'processing' self._add_meta_info(eopatch) return eopatch
def _get_raster_shape(self, eopatch): """ Determines the shape of new raster feature, returns a pair (height, width) """ if isinstance(self.raster_shape, (tuple, list)) and len(self.raster_shape) == 2: if isinstance(self.raster_shape[0], int) and isinstance(self.raster_shape[1], int): return self.raster_shape feature_type, feature_name = next(self._parse_features(self.raster_shape)(eopatch)) return eopatch.get_spatial_dimension(feature_type, feature_name) if self.raster_resolution: resolution = float(self.raster_resolution.strip('m')) if isinstance(self.raster_resolution, str) else \ self.raster_resolution width, height = bbox_to_dimensions(eopatch.bbox, resolution) return height, width raise ValueError('Could not determine shape of the raster image')
def checkSize(coords, resolution): """ This function allows you to try out different bounaries and resolutions to make sure it will work with the Sentinel API (restricted to 2500x2500 or less). Also creates the objects necessary to make the image request. Parameters ---------- coords : List containing the northwest corner and southeast corner coordinates of area box. resolution : How many meters each pixel should represent in satellite image. Returns ------- bbox : An object that is needed for gathering satellite image from Sentinel API size : List with height and width of image in pixels. The limit is 2500 for each. """ bbox = BBox(bbox=coords, crs=CRS.WGS84) size = bbox_to_dimensions(bbox, resolution=resolution) return bbox, size
def do_magic(lat, lng): payload = {} # set configuration CLIENT_ID = '' CLIENT_SECRET = '' config = SHConfig() if CLIENT_ID and CLIENT_SECRET: config.sh_client_id = CLIENT_ID config.sh_client_secret = CLIENT_SECRET if config.sh_client_id == '' or config.sh_client_secret == '': print( "Warning! To use Sentinel Hub services, please provide the credentials (client ID and client secret)." ) # set coordinates, bounding box and a resolution (Naklo) TODO -> use input coordinates # [Longitude (x1), Latitude (y1) ... ] # betsiboka_coords_wgs84 = [14.2864, 46.2335, 14.3741, 46.2912] # Naklo # betsiboka_coords_wgs84 = [14.3964, 46.2369, 14.4555, 46.2744] # Sencur bbox = get_bounding_box(lat, lng, 5000) payload['bbox'] = [[bbox[0], bbox[3]], [bbox[2], bbox[1]]] #if 1 == 1: # return payload resolution = 20 betsiboka_bbox = BBox(bbox=bbox, crs=CRS.WGS84) betsiboka_size = bbox_to_dimensions(betsiboka_bbox, resolution=resolution) print(f'Image shape at {resolution} m resolution: {betsiboka_size} pixels') # get snow and vegetation data weatherData = weatherDragons(bbox) payload['weather'] = weatherData vegData = snowyVegetation(betsiboka_bbox, betsiboka_size, config) payload['vegetation'] = vegData return payload
def setup_bbox(self, input_bbox): """ Prepares the bbox for use with Sentinel Hub :param input_bbox: list, tuple or sentinelhub.Bbox. If hashable type: xmin, ymin, xmax, ymax :return: nothing """ try: x = input_bbox.min_x except AttributeError: # it's tuple or list x, y = input_bbox[0], input_bbox[3] if x <= 180 and y <= 90: # given as lon lat upper_left_utm = utm.from_latlon(y, x) lower_right_utm = utm.from_latlon(input_bbox[2], input_bbox[1]) hemisphere = "N" if y >= 0 else "S" crs = CRS["UTM_" + str(upper_left_utm[2]) + hemisphere] input_bbox = (upper_left_utm[0], lower_right_utm[1], lower_right_utm[0], upper_left_utm[1]) self.bbox = BBox(bbox=input_bbox, crs=crs) else: raise ValueError("bbox not EPSG:4326") else: self.bbox = input_bbox self.bbox_size = bbox_to_dimensions(self.bbox, resolution=self.resolution)
def download_timeseries_from_bbox(bbox, start, end, num, evalscript=true_color, maxcc=None, size=None, resolution=None): slots = create_slots(start, end, num) bbox = BBox(bbox=bbox, crs=CRS.WGS84) if size and resolution: print( "Both size and resolution parameters can't be used together. Using size." ) if resolution and size is None: size = bbox_to_dimensions(bbox, resolution) return download_image_series(slots, evalscript, maxcc=maxcc, size=size, bbox=bbox)
ep.plot_rgb(arr_stack, rgb=[4, 3, 1], stretch=True, figsize=(20, 20)) plt.savefig('edata') # In[2]: #sentinel2 processing config = SHConfig() CLIENT_SECRET = 'm*JW}?-76bBH)PjZp:-sW,3ISibK)mfh0GPc])n^' CLIENT_ID = 'edb4f750-7cb2-475c-b190-3406e33de291' config.sh_client_id = CLIENT_ID config.sh_client_secret = CLIENT_SECRET usa_bbox = -118.572693, 34.002581, -118.446350, 34.057211 resolution = 60 bbox = BBox(bbox=usa_bbox, crs=CRS.WGS84) size = bbox_to_dimensions(bbox, resolution=resolution) evalscript_true_color = """ //VERSION=3 function setup() { return { input: [{ bands: ["B02", "B03", "B04"] }], output: { bands: 3 } }; } function evaluatePixel(sample) { return [sample.B04, sample.B03, sample.B02];
month=7, day=30) sentinelhub_test_request = SentinelHubRequest( evalscript=evalscript, input_data=[ SentinelHubRequest.input_data( data_collection=DataCollection.SENTINEL2_L1C, time_interval=time_interval) ], responses=[ SentinelHubRequest.output_response('NDVI', MimeType.TIFF), SentinelHubRequest.output_response('data_mask', MimeType.TIFF) ], bbox=test_bbox, size=bbox_to_dimensions(test_bbox, 10), config=config) results = sentinelhub_test_request.get_data()[0] print(f'Output data: {list(results)}') plt.imshow(results['NDVI.tif'][..., 2]) # 1.2 Select a tiling grid list(SentinelHubBatch.iter_tiling_grids(config=config)) GRID_ID = 1 SentinelHubBatch.get_tiling_grid(GRID_ID, config=config) # 1.3 Set up an S3 bucket
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))
def pull_images(coords): """ Pulls satellite images with the respective parameters from sentinel hub services and stores them in the data folder. :param coords: coordinates of RoI """ bbox = BBox(bbox=coords, crs=CRS.WGS84) size = bbox_to_dimensions(bbox, resolution=config.RES) # create data directory to store pulled data data_path = os.path.join(os.getcwd(), 'data') if not os.path.exists(data_path): os.mkdir(data_path) print(f'Image shape at {config.RES} m resolution: {size} pixels') evalscript_true_color = """ //VERSION=3 function setup() { return { input: [{ bands: ["B02", "B03", "B04", "B08"] }], output: { bands: 4 } }; } function evaluatePixel(sample) { //return [3.5*sample.B04, 3.5*sample.B03, 3.5*sample.B02]; return [sample.B02, sample.B03, sample.B04, sample.B08]; } """ for year_idx in range(len(config.START_DATES)): start_date = config.START_DATES[year_idx] end_date = config.END_DATES[year_idx] for date in daterange(datetime.strptime(start_date, "%Y-%m-%d"), datetime.strptime(end_date, "%Y-%m-%d")): folder = os.path.join( os.path.join(data_path, date.strftime("%Y_%m_%d"))) request_bands = SentinelHubRequest( evalscript=evalscript_true_color, input_data=[ SentinelHubRequest.input_data( data_source=DataSource.SENTINEL2_L1C, time_interval=(date, date + timedelta(days=config.ORBITAL_PERIOD)), maxcc=0.0 # maximum cloud coverage of 0% ) ], responses=[ SentinelHubRequest.output_response('default', MimeType.PNG) ], bbox=bbox, size=size, data_folder=folder, config=authorize()) # request the bands and save as numpy file try: bands = request_bands.get_data() bands_data = bands[0].astype(int) height, width, channels = bands_data.shape if ((np.count_nonzero(bands_data) / (height * width * channels)) < 0.5): continue request_bands.save_data() np.save(os.path.join(folder, "bands.npy"), bands_data) except Exception as e: print(f'Could not fetch an image for date {date}.', e)
Utility function for plotting RGB images. """ fig = plt.subplots(nrows=1, ncols=1, figsize=(15, 7)) if np.issubdtype(image.dtype, np.floating): plt.imshow(np.minimum(image * factor, 1)) else: plt.imshow(image) plt.show() betsiboka_coords_wgs84 = [46.16, -16.15, 46.51, -15.58] resolution = 60 betsiboka_bbox = BBox(bbox=betsiboka_coords_wgs84, crs=CRS.WGS84) betsiboka_size = bbox_to_dimensions(betsiboka_bbox, resolution=resolution) # print(f'Image shape at {resolution} m resolution: {betsiboka_size} pixels') evalscript_true_color = """ //VERSION=3 function setup() { return { input: [{ bands: ["B02", "B03", "B04"] }], output: { bands: 3 } };
def getVars(): if request.method == 'POST': jsonData = request.get_json() longitude = float(jsonData['longitude']) latitude = float(jsonData['latitude']) distance = float(jsonData['distance']) coords = [(longitude - (distance / 2)), (latitude - (distance / 2)), (longitude + (distance / 2)), (latitude + (distance / 2))] bbbox = BBox(coords, crs=CRS.WGS84) bsize = bbox_to_dimensions(bbbox, resolution=15) evalscript_clm = """ //VERSION=3 function setup() { return { input: ["B02", "B03", "B04", "CLM"], output: { bands: 3 } } } function evaluatePixel(sample) { if (sample.CLM == 1) { return [0.75 + sample.B04, sample.B03, sample.B02] } return [3.5*sample.B04, 3.5*sample.B03, 3.5*sample.B02]; } """ request_true_color = SentinelHubRequest( evalscript=evalscript_clm, input_data=[ SentinelHubRequest.input_data( data_collection=DataCollection.SENTINEL2_L1C, time_interval=('2020-06-01', '2020-06-30'), mosaicking_order='leastCC') ], responses=[ SentinelHubRequest.output_response('default', MimeType.PNG) ], bbox=bbbox, size=bsize, config=config) data_with_cloud_mask = request_true_color.get_data() image = data_with_cloud_mask[0] #print(image) plot_image(image, factor=1 / 255, clip_range=(0, 1)) # plt.show() imagename = "C:\\Users\desai\programs\plot2.png" image = cv2.imread(imagename, cv2.IMREAD_COLOR) ## Read image file #print(imagename) print("test") #boundaries detects foliage from green to almost white boundaries = [([27, 0, 98], [252, 229, 210])] for (lower, upper) in boundaries: # create NumPy arrays from the boundaries lower = np.array(lower, dtype="uint8") upper = np.array(upper, dtype="uint8") # find the colors within the specified boundaries and apply # the mask mask = cv2.inRange(image, lower, upper) output = cv2.bitwise_and(image, image, mask=mask) # show the images cv2.imshow("images", np.hstack([image, output])) cv2.waitKey(0) #boundary2 detects water from dark blue to light print("here") boundaries2 = [([32, 0, 4], [184, 104, 112])] for (lower, upper) in boundaries2: # create NumPy arrays from the boundaries lower2 = np.array(lower, dtype="uint8") upper2 = np.array(upper, dtype="uint8") # find the colors within the specified boundaries and apply # the mask mask2 = cv2.inRange(image, lower2, upper2) output2 = cv2.bitwise_and(image, image, mask=mask2) # show the images cv2.imshow("images", np.hstack([image, output2])) cv2.waitKey(0) #counts number of pixels in the boundaries nPixels = np.count_nonzero(mask == 0) count = mask.size #percentage = the percentage of pixels deemed bad soil, or not able to support trees - this could include water, dry land, etc percentage = nPixels / count nPixels2 = np.count_nonzero(mask2 == 0) count2 = mask2.size percentage2 = nPixels2 / count2 #percentage2 = the percentage of pixels that are not deemed overcrowded by vegetation print("The percent of land that is deemed unpplantable for tree is: " + str(percentage * 100) + "%") print( "The percent of land that is not overcrowded by dense vegetation is: " + str(percentage2 * 100) + "%") if percentage > 0.9: return "The soil is not suitable for trees" if percentage2 < 0.3: return "There is to much vegetation to plant a tree" if percentage < 0.9 and percentage2 > 0.3: return "This land is suitable for trees"
bands=('W', ), is_timeless=False) print(DataCollection.CUSTOM_SENTINEL1) # define a new BYOC data collection collection_id = '7453e962-0ee5-4f74-8227-89759fbe9ba9' byoc = DataCollection.define_byoc(collection_id, name='SLOVENIA_LAND_COVER', is_timeless=True) print(byoc.__dir__) # load data for the defined BYOC data collection slovenia_bbox = BBox([13.35882, 45.402307, 16.644287, 46.908998], crs=CRS.WGS84) slovenia_size = bbox_to_dimensions(slovenia_bbox, resolution=240) evalscript_byoc = """ //VERSION=3 function setup() { return { input: ["lulc_reference"], output: { bands: 3 } }; } var colorDict = { 0: [255/255, 255/255, 255/255], 1: [255/255, 255/255, 0/255], 2: [5/255, 73/255, 7/255], 3: [255/255, 165/255, 0/255],