geemap

GeeMap笔记

GeeMap是Google Earth Engine代码编辑器的python版本,接入了其平台的各类API接口以及其自定义函数,从而实现了在Python中调用平台资源和进行各种运算、输出等功能,由于笔者并非计算机科班出身,因此一开始接触编程也是以Python为主,在学习到Google Earth Engine时,发现其官方平台以及网络上大多数资源都是以js语言为主,与其学习一门新语言,不如把一门语言学的更透一点,抱着这样的想法,我开始学习geemap,学习资源主要来自吴秋生1老师。

geemap包安装

这里不再赘述,在该网站上有详细教程2

首次授权以及初始化

import gemap  
import ee  
import os

geemap.set_proxy(port=10809) # 国内的用户要先设置代理端口
ee.Authenticate() # 后续会弹出网页,登录Google earth engine后创建一个工作空间类似的东西后继续点下去会有一个授权码一样的东西,复制过来回车就行
ee.Initialize() # 初始化方法1
Map = geemap.Map() # 初始化方法2,同时也是创建一个实例化地图交互对象

创建地图

Map = geemap.Map() # 最基础的
Map = geemap.Map(center=[lat, lon], height=value, width=value, basemap="str") # 依次是显示的中心经纬度、显示高度、宽度和要添加显示的底图
Map.add_basemap("str") # 同时也可以向创建好的地图中添加底图
geemap.basemap.keys() # 其中存放着geemap库中包含的所有底图名称,可以用列表推导式或者for循环给打印出来
# 同时可以添加在线底图,不是目前学习的重点,因此不再赘述
Map = geemap.Map(center=[35.531978, 112.951408], zoom=9, height=500, width=800, basemap="OpenStreetMap.CH") # 显示效果如下图

17887272237680

Google Earth Engine(下文简称GEE或gee)的数据获取

gee数据类型

数据类型/对象方法简单描述
Geometry没有属性表的单一形状
Feature带有属性表的单个矢量要素
FeatureCollection带有属性表的矢量要素数据集
Image单幅栅格影像
ImageCollection栅格影像数据集
Reducer用于计算统计或者汇总的对象
Join某些数据集按照某种规则(如相同时间范围、相同位置、或者某些相同属性)的交集集合
Array数组
Chart图表

gee中对这些属性的大致解释如下3

430396458009089

Geometry数据类型的多种形式4
几何类型说明
Point
LineString线段
LinearRing多边形
Rectangle矩形
Polygon多边形面
Geometry对象的几种手动创建方式
# 可以创建点、线段、多边形、矩形、多边形面
point = ee.Geometry.Point([113.598234, 35.18936]) # 点坐标,注意是经度在前,纬度在后
lineString = ee.Geometry.LineString([[113.898234, 35.18936], [114.898234, 36.18936], [114.398234, 36.28936]]) # 线段顶点坐标,不闭合
linearRing = ee.Geometry.LinearRing([[113.398234, 35.08936], [114.598234, 36.08936], [114.398234, 36.28936]]) # 多边形顶点坐标,最后一个点自动与第一个点连接,闭合
rectangle = ee.Geometry.Rectangle([113.398234, 35.08936, 114.598234, 36.08936]) # 矩形顶点坐标,闭合
polygon = ee.Geometry.Polygon([[[113.398234, 35.08936], [113.198234, 35.18936], [113.098234, 34.98936]]]) # 多边形顶点坐标,最后一个点自动与第一个点连接,闭合,并且可以创建多个,因此[]个数也与其他几个不一样

# 该部分不再可视化
geometrySet = ee.Geometry.MultiPoint([[114.898234, 36.18936], [114.398234, 36.28936]]) # 多点坐标
pointSet = geometrySet.geometries() # 拆分要素
point1 = pointSet.get(0) # 获取第一个要素
point2 = pointSet.get(1) # 获取第二个要素

Map.addLayer(point, {"color": "red"}, 'point')
Map.addLayer(lineString, {"color": "blue"}, 'lineString')
Map.addLayer(linearRing, {"color": "green"}, 'linearRing')
Map.addLayer(rectangle, {"color": "yellow"}, 'rectangle')
Map.addLayer(polygon, {"color": "purple"}, 'polygon')

Map

343063451067252

大地几何和平面几何

我们都知道地球坐标系一般分为地理坐标系和投影坐标系(就是从小到大学的平面直角坐标系)定位,因此当我们要将几何形状投影到底图上时也要选择是使用经纬度投影还是平面投影

rectangle1 = ee.Geometry.Rectangle([130.398234, 35.08936, 180.00, 39.08936], None, geodesic=False) # 设置为平面坐标系
rectangle2 = ee.Geometry.Rectangle([130.398234, 35.08936, 180.00, 39.08936], None, geodesic=True) # 设置为地理坐标系

Map.addLayer(rectangle1, {"color": "red"}, 'rectangle1')
Map.addLayer(rectangle2, {"color": "blue"}, 'rectangle2')
Map

389112320955247

关于Geometry对象的一些操作
操作作用备注编号
geometry.buffer(value)对当前形状取缓冲区单一Polygon(单位为m)1
geometry.centroid()获取当前形状中心点坐标单一Polygon2
geometry.contains(object)判断object是否包含在当前形状中返回一个类字典,要想像js一样获得True或者False需要在后加上.getInfo()3
geometry.intersection(anotherGeometry, ee.ErrorMargin(1))获取两个形状的交集形状ee.ErrorMargin(1)为容许误差(m),以下同理4
geometry.union(anotherGeometry, ee.ErrorMargin(1))获取两个形状的并集形状5
geometry.difference(anotherGeometry, ee.ErrorMargin(1))从当前形状中删除其与另一个形状的交集的余下形状6
geometry.symmetricDifference(anotherGeometry, ee.ErrorMargin(1))获取两个形状的交集形状互斥的形状7
# 1、2操作演示
polygon = ee.Geometry.Polygon([[[-5, 40], [-6, 41], [-7, 42], [-8, 43], [-9, 43]]], )# 创建一个多边形
buffer = polygon.buffer(10000) # 获对多边形使用缓冲区
centriod = polygon.centroid() # 获取点

Map.addLayer(polygon, {"color": "red"}, 'polygon')
Map.addLayer(buffer, {"color": "blue"}, 'buffer')
Map.addLayer(centriod, {"color": "green"}, 'centriod')

Map

# 3:操作演示
point = ee.Geometry.Point([-50, 30]) # 创建一个点
poly1 = ee.Geometry.Point([-50, 30]).buffer(1e6) # 创建一个点并取缓冲区1e6m
poly2 = ee.Geometry.Point([-40, 30]).buffer(1e6) # # 创建一个点并取缓冲区1e6m

Map.setCenter(-45, 30) # 设置底图显示的中心坐标
Map.addLayer(poly1, {"color": 'FF0000'}, 'poly1') # 添加到地图进行显示
Map.addLayer(poly2, {"color": '0000FF'}, 'poly2')

intersection = poly1.intersection(poly2, ee.ErrorMargin(1)) # 进行相交操作
Map.addLayer(intersection, {"color": '00FF00'}, 'intersection')

union = poly1.union(poly2, ee.ErrorMargin(1)) # 进行合并操作
Map.addLayer(union, {"color": 'FF00FF'}, 'union')

diff1 = poly1.difference(poly2, ee.ErrorMargin(1)) # 进行擦除操作
Map.addLayer(diff1, {"color": 'FFFF00'}, 'diff1')

symDiff = poly1.symmetricDifference(poly2, ee.ErrorMargin(1)) # 进行交集取反操作
Map.addLayer(symDiff, {"color": '000000'}, 'symmetric difference')
print(poly1.contains(poly2).getInfo()) # 判断poly1是否包含poly2
print(poly1.contains(point).getInfo()) # 判断poly1是否包含point
Map

False
True
poly1和poly2 相交 合并 擦除 交集取反
以上依次为:
ploy1是否包含poly2,输出为False
ploy1是否包含point,输出为True
ploy1和poly2可视化
相交可视化
合并可视化
擦除可视化
交集取反可视化

Feature&FeatureCollection
Feature
  • 前面已经说过,Feature就是在Geometry的基础上添加了属性表,FeatureCollection就是多个Feature的集合
  • display(object)可以像gee编辑器里那样显示对象的结构
# Feature
# 1. 创建一个Feature
poly1 = ee.Geometry.Polygon([[[-122, 37],
                             [-123, 38],
                             [-124, 36],
                             [-125, 35]]]) # 首先创建一个几何形状
fea1 = ee.Feature(poly1, {'name': 'feature1'}) # 通过添加字典的形式添加属性表,使其转换为要素

Map.addLayer(fea1, {}, 'feature1')

# Feature中几何形状不是必须的,只创建一个属性表(通过字典的形式)也可以,甚至可以在某个字段进行运算
dic = {'foo': ee.Number(8).add(88), 'bar': 'nihao'}
nowhere_feature = ee.Feature(None, dic)

display(fea1) # 可以像gee编辑器里那样显示对象的结构
Map

对象结构 显示效果

  • Feature(后面都叫要素了)仍有缓冲区、相交等操作,每一个Feature(要素)都存在一个主要的Geometry(后面都叫形状了)存放在geometry属性中,而其余的形状则存在在其他的属性中(后半段话我没太理解)
  • FeatureObject.set("字段名", "属性"/数值)可以用来设置属性表,由于要素只有一个,因此也只能设置一个属性或者数值
# 创建一个点要素并设置属性表
feature = (
    ee.Feature(ee.Geometry.Point([-122.22599, 37.17605]))
    .set('genus', 'Sequoia')
    .set('species', 'sempervirens')
)

# 获取指定字段属性
species = feature.get('species')
display(species)

# 新增一个字段并设置属性
feature = feature.set('presence', 1)

# 覆盖原有的字段名和属性
new_dic = {'genus': 'Brachyramphus', 'species': 'marmoratus'}
feature = feature.set(new_dic)

display(feature)

output

2024_07_06


FeatureCollection(要素数据集)
  1. FeatureCollection的构造方式(ee.FeatureCollection(features))

    • 1.1. 提供一个要素的列表, 单个要素也可以被转为要素数据集
    features = [
    ee.Feature(ee.Geometry.Rectangle(30.01, 59.80, 30.59, 60.15), {'name': 'Voronoi'}),
    ee.Feature(ee.Geometry.Point(-73.96, 40.781), {'name': 'Thiessen'}),
    ee.Feature(ee.Geometry.Point(6.4806, 50.8012), {'name': 'Dirichlet'}),
    ] # 构建要素列表
    
    from_list = ee.FeatureCollection(features) # 转化为要素数据集
    display(from_list)
    

    • 1.2. gee上的要素数据集
    fc = ee.FeatureCollection('RESOLVE/ECOREGIONS/2017') # 获取在gee上的要素数据集
    m = geemap.Map()
    m.set_center(12.17, 20.96, 3)
    m.add_layer(fc, {}, 'ecoregions')
    display(m)
    

    • 1.3. 在一个要素范围内随机生成样点(ee.FeatureCollection.randomPoints(region))
    # 定义一个形状区域
    region = ee.Geometry.Rectangle(-119.224, 34.669, -99.536, 50.064)
    
    # 在该区域范围内随机生成1000个样点
    random_points = ee.FeatureCollection.randomPoints(region)
    
    # 显示
    m = geemap.Map()
    m.center_object(random_points)
    m.add_layer(random_points, {}, 'random points')
    m.add_layer(region, {'color': '000000'}, 'region')
    display(m)
    

  2. 要素和要素数据集的可视化

    • 2.1. 通过前面的例子我们也可以知道,在将栅格影像或者几何形状等可视化时,都使用了Map.addLayer(visObject, visParams(dict), name(str))的函数,其中控制显示化效果的就是visParams的设置,其为字典形式,其中常见的是颜色控制{"color": "red"}或者{"color": "FF0000"},前者是预设好的颜色字符串,后者是R-G-B三原色数字分别转换为16进制后组成的字符串,即FF代表R颜色十进制编码,00和00分别代表G和B颜色十进制编码。
    • 2.2. 要素数据集使用其他显示渲染选项的话,还有featureCollection.draw(),其中pointRadiusstrokeWidth参数来控制点的显示半径线宽
    # 从gee获取要素数据集
    ecoregions = ee.FeatureCollection('RESOLVE/ECOREGIONS/2017')
    pointG = ee.Geometry.Point(-76.2486, 44.8988) # 设置形状点
    pointF = ee.Feature(pointG) # 将点转化为要素
    pointFC = ee.FeatureCollection(pointF) # 将要素转化为要素数据集
    
    # 设置可视化颜色
    m = geemap.Map()
    m.set_center(-76.2486, 44.8988, 8)
    m.add_layer(ecoregions.draw(color='green', strokeWidth=5), {}, 'drawn') # 设置面要素数据集的颜色和线宽
    m.add_layer(pointFC.draw(color='red', pointRadius=20), {}, 'point') # 设置点要素数据集的显示半径
    m
    

    *注意:*在形状或者要素对象使用draw()函数会报错,即这两种对象不支持通过该函数设置显示效果
    *注意:*在该段代码构建几何形状、要素和要素数据集时,尤其是后两者时,并没有提供属性表,但仍然可以成功。

    • 2.3. 要对要素数据集的可视化进行更多的控制,可以使用image.paint()函数,该函数将要素数据集作为一个输入参数使用
    # 创建一个空图像,在其中绘制特征,投影到字节(这句话我没看懂)。
    empty = ee.Image().byte() # 
    m = geemap.Map()
    ecoregions = ee.FeatureCollection('RESOLVE/ECOREGIONS/2017')
    
    # 可视化
    outline = empty.paint(featureCollection=ecoregions, color=1) # 不设置宽度
    outline = empty.paint(featureCollection=ecoregions, color=1, width=10) # 设置宽度
    m.add_layer(outline, {'palette': 'FF0000'}, 'paint') # 可视化
    
    m
    

    通过查阅gee中paint(featureCollection, color, width)的API说明:在图像上绘制几何图形集合的几何图形,使用给定的 "颜色 "值替换任何几何图形覆盖图像的区域(如果指定了线宽,则替换周长覆盖图像的区域)中每个波段的值。这种算法最适合将特征属性中的分类数据转换为图像中的像素;如果您希望将集合可视化,可以考虑使用 FeatureCollection.style,它支持 RGB 颜色,而这种算法严格来说是 "单色 "的(使用单个数值)。
    可以看出来,该函数似乎是把要素数据集的每个要素的几何形状转为了栅格形式进行渲染,通过display()函数可以看到确实是一个栅格影像格式的对象

    • 该方法也可以根据字段属性(字段属性必须是ee.Number类型)进行渲染
    outlines = empty.paint(featureCollection=ecoregions, color='BIOME_NUM', width="NNH") # 设置RESOLVE/ECOREGIONS/2017的BIOME_NUM字段为颜色设置基础,线宽也一样
    palette = ['FF0000', '00FF00', '0000FF'] # 设置调色板
    m.add_layer(outlines, {'palette': palette, 'max': 14}, 'different color edges') # 设置可视化,调色板为palette拉伸显示,最大显示到BIOME_NUM字段的属性14
    

    最终可以看到不一样的颜色和不一样粗的线宽

    • 如果想填充和线宽同时显示
    filled_outlines = empty.paint(ecoregions, 'BIOME_NUM').paint(ecoregions, 0, "NNH") # 在设置完填充对象后再次设置填充线宽显示
    m.add_layer(filled_outlines, {'palette': ['000000'] + palette, 'max': 14}, 'edges and fills')
    
    m    
    

2024/07/06 end


  1. 要素数据集的信息和元数据
    该部分与栅格和栅格数据集的索引方式相同,但是我又是从要素和要素数据集先开始介绍的,因此当前要素和要素数据集部分先暂停,下面从栅格和栅格数据集开始介绍
Image

添加gee数据到地图并可视化

SR2a = ee.ImageCollection("CloudDataReserveID") # 获取gee数据,需要填写该数据在gee上的ID
# 以下为详细举例
# 这里选择了哨兵2号的遥感影像数据集,取其中的第一幅,将其栅格值缩小1w倍,得到真正的反射率值,再选择其中的4、3、2真彩色波段
# 当使用第一个函数.first()后,该SR2a实质上已变成了Image了,因为只取了整个栅格数据集的第一个栅格。
SR2a = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED").first()\
                                                        .divide(10000)\
                                                        .select("B4", "B3", "B2", )
# 设置可视化参数
visParams = {
            "min": 0.0 # 影像显示的最小值
            "max": 0.5 # 影像显示的最大值
            "bands":["B4", "B3", "B2"] # 三个波段组成真彩色
}
# 进行可视化显示
Map.addLayer(SR2a, visParams, "Sentinel-2A") # 这三个参数位置分别为显示对象、可视化参数设置集、在地图上显示的图层名称

图左为哨兵2数据集在gee中的说明;图右为哨兵2添加到地图后的样子

137531401784829 589844780078212

参考


  1. @giswqs ↩︎

  2. 01_introduction.html ↩︎

  3. objects_methods_overview ↩︎

  4. geometries ↩︎

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值