GEE批量上传本地tif到ImageCollection的几种方法
引言
GEE(Google Earth Engine)允许用户在云端存储、处理和分析遥感数据。
在GEE平台上上传本地TIF格式的遥感影像数据进行处理有以下优势:
-
高效性:GEE平台基于云计算技术,可以在分布式的计算资源上同时处理多个任务,大大提高了数据处理的效率。相比本地计算,GEE平台能够更快地完成数据处理和分析任务。
-
大规模数据处理:GEE平台具有强大的分布式数据处理能力,支持处理海量数据,可以轻松地处理大规模的遥感影像数据,提高了数据处理的效率。
-
多种算法:GEE平台支持多种常见的遥感影像处理算法,包括影像分类、变化检测、图像重建等等,用户可以根据自己的需求选择适合的算法进行处理。
总的来说,GEE平台上传本地TIF进行处理可以大大提高数据处理的效率和精度,让用户更加方便地进行遥感数据分析和应用。
一般来说,影像不多时,一张一张点击即可:

但当影像有几十张几百张时,无法批量上传,本文提出了几种方法。
按推荐程度,有如下几种方法进行批量
-
合成多波段(最推荐) -
geebam批量上传(次推荐,受网络问题影响) -
存储桶批量上传(不推荐,需要信用卡,且对TIF有要求)
合成多波段
既然无法批量上传,那么只要把多张TIF合成一张多波段就好了
假设已经有了很多单波段TIF:

用rasterio
的一些功能合成多波段影像,并重命名每个波段,代码如下:
import glob
names = glob.glob('D:/Acdemic/xibei/grace/tif/2018/*.tif')
#print(names)
date = [x.split('\\')[-1][0:9] for x in names]
#print(date)
import rasterio
from osgeo import gdal
import numpy as np
# 读取多个单波段的tif影像
src_files_to_mosaic = names
# 打开并读取所有单波段的tif影像
src_files = []
for file in src_files_to_mosaic:
ds = gdal.Open(file)
im_proj = ds.GetProjection()
im_width = ds.RasterXSize #栅格矩阵的列数
im_height = ds.RasterYSize #栅格矩阵的行数
im_data = ds.ReadAsArray(0, 0, im_width, im_height)
src_files.append(im_data)
src_files = np.array(src_files)
metadata = {
'driver': 'GTiff',
'count': src_files.shape[0],
'dtype': src_files.dtype,
'height': src_files.shape[1],
'width': src_files.shape[2],
'transform': rasterio.transform.from_bounds(-180, -90, 180, 90, src_files.shape[2], src_files.shape[1]),
'crs': rasterio.crs.CRS.from_epsg(4326)
}
#band_names = date
#metadata["band_names"] = band_names
with rasterio.open('D:/Acdemic/xibei/grace/tif/2018/GRACE2018.tif', 'w', **metadata) as dst:
dst.write(src_files)
dst.descriptions = tuple(date)
上述代码让我们创建多波段TIF,并为每个波段重命名

把上述多波段TIF上传至GEE

打印上传的多波段TIF,发现波段命名并不对

-
日期属性对于ImageCollection是十分重要的 -
想办法为每个Image添加时间属性 -
如果文件是均匀的时间,写个循环就行了,但是不均匀的情况下

-
如果能把文件对应的时间提取下来,上传至GEE,循环匹配就行了
说干就干!
提取MetaData
提取一个metadata记录下每个system:time_start
用python代码:
第一步,提取文件夹下的所有文件名
import glob
names = glob.glob('D:/Acdemic/xibei/grace/tif/2017/*.tif')
#print(names)
date = [x.split('\\')[-1][0:9] for x in names]
print(date)

第二步,根据文件名提取id和system:time_start
import time
from datetime import datetime, timedelta
id_no = date
system_time_start = [(datetime.strptime(x, 'A%Y%m%d') - datetime.strptime('19700101', '%Y%m%d')).days * 86400000 for x in date]
import pandas as pd
df = pd.DataFrame(columns=['id_no', 'system:time_start'])
df['id_no'] = id_no
df['system:time_start'] = system_time_start
df.to_csv('D:/Acdemic/xibei/grace/tif/2017/metadata2017.csv')
打印df,发现是这样:
id_no | system:time_start | |
---|---|---|
0 | A20170102 | 1483315200000 |
1 | A20170109 | 1483920000000 |
2 | A20170116 | 1484524800000 |
3 | A20170123 | 1485129600000 |
4 | A20170130 | 1485734400000 |
5 | A20170206 | 1486339200000 |
6 | A20170213 | 1486944000000 |
7 | A20170220 | 1487548800000 |
8 | A20170227 | 1488153600000 |
9 | A20170306 | 1488758400000 |
...... | ...... | ...... |
但是GEE是不能上传csv属性信息的:

上面的csv只适用于上传经纬度点
那么如何上传属性信息呢?有一个小技巧是用FeatureCollection
实现,即上传一个shp
,然后录入属性信息即可,然后再把这些属性信息get()
出来为我们所用
制作属性信息shp
使用geopandas很轻松地实现
因为我们已经有了属性df
,只需要添加空间信息,就能创建一个geopandas
,即gdf
import geopandas as gpd
from shapely.geometry import Point
geometry = [Point(0, 0) for i in range(len(df))]
gdf = gpd.GeoDataFrame(df, crs='EPSG:4326', geometry=geometry)
gdf
打印下来如表所示:
id_no | system:time_start | geometry | |
---|---|---|---|
0 | A20170102 | 1483315200000 | POINT (0.00000 0.00000) |
1 | A20170109 | 1483920000000 | POINT (0.00000 0.00000) |
2 | A20170116 | 1484524800000 | POINT (0.00000 0.00000) |
3 | A20170123 | 1485129600000 | POINT (0.00000 0.00000) |
4 | A20170130 | 1485734400000 | POINT (0.00000 0.00000) |
5 | A20170206 | 1486339200000 | POINT (0.00000 0.00000) |
6 | A20170213 | 1486944000000 | POINT (0.00000 0.00000) |
7 | A20170220 | 1487548800000 | POINT (0.00000 0.00000) |
8 | A20170227 | 1488153600000 | POINT (0.00000 0.00000) |
9 | A20170306 | 1488758400000 | POINT (0.00000 0.00000) |
...... | ...... | ...... | ...... |
gdf.to_file('D:/Acdemic/xibei/grace/tif/2017/mete2017.shp', driver='ESRI Shapefile')
导出后,将刚刚导出的shp上传

上传后的影像综合处理
现在有以下数据:
-
上传后的多波段Image(未进行波段命名,未添加属性信息) -
带有属性的FeatureCollection
用以下GEE代码进行综合处理,重新命名波段,添加system:time_start
,求月平均值
var image = ee.Image("projects/ee-wang/assets/dryland/GRACE2017"),
table = ee.FeatureCollection("projects/ee-wang/assets/dryland/mete2017");
var pkg_print = require('users/wanglonghao/pkgs:pkg_print');
var pkg_trend = require('users/wanglonghao/PML:pkg_trend');
var numList = ee.List.sequence(0, table.size().add(-1))
var tableList = table.toList(100)
var imgList = numList.map(function(num){
var fea = ee.Feature(tableList.get(num))
return ee.Image(image.select([num])).rename(ee.String(fea.get('id_no')))
.set("system:time_start", fea.get('system_tim'))
})
var imgCol = ee.ImageCollection(imgList)
var imgCol =imgCol//
.map(pkg_trend.add_dn(false, 8)).select([0], ['grace']);
var imgCol = pkg_trend.aggregate_prop(imgCol, 'month', 'mean')
其中pkg_trend
是自己的包,pkg_trend.add_dn
用于添加属性值,pkg_trend.aggregate_prop
用于按属性求平均值。
这样就计算好了月平均值

geebam批量上传
https://github.com/tracek/gee_asset_manager
先把这个打包下载下来

cd D:\Onedrive\gee_asset_manager-master
D:
在geemap环境里先注册一下:
import os
import ee
import geemap
os.environ['HTTP_PROXY'] = 'http://127.0.0.1:7890'
os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'
Map = geemap.Map()
geemap.ee_initialize()
python geebam.py upload -u pamelslade@gmail.com --source D:\Acdemic\xibei\grace\tif\2017 -m D:\Acdemic\xibei\grace\tif\metadata.csv --dest projects/ee-wang/assets/dryland/GRACE
其中:
-
geebam.py
是打包下载后的路径,要先切换路径,这里我是:
cd D:\Onedrive\gee_asset_manager-master
D:
-
-u pamelslade@gmail.com
是我的谷歌账号 -
--source D:\Acdemic\xibei\grace\tif\2017
是tif所在的路径,如图所示

-
-m D:\Acdemic\xibei\grace\tif\metadata.csv
是存储metadata csv文件的地方,作者推荐格式:
filename (without extension) | property1 header | property2 header |
---|---|---|
file1 | value1 | value2 |
file2 | value3 | value4 |
一个例子如下表:
id_no | class | category | binomial | system:time_start |
---|---|---|---|---|
my_file_1 | GASTROPODA | EN | Aaadonta constricta | 1478943081000 |
my_file_2 | GASTROPODA | CR | Aaadonta irregularis | 1478943081000 |
为了生成上述csv文件,可以参考前文的制作属性信息shp
-
--dest projects/ee-wang/assets/dryland/GRACE
是目的Asset路径
复制上述路径,输入gee账号密码,即可上传成功

批量上传至存储桶
最不推荐的一种方法,有很多限制,按下不表。
https://cloud.google.com/storage/docs/uploading-objects?hl=zh-cn
点击"免费开始使用"
缺点是需要一张visa信用卡:

点击创建存储桶:

点击上传文件:

上传后可以复制每个文件的路径,使用如下JS代码
// All the GeoTiffs are in this folder.
var uriBase = 'gs://geewang/grace/'
// List of URIs, one for each band.
var uris = ee.List([
uriBase + 'A20170102.tif',
uriBase + 'A20170109.tif',
uriBase + 'A20170116.tif',
uriBase + 'A20170123.tif',
]);
// Make a collection from the list of images.
var images = uris.map(ee.Image.loadGeoTIFF);
var collection = ee.ImageCollection(images);
print(collection)
https://developers.google.com/earth-engine/guides/ic_creating
或者使用Python API上传
启动授权会话
为了能够在用户文件夹中创建 Earth Engine ,需要以自己的身份进行身份验证。可以使用 Earth Engine 身份验证器的凭据来启动AuthorizedSession
. 然后,可以使用AuthorizedSession
向 Earth Engine 发送请求。
import ee
from google.auth.transport.requests import AuthorizedSession
ee.Authenticate() # or !earthengine authenticate --auth_mode=gcloud
session = AuthorizedSession(ee.data.get_persistent_credentials())
以下是EarthEngineAsset的一个实例。这是指定 COG 路径以及其他属性的地方。[请注意,该图像是从本示例脚本](https://code.earthengine.google.com/?scriptPath=Examples%3ACloud Masking%2FSentinel2)中制作的合成中导出的一小块区域。有关导出 COG 的详细信息,请参阅此文档。
Earth Engine 将从 TIFF 的元数据中确定波段、几何形状和其他相关信息。在创建 COG 支持的资产时唯一接受的其他字段是properties
、start_time
和end_time
。
import json
from pprint import pprint
# Request body as a dictionary.
request = {
'type': 'IMAGE',
'gcs_location': {
'uris': ['gs://ee-docs-demos/COG_demo.tif']
},
'properties': {
'source': 'https://code.earthengine.google.com/d541cf8b268b2f9d8f834c255698201d'
},
'startTime': '2016-01-01T00:00:00.000000000Z',
'endTime': '2016-12-31T15:01:23.000000000Z',
}
pprint(json.dumps(request))
向 Earth Engine 端点发出 POST 请求projects.assets.create
。
# Earth Engine enabled Cloud Project.
project_folder = 'your-project'
# A folder (or ImageCollection) name and the new asset name.
asset_id = 'cog-collection/your-cog-asset'
url = 'https://earthengine.googleapis.com/v1alpha/projects/{}/assets?assetId={}'
response = session.post(
url = url.format(project_folder, asset_id),
data = json.dumps(request)
)
pprint(json.loads(response.content))
缺点是对于gs中的TIF具有一定要求:
配置
TIFF 必须是:
-
Tiled,其中Tiled尺寸为: -
16x16 -
32x32 -
64x64 -
128x128 -
256x256 -
512x512 -
1024x1024
-
-
所有 IFD 都在开头。
参考
-
https://developers.google.com/earth-engine/Earth_Engine_asset_from_cloud_geotiff -
https://developers.google.com/earth-engine/guides/ic_creating -
https://github.com/gee-hydro/gee_docs
本文由 mdnice 多平台发布