-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathEarthEngineToGeoTIFF.py
More file actions
122 lines (94 loc) · 4.42 KB
/
EarthEngineToGeoTIFF.py
File metadata and controls
122 lines (94 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import zipfile
import os
import requests
import numpy as np
import ee
import rasterio
def getSentinalS2SRImage(lon, lat, sze, filename, dateMin = '2020-04-01', dateMax = '2020-04-30', vmin = 0, vmax = 3500):
'''
download an RGB image from the Sentinal S2 Surface Reflectance satellite, at the given coordinates
lon : central longitude in degrees
lat : central latitude in degrees
sze : size of the edge of the box in degrees
dateMin : minimum date to use for image search in year-month-day (e.g., 2020-08-01)
dateMax : maximum date to use for image search in year-month-day (e.g., 2020-08-31)
vMin : minimum value to select in the Sentinal image pixels (I think this should be close to 0)
vMax : maximum value to select in the Sentinal image pixels (I think this should be close to 3000)
filename : output filename for the GeoTIFF image
Note: it's possible that the vMin and vMax values should be different for each band to make the image look nicer
https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S2_SR
'''
print('Downloading Sentinel S2 Surface Reflectance satellite images ... ')
# define the area of interest, using the Earth Engines geometry object
coords = [
[lon - sze/2., lat - sze/2.],
[lon + sze/2., lat - sze/2.],
[lon + sze/2., lat + sze/2.],
[lon - sze/2., lat + sze/2.],
[lon - sze/2., lat - sze/2.]
]
aoi = ee.Geometry.Polygon(coords)
# get the image using Google's Earth Engine
db = ee.Image(ee.ImageCollection('COPERNICUS/S2_SR')\
.filterBounds(aoi)\
.filterDate(ee.Date(dateMin), ee.Date(dateMax))\
.sort('CLOUDY_PIXEL_PERCENTAGE')\
.first())
# add the latitude and longitude
db = db.addBands(ee.Image.pixelLonLat())
# define the bands that I want to use. B4 is red, B3 is green, B2 is blue
# https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S2_SR#bands
bands = ['B4', 'B3', 'B2']
# export geotiff images, these go to Drive and then are downloaded locally
for selection in bands:
task = ee.batch.Export.image.toDrive(image=db.select(selection),
description=selection,
scale=30,
region=aoi,
fileNamePrefix=selection,
crs='EPSG:4326',
fileFormat='GeoTIFF')
task.start()
url = db.select(selection).getDownloadURL({
'scale': 30,
'crs': 'EPSG:4326',
'fileFormat': 'GeoTIFF',
'region': aoi})
r = requests.get(url, stream=True)
filenameZip = selection+'.zip'
filenameTif = selection+'.tif'
# unzip and write the tif file, then remove the original zip file
with open(filenameZip, "wb") as fd:
for chunk in r.iter_content(chunk_size=1024):
fd.write(chunk)
zipdata = zipfile.ZipFile(filenameZip)
zipinfos = zipdata.infolist()
# iterate through each file (there should be only one)
for zipinfo in zipinfos:
zipinfo.filename = filenameTif
zipdata.extract(zipinfo)
zipdata.close()
# create a combined RGB geotiff image
# https://gis.stackexchange.com/questions/341809/merging-sentinel-2-rgb-bands-with-rasterio
print('Creating 3-band GeoTIFF image ... ')
# open the images
B2 = rasterio.open('B2.tif')
B3 = rasterio.open('B3.tif')
B4 = rasterio.open('B4.tif')
# get the scaling
image = np.array([B2.read(1), B3.read(1), B4.read(1)]).transpose(1,2,0)
p2, p98 = np.percentile(image, (2,98))
# use the B2 image as a starting point so that I keep the same parameters
B2_geo = B2.profile
B2_geo.update({'count': 3})
with rasterio.open(filename, 'w', **B2_geo) as dest:
dest.write( (np.clip(B4.read(1), p2, p98) - p2)/(p98 - p2)*255, 1)
dest.write( (np.clip(B3.read(1), p2, p98) - p2)/(p98 - p2)*255, 2)
dest.write( (np.clip(B2.read(1), p2, p98) - p2)/(p98 - p2)*255, 3)
B2.close()
B3.close()
B4.close()
# remove the intermediate files
for selection in bands:
os.remove(selection + '.tif')
os.remove(selection + '.zip')