# (2.5 or 3.5 generally is sufficient) dilatePixels = 2.5 # Choose the resampling method: 'near', 'bilinear', or 'bicubic' # Defaults to 'near' # If method other than 'near' is chosen, any map drawn on the fly that is not # reprojected, will appear blurred # Use .reproject to view the actual resulting image (this will slow it down) resampleMethod = 'near' # If available, bring in preComputed cloudScore offsets and TDOM stats # Set to null if computing on-the-fly is wanted # These have been pre-computed for all CONUS for Landsat and Setinel 2 (separately) # and are appropriate to use for any time period within the growing season # The cloudScore offset is generally some lower percentile of cloudScores on a pixel-wise basis preComputedCloudScoreOffset = getImagesLib.getPrecomputedCloudScoreOffsets( cloudScorePctl)['landsat'] # The TDOM stats are the mean and standard deviations of the two IR bands used in TDOM # By default, TDOM uses the nir and swir1 bands preComputedTDOMStats = getImagesLib.getPrecomputedTDOMStats() preComputedTDOMIRMean = preComputedTDOMStats['landsat']['mean'] preComputedTDOMIRStdDev = preComputedTDOMStats['landsat']['stdDev'] # correctIllumination: Choose if you want to correct the illumination using # Sun-Canopy-Sensor+C correction. Additionally, choose the scale at which the # correction is calculated in meters. correctIllumination = False correctScale = 250 #Choose a scale to reduce on- 250 generally works well # Export params # Whether to export composites
def getTimeSeriesSample(startYear, endYear, startJulian, endJulian, compositePeriod, exportBands, studyArea, nSamples, output_table_name, showGEEViz, maskSnow=False, programs=['Landsat', 'Sentinel2']): check_dir(os.path.dirname(output_table_name)) #If available, bring in preComputed cloudScore offsets and TDOM stats #Set to null if computing on-the-fly is wanted #These have been pre-computed for all CONUS for Landsat and Setinel 2 (separately) #and are appropriate to use for any time period within the growing season #The cloudScore offset is generally some lower percentile of cloudScores on a pixel-wise basis preComputedCloudScoreOffset = getImagesLib.getPrecomputedCloudScoreOffsets( 10) preComputedLandsatCloudScoreOffset = preComputedCloudScoreOffset['landsat'] preComputedSentinel2CloudScoreOffset = preComputedCloudScoreOffset[ 'sentinel2'] #The TDOM stats are the mean and standard deviations of the two bands used in TDOM #By default, TDOM uses the nir and swir1 bands preComputedTDOMStats = getImagesLib.getPrecomputedTDOMStats() preComputedLandsatTDOMIRMean = preComputedTDOMStats['landsat']['mean'] preComputedLandsatTDOMIRStdDev = preComputedTDOMStats['landsat']['stdDev'] preComputedSentinel2TDOMIRMean = preComputedTDOMStats['sentinel2']['mean'] preComputedSentinel2TDOMIRStdDev = preComputedTDOMStats['sentinel2'][ 'stdDev'] ##################################################################################### #Function Calls #Get all images try: saBounds = studyArea.geometry().bounds() except: saBounds = studyArea.bounds() #Sample the study area randomSample = ee.FeatureCollection.randomPoints(studyArea, nSamples, 0, 50) Map.addLayer(randomSample, {"layerType": "geeVector"}, 'Samples', True) dummyImage = None for yr in range(startYear, endYear + 1): output_table_nameT = '{}_{}_{}_{}-{}_{}_{}{}'.format( os.path.splitext(output_table_name)[0], '-'.join(programs), yr, startJulian, endJulian, compositePeriod, nSamples, os.path.splitext(output_table_name)[1]) if not os.path.exists(output_table_nameT): if 'Landsat' in programs and 'Sentinel2' in programs: if dummyImage == None: dummyImage = ee.Image(getImagesLib.getProcessedLandsatAndSentinel2Scenes(saBounds,\ 2019,\ 2020,\ 1,\ 365).first()) images = getImagesLib.getProcessedLandsatAndSentinel2Scenes(saBounds,\ yr,\ yr,\ startJulian,\ endJulian,\ toaOrSR = 'TOA', includeSLCOffL7 = True, ) elif 'Sentinel2' in programs: if dummyImage == None: dummyImage = ee.Image(getImagesLib.getProcessedSentinel2Scenes(saBounds,\ 2019,\ 2020,\ 1,\ 365).first()) images = getImagesLib.etProcessedSentinel2Scenes(saBounds,\ yr,\ yr,\ startJulian,\ endJulian) elif 'Landsat' in programs: if dummyImage == None: dummyImage = ee.Image(getImagesLib.getProcessedLandsatScenes(saBounds,\ 2019,\ 2020,\ 1,\ 365).first()) images = getImagesLib.getProcessedLandsatScenes( saBounds,\ yr,\ yr,\ startJulian,\ endJulian,\ toaOrSR = 'TOA', includeSLCOffL7 = True) images = getImagesLib.fillEmptyCollections(images, dummyImage) #Vizualize the median of the images # Map.addLayer(images.median(),vizParamsFalse,'Median Composite '+str(yr),False) #Mask snow if maskSnow: print('Masking snow') images = images.map(getImagesLib.sentinel2SnowMask) #Add greenness ratio/indices images = images.map(getImagesLib.HoCalcAlgorithm2) # Map.addLayer(images.select(exportBands),{},'Raw Time Series ' + str(yr),True) #Convert to n day composites composites = getImagesLib.nDayComposites(images, yr, yr, 1, 365, compositePeriod) # Map.addLayer(composites.select(exportBands),{},str(compositePeriod) +' day composites '+str(yr)) #Convert to a stack stack = composites.select(exportBands).toBands() #Fix band names to be yyyy_mm_dd bns = stack.bandNames() bns = bns.map( lambda bn: ee.String(bn).split('_').slice(1, None).join('_')) stack = stack.rename(bns) #Start export table thread tt = threading.Thread(target=getTableWrapper, args=(stack, randomSample, output_table_nameT)) tt.start() time.sleep(0.1) threadLimit = 1 if showGEEViz: #Vizualize outputs Map.addLayer(studyArea, {'strokeColor': '00F'}, 'Study Area') Map.centerObject(studyArea) Map.view() threadLimit = 2 limitThreads(threadLimit)
# Defaults to 'aggregate' # Aggregate is generally useful for aggregating pixels when reprojecting instead of resampling # A good example would be reprojecting S2 data to 30 m # If method other than 'near' is chosen, any map drawn on the fly that is not # reprojected, will appear blurred or not really represented properly # Use .reproject to view the actual resulting image (this will slow it down) resampleMethod = 'aggregate' # If available, bring in preComputed cloudScore offsets and TDOM stats # Set to None if computing on-the-fly is wanted # These have been pre-computed for all CONUS for Landsat and Setinel 2 (separately) # and are appropriate to use for any time period within the growing season # The cloudScore offset is generally some lower percentile of cloudScores on a pixel-wise basis preComputedCloudScoreOffset = getImagesLib.getPrecomputedCloudScoreOffsets( cloudScorePctl)['sentinel2'] # The TDOM stats are the mean and standard deviations of the two IR bands used in TDOM # By default, TDOM uses the nir and swir1 bands preComputedTDOMStats = getImagesLib.getPrecomputedTDOMStats() preComputedTDOMIRMean = preComputedTDOMStats['sentinel2']['mean'] preComputedTDOMIRStdDev = preComputedTDOMStats['sentinel2']['stdDev'] # Export params # Whether to export composites exportComposites = False # Set up Names for the export outputName = 'Sentinel2'
#final deliverables for local viewing #Intended to work within the geeViz package # python -m pip install geeViz #Also requires gdal #################################################################################################### import geeViz.getImagesLib as getImagesLib import geeViz.taskManagerLib as tml ee = getImagesLib.ee Map = getImagesLib.Map import make_esri_viewer as mew import json, os, threading, time, glob from osgeo import gdal ################################################## #Bring in some existing assets to use for cloud masking preComputedCloudScoreOffset = getImagesLib.getPrecomputedCloudScoreOffsets(10) preComputedLandsatCloudScoreOffset = preComputedCloudScoreOffset['landsat'] preComputedSentinel2CloudScoreOffset = preComputedCloudScoreOffset['sentinel2'] #The TDOM stats are the mean and standard deviations of the two bands used in TDOM #By default, TDOM uses the nir and swir1 bands preComputedTDOMStats = getImagesLib.getPrecomputedTDOMStats() preComputedLandsatTDOMIRMean = preComputedTDOMStats['landsat']['mean'] preComputedLandsatTDOMIRStdDev = preComputedTDOMStats['landsat']['stdDev'] preComputedSentinel2TDOMIRMean = preComputedTDOMStats['sentinel2']['mean'] preComputedSentinel2TDOMIRStdDev = preComputedTDOMStats['sentinel2']['stdDev'] ############################################################################ #On-the-fly basic water masking method