在GEE里被问得最多的数据类型,除了逐像元的Image之外,大概就是矢量那一家子了。FeatureCollection这个类型,我见过太多人一开始被它绕晕:明明就是个"点线面集合",为什么操作起来一会儿要map,一会儿要filter,还动不动就报错说"无法在Element上调用该函数"。其实如果你把FeatureCollection当成一张"带空间位置的表格"来理解,GEE里一大半的矢量操作逻辑就都顺了。这篇文章我就以FeatureCollection为主线,把它的概念、创建方式、属性筛选、渲染与导出整套流程讲透,尤其会把我这几年来踩过的坑一并列出来。适合刚开始学GEE的遥感、GIS从业者,也适合已经被filter和map折磨过一轮、想系统捋一遍的同学。
1. FeatureCollection究竟是什么:从一个Feature说起
1.1 Feature = Geometry + 属性的组合逻辑
很多教程一上来就给你摆ee.FeatureCollection的API文档,结果新手压根不知道这个对象内部长什么样。我的经验是,先搞明白Feature,再理解FeatureCollection就顺理成章。Feature这个类型在GEE里就做一件事:把一个几何对象(Geometry)和一堆属性(properties)捆绑在一起。
几何对象就是点、线、面,比如ee.Geometry.Point([lon, lat])是一个点,ee.Geometry.LineString([[lon1,lat1],[lon2,lat2]])是一条线。而Feature就是在这些几何上附加了一个字典,类似这样:
javascript复制var myFeature = ee.Feature(
ee.Geometry.Point([121.47, 31.23]),
{name: '观测点A', value: 35.6, time: '2024-06-01'}
);
这段代码创建了一个带两个字段(name、value)的"带位置记录"。属性字段不限制类型,字符串、数字、数组都可以放进去,唯一要注意的是GEE服务器的数据类型限制,嵌套结构别搞得过于复杂,否则后续序列化很容易出幺蛾子。Feature最方便的地方在于,你可以像操作普通对象一样,通过.get('name')去取属性值,也可以通过.set('value', 40)去更新属性,而几何对象始终跟着这条记录走,不会丢。
理解了Feature之后,FeatureCollection就好办了:它就是Feature的集合,存储方式类似于一个数组,内部每一条都带有形状不同的Geometry,以及结构一致或不一致的properties。不过GEE更希望你的集合里所有Feature的字段结构是统一的,因为很多聚合函数、筛选操作都是基于"整列字段"来做的,字段不齐会让后面统计时出现一堆null。
1.2 FeatureCollection的本质是一张"属性表"
我一直觉得FeatureCollection最恰当的类比,是GIS桌面软件里的属性表。你想想,在QGIS或ArcGIS里,一个矢量图层打开属性表,每一行是一个要素,每一列是一个字段,行里还隐含着这个要素的几何形状。FeatureCollection就是这样一张表,只是它跑在云端、面向海量数据,操作方式从鼠标点击换成了代码。
这个"表格"思维非常有用。比如你在QGIS里想按属性选要素,用"按属性选择"对话框;在GEE里就是fc.filter(ee.Filter.eq('字段名', 值))。你在QGIS里想做字段计算,在GEE里就是fc.map(function(f) { return f.set('新字段', 计算表达式); })。你在QGIS里想对某一列做统计,在GEE里就是fc.aggregate_mean('字段名')。一旦你把FeatureCollection当作属性表来用,GEE的矢量操作就不再是一堆孤立的API函数,而是一套有逻辑的表格处理流程。
也正是因为这一点,FeatureCollection和普通的JavaScript数组有天壤之别。你没法用for循环去遍历它,也没法直接用arr.push去追加元素。GEE里所有对FeatureCollection的操作都需要通过map、filter这类服务器端函数来完成,它们会被翻译成云端分布式计算任务。换句话说,你不是在操作一堆本地对象,而是在给一台"云端遥感计算引擎"下指令。
1.3 FeatureCollection与Image、Geometry的协作边界
在GEE里,数据类型之间不是孤立的,但它们的协作方式有明确边界。FeatureCollection是矢量侧的高层容器,Geometry是底层几何,Image是栅格侧的核心。实际项目中,矢量和栅格最常见的配合方式有这么几种:
- 用FeatureCollection去裁剪Image,做区域统计:image.reduceRegions({collection: fc, reducer: ee.Reducer.mean(), scale: 30})。
- 用Image的像素值去提取矢量点的属性:sampleRegions。
- 用FeatureCollection去筛选Image集合:ImageCollection.filterBounds(fc)。
这些操作里,FeatureCollection充当的是"空间范围"或者"采样点位"的角色。所以你可以看到,FeatureCollection不只是用来展示点线面的,它是连接矢量与栅格两大世界的桥梁。很多做地物分类的同学,整个工作流就是:先建样本点FeatureCollection,然后对每个样本点提取影像波段值,得到带特征字段的样本集,最后喂给分类器。分类器输出出来还是一个FeatureCollection,只是属性里多了一个"类别"字段。懂得让FeatureCollection在不同数据形态之间流转,GEE项目基本上就打通了一半。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 创建FeatureCollection的几种方式与关键参数
2.1 从零构造:ee.Feature与ee.FeatureCollection
最基础的方式,就是先构造单个Feature,再组成集合。直接上代码:
javascript复制var feat1 = ee.Feature(ee.Geometry.Point([121.47, 31.23]), {id: 1, type: 'obs'});
var feat2 = ee.Feature(ee.Geometry.Point([121.48, 31.24]), {id: 2, type: '
