def extractor(image): # a time date = ee.Date(image.get('system:time_start')) # a place if not Atmcorr_input.geom: Atmcorr_input.geom = image.geometry().centroid() # atmospheric correction inputs atmcorr_inputs = ee.Dictionary({ 'solar_z':image.get('MEAN_SOLAR_ZENITH_ANGLE'), 'h2o':Atmospheric.water(Atmcorr_input.geom,date), 'o3':Atmospheric.ozone(Atmcorr_input.geom,date), 'aot':Atmospheric.aerosol(Atmcorr_input.geom,date), 'alt':Atmcorr_input.elevation.reduceRegion(\ reducer = ee.Reducer.mean(),\ geometry = Atmcorr_input.geom.centroid()).get('be75'), 'doy':Atmcorr_input.doy_from_date(date) }) # solar irradiance (to calculate at-sensor radiance from TOA) solar_irradiance = { 'B1': image.get('SOLAR_IRRADIANCE_B1'), 'B2': image.get('SOLAR_IRRADIANCE_B2'), 'B3': image.get('SOLAR_IRRADIANCE_B3'), 'B4': image.get('SOLAR_IRRADIANCE_B4'), 'B5': image.get('SOLAR_IRRADIANCE_B5'), 'B6': image.get('SOLAR_IRRADIANCE_B6'), 'B7': image.get('SOLAR_IRRADIANCE_B7'), 'B8': image.get('SOLAR_IRRADIANCE_B8'), 'B8A': image.get('SOLAR_IRRADIANCE_B8A'), 'B9': image.get('SOLAR_IRRADIANCE_B9'), 'B10': image.get('SOLAR_IRRADIANCE_B10'), 'B11': image.get('SOLAR_IRRADIANCE_B11'), 'B12': image.get('SOLAR_IRRADIANCE_B12') } # image identifier imgID = image.get('system:index') # properties properties = {'imgID':imgID,\ 'bandNames':['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7',\ 'B8', 'B8A', 'B9', 'B10', 'B11', 'B12'],\ 'atmcorr_inputs':atmcorr_inputs,\ 'solar_irradiance':solar_irradiance} return ee.Feature(Atmcorr_input.geom, properties)
def get(): altitude = AtmcorrInput.elevation.reduceRegion(\ reducer = ee.Reducer.mean(),\ geometry = TimeSeries.geom.centroid()\ ) return ee.Dictionary({ 'solar_z': mission_specifics.solar_z(TimeSeries.image, TimeSeries.mission), 'h2o': Atmospheric.water(TimeSeries.geom, TimeSeries.date), 'o3': Atmospheric.ozone(TimeSeries.geom, TimeSeries.date), 'aot': Atmospheric.aerosol(TimeSeries.geom, TimeSeries.date), 'alt': altitude.get('be75'), 'doy': TimeSeries.day_of_year })
# metadata info = S2.getInfo()['properties'] scene_date = datetime.datetime.utcfromtimestamp( info['system:time_start'] / 1000) # i.e. Python uses seconds, EE uses milliseconds date = ee.Date(scene_date) solar_z = info['MEAN_SOLAR_ZENITH_ANGLE'] #需要修改 geom = ee.Geometry.Point(125.266, 42.86) toa = S2.divide(10000) print(2) """atmospheric constituents""" h2o = Atmospheric.water(geom, date).getInfo() o3 = Atmospheric.ozone(geom, date).getInfo() aot = Atmospheric.aerosol(geom, date).getInfo() """target altitude (km)""" SRTM = ee.Image( 'CGIAR/SRTM90_V4' ) # Shuttle Radar Topography mission covers *most* of the Earth alt = SRTM.reduceRegion(reducer=ee.Reducer.mean(), geometry=geom.centroid()).get('elevation').getInfo() km = alt / 1000 # i.e. Py6S uses units of kilometers """6S object""" # Instantiate s = SixS() # Atmospheric constituents s.atmos_profile = AtmosProfile.UserWaterAndOzone(h2o, o3)
def TOAtoSR(self, img): #TDOMMask = img.select(['TDOMMask']) info = self.collectionMeta[self.env.feature]['properties'] scene_date = datetime.datetime.utcfromtimestamp( info['system:time_start'] / 1000) # i.e. Python uses seconds, EE uses milliseconds solar_z = info['MEAN_SOLAR_ZENITH_ANGLE'] geom = ee.Geometry(info['system:footprint']).centroid() #geom = ee.Geometry.Point([info['centroid']['coordinates'][0],info['centroid']['coordinates'][1]]) date = ee.Date.fromYMD(scene_date.year, scene_date.month, scene_date.day) h2o = Atmospheric.water(geom, date).getInfo() o3 = Atmospheric.ozone(geom, date).getInfo() aot = Atmospheric.aerosol(geom, date).getInfo() SRTM = ee.Image( 'CGIAR/SRTM90_V4' ) # Shuttle Radar Topography mission covers *most* of the Earth alt = SRTM.reduceRegion(reducer=ee.Reducer.mean(), geometry=geom).get('elevation').getInfo() if alt: km = alt / 1000 # i.e. Py6S uses units of kilometers else: km = 0 # Instantiate s = SixS() # Atmospheric constituents s.atmos_profile = AtmosProfile.UserWaterAndOzone(h2o, o3) s.aero_profile = AeroProfile.Continental s.aot550 = aot # Earth-Sun-satellite geometry s.geometry = Geometry.User() s.geometry.view_z = 0 # always NADIR (I think..) s.geometry.solar_z = solar_z # solar zenith angle s.geometry.month = scene_date.month # month and day used for Earth-Sun distance s.geometry.day = scene_date.day # month and day used for Earth-Sun distance s.altitudes.set_sensor_satellite_level() s.altitudes.set_target_custom_altitude(km) def spectralResponseFunction(bandname): """ Extract spectral response function for given band name """ bandSelect = { 'B1': PredefinedWavelengths.S2A_MSI_01, 'B2': PredefinedWavelengths.S2A_MSI_02, 'B3': PredefinedWavelengths.S2A_MSI_03, 'B4': PredefinedWavelengths.S2A_MSI_04, 'B5': PredefinedWavelengths.S2A_MSI_05, 'B6': PredefinedWavelengths.S2A_MSI_06, 'B7': PredefinedWavelengths.S2A_MSI_07, 'B8': PredefinedWavelengths.S2A_MSI_08, 'B8A': PredefinedWavelengths.S2A_MSI_09, 'B9': PredefinedWavelengths.S2A_MSI_10, 'B10': PredefinedWavelengths.S2A_MSI_11, 'B11': PredefinedWavelengths.S2A_MSI_12, 'B12': PredefinedWavelengths.S2A_MSI_13 } return Wavelength(bandSelect[bandname]) def toa_to_rad(bandname): """ Converts top of atmosphere reflectance to at-sensor radiance """ # solar exoatmospheric spectral irradiance ESUN = info['SOLAR_IRRADIANCE_' + bandname] solar_angle_correction = math.cos(math.radians(solar_z)) # Earth-Sun distance (from day of year) doy = scene_date.timetuple().tm_yday d = 1 - 0.01672 * math.cos( 0.9856 * (doy - 4) ) # http://physics.stackexchange.com/questions/177949/earth-sun-distance-on-a-given-day-of-the-year # conversion factor multiplier = ESUN * solar_angle_correction / (math.pi * d**2) # at-sensor radiance rad = img.select(bandname).multiply(multiplier) return rad def surface_reflectance(bandname): """ Calculate surface reflectance from at-sensor radiance given waveband name """ # run 6S for this waveband s.wavelength = spectralResponseFunction(bandname) s.run() # extract 6S outputs Edir = s.outputs.direct_solar_irradiance #direct solar irradiance Edif = s.outputs.diffuse_solar_irradiance #diffuse solar irradiance Lp = s.outputs.atmospheric_intrinsic_radiance #path radiance absorb = s.outputs.trans[ 'global_gas'].upward #absorption transmissivity scatter = s.outputs.trans[ 'total_scattering'].upward #scattering transmissivity tau2 = absorb * scatter #total transmissivity # radiance to surface reflectance rad = toa_to_rad(bandname) ref = rad.subtract(Lp).multiply(math.pi).divide(tau2 * (Edir + Edif)) return ref # all wavebands output = img.select('QA60') for band in [ 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B8A', 'B9', 'B10', 'B11', 'B12' ]: output = output.addBands(surface_reflectance(band)) self.env.feature += 1 return output.copyProperties(img, [ 'system:time_start', 'system:footprint', 'MEAN_SOLAR_ZENITH_ANGLE', 'MEAN_SOLAR_AZIMUTH_ANGLE' ])
def correctAts(self,image): keepBands = ['temp'] esun = {'TM': [1958.00,1827.00,1551.00,1036.00,214.90,80.65], 'ETM':[1969.00,1840.00,1551.00,1044.00,225.70,82.07], 'OLI':[2004.57,1820.75,1549.49, 951.76,247.55,85.46]} exportBands = ['blue','green','red','nir','swir1','swir2'] metaData = self.collectionMeta[self.feature]['properties'] sensorId = str(metaData['SENSOR_ID']) if len(sensorId) > 3: sensorId = sensorId.split('_')[0] sunAngle = 90-float(metaData['SUN_ELEVATION']) llLat = float(metaData['CORNER_LL_LAT_PRODUCT']) llLon = float(metaData['CORNER_LL_LON_PRODUCT']) ulLat = float(metaData['CORNER_UL_LAT_PRODUCT']) ulLon = float(metaData['CORNER_UL_LON_PRODUCT']) lrLat = float(metaData['CORNER_LR_LAT_PRODUCT']) lrLon = float(metaData['CORNER_LR_LON_PRODUCT']) urLat = float(metaData['CORNER_UR_LAT_PRODUCT']) urLon = float(metaData['CORNER_UR_LON_PRODUCT']) imgBounds = ee.Geometry.Polygon([[llLon,llLat],[ulLon,ulLat],[urLon,urLat],[lrLon,lrLat],[llLon,llLat]]) elv = ee.Image('CGIAR/SRTM90_V4') srtm = ee.Image(0).where(elv.gt(0),elv) #minAlt = np.abs(srtm.reduceRegion(reducer=ee.Reducer.min(),scale=90,geometry=imgBounds,maxPixels=9e9).get('elevation').getInfo()) maxAlt = np.abs(srtm.reduceRegion(reducer=ee.Reducer.max(),scale=90,geometry=imgBounds,maxPixels=9e9).get('constant').getInfo()) acqDate = metaData['DATE_ACQUIRED'].split('-') dateob = datetime.date(int(acqDate[0]),int(acqDate[1]),int(acqDate[2])) eeDate = ee.Date.fromYMD(int(acqDate[0]),int(acqDate[1]),int(acqDate[2])) doy = dateob.timetuple().tm_yday orbit_correction = 0.03275104*math.cos(doy/59.66638337) + 0.96804905 dsun = (1 - 0.01672 * math.cos(0.9856 * (doy - 4))) ** 2 atmoData = Atmospheric(imgBounds,eeDate) aot = atmoData.aerosol().getInfo() h2o = atmoData.water().getInfo() o3 = atmoData.ozone().getInfo() imgList = [] altRange = np.arange(0,maxAlt+60,15) for i in range(altRange.size): elvMask = srtm.gte(altRange[i]-7.5).And(srtm.lt(altRange[i]+7.5)) temp = image.updateMask(elvMask) outsr = image.select(keepBands) for j in range(len(self.bands)): a,b = self.luts[sensorId][self.bands[j]](sunAngle,h2o,o3,aot,(altRange[i]/1000.)) band = temp.select(self.bands[j]) denom = esun[sensorId][j]*math.cos(math.radians(sunAngle)) numer = math.pi * dsun radiance = band.multiply(ee.Number(denom)).divide(ee.Number(numer)) a *= orbit_correction b *= orbit_correction outsr = outsr.addBands((radiance.subtract(ee.Number(a)).divide(ee.Number(b))\ .rename([self.bands[j]]))) imgList.append(outsr.where(outsr.lt(0),0)) outImg = ee.ImageCollection(imgList).median().copyProperties(image,['system:time_start']) self.feature += 1 return outImg