8.2集合类Map

本文深入探讨了HashMap的基本概念与使用方法,包括实例创建、数据添加、删除与查询操作,并介绍了如何通过键集进行数据遍历。

1Map

1.1基于HashMap实现

  • Map存放数据是键(k)值(v)对的形式来存放数据的
  • 键(k)对应相应的值(k)

当添加键(k)有重复时会覆盖原来键对应的值

HashMap的常用方法

		//创建实例
		Map<Integer,String> maps = new HashMap<Integer,String>();
		//添加数据,用put
		maps.put(1, "好人");
		maps.put(2, "坏人");
		maps.put(3, "不是人");
		//删除数据,跟据键(k)来删除对应的数据
		maps.remove(3);	//移除了3中的不是好人这个值
		//获取数据,也是根据键(k)来获取后面的值
		maps.get(2);
		//判断是否有键(k)
		maps.containsKey(1);
		//判断值
		maps.containsValue("不是人");
		//将map中的键(k)存放到set中
		Set set = maps.keySet();


1.2Map的遍历

可以先将Map中的键(k)存放到Set中,在Set循环中调用Map的的get()放法,将Set的值作为参数。

例:

		//遍历
		//将maps中的key放到Set中
		Set si = maps.keySet();

		//超级for循环
		for(Object key:si){
			//调用maps中的get方法
			String str = maps.get(key);
		}


// =================================================================== // 7. 创建年度合成影像(核心步骤) // =================================================================== // 定义时间范围(可以修改为其他年份) var startYear = '2020-01-01'; var endYear = '2020-12-31'; print('正在创建 ' + startYear + ' 到 ' + endYear + ' 的年度合成影像...'); // 创建完整的年度影像集合 var annualCollection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterBounds(study_area) .filterDate(startYear, endYear) .filter(ee.Filter.lt('CLOUD_COVER', 50)) // 放宽云量限制以获取更多影像 .map(preprocessLandsat); // 应用预处理函数 // 打印年度集合信息 print('年度影像集合大小:', annualCollection.size()); print('年度集合中的影像列表:', annualCollection); // 生成年度中值合成影像(有效去除云和噪声) var annualComposite = annualCollection.median().clip(study_area); print('年度合成影像完成!波段信息:'); print('合成影像波段:', annualComposite.bandNames()); // =================================================================== // 8. 可视化年度合成影像 // =================================================================== // 8.1 年度真彩色合成 Map.addLayer(annualComposite, {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 0.3, gamma: 1.2}, '📅 2020 年度真彩色合成', true); // 8.2 年度假彩色合成(突出植被) Map.addLayer(annualComposite, {bands: ['SR_B5', 'SR_B4', 'SR_B3'], min: 0, max: 0.3, gamma: 1.2}, '🌳 2020 年度假彩色合成', false); // 8.3 年度NDBI合成(建筑用地) var compositeNDBI = annualComposite.select('NDBI'); Map.addLayer(compositeNDBI, {min: -0.2, max: 0.4, palette: ['blue', 'white', 'orange', 'brown']}, '🏗️ 2020 年度NDBI合成', false); // 8.4 年度NDVI合成(植被) var compositeNDVI = annualComposite.select('NDVI'); Map.addLayer(compositeNDVI, {min: -0.2, max: 0.8, palette: ['brown', 'yellow', 'lightgreen', 'darkgreen']}, '🌿 2020 年度NDVI合成', false); // =================================================================== // 9. 影像质量检查与统计 // =================================================================== // 检查合成影像的有效像素覆盖率 var count = annualCollection.count().clip(study_area); Map.addLayer(count, {min: 0, max: annualCollection.size().getInfo(), palette: ['red', 'yellow', 'green']}, '📊 有效影像覆盖次数', false); // 打印统计信息 print('=== 影像质量报告 ==='); print('参与合成的影像数量:', annualCollection.size()); print('时间范围:', startYear, '至', endYear); print('空间分辨率: 30米'); print('覆盖区域:', study_area.geometry().area().divide(1000000), '平方公里'); // 计算研究区内平均NDVI和NDBI值(用于质量参考) var meanNDVI = compositeNDVI.reduceRegion({ reducer: ee.Reducer.mean(), geometry: study_area.geometry(), scale: 30, maxPixels: 1e9 }); var meanNDBI = compositeNDBI.reduceRegion({ reducer: ee.Reducer.mean(), geometry: study_area.geometry(), scale: 30, maxPixels: 1e9 }); print('研究区平均NDVI(植被指数):', meanNDVI.get('NDVI')); print('研究区平均NDBI(建筑指数):', meanNDBI.get('NDBI')); // =================================================================== // 10. 导出功能(可选) // =================================================================== // 如果需要导出合成影像到Google Drive,取消注释以下代码 /* Export.image.toDrive({ image: annualComposite, description: 'LandUse_2020_Annual_Composite', folder: 'GEE_Exports', scale: 30, region: study_area.geometry(), maxPixels: 1e13, fileFormat: 'GeoTIFF' }); */ // 导出NDBI指数图(用于后续CGEI计算) /* Export.image.toDrive({ image: compositeNDBI, description: 'NDBI_2020_For_CGEI', folder: 'GEE_Exports', scale: 30, region: study_area.geometry(), maxPixels: 1e13 }); */ // =================================================================== // 11. 使用说明 // =================================================================== print('=== 🎯 下一步行动指南 ==='); print('1. 检查"年度真彩色合成"图层是否完整覆盖研究区'); print('2. 查看"有效影像覆盖次数"图层,绿色区域表示数据质量好'); print('3. 切换NDBI图层,确认建筑用地(棕色)识别准确'); print('4. 如果结果满意,可以取消注释导出代码保存数据'); print('5. 准备好后,我们将开始绘制训练样本进行土地利用分类!'); print('=== 💡 质量控制提示 ==='); print('✅ 理想情况:研究区大部分为绿色(高覆盖次数)'); print('✅ NDBI图层:城市和建成区应显示为棕色/红色'); print('✅ NDVI图层:植被茂密区应显示为深绿色'); print('❌ 如果大片区域为红色:云覆盖严重,考虑调整时间范围'); // 添加图例说明 print('=== 🎨 图层说明 ==='); print('红色边界: 研究区范围'); print('蓝色区域: 中方口岸缓冲区'); print('绿色区域: 越方口岸缓冲区'); print('棕色区域(NDBI): 建筑用地/建成区'); print('深绿色区域(NDVI): 茂密植被');这部分代码是否正确,如有错误帮我修改
最新发布
10-23
你的这段 Google Earth Engine (GEE) 代码整体结构清晰、逻辑完整,涵盖了**年度合成影像生成 → 可视化 → 质量检查 → 导出建议**的全流程。从语法和功能上看,**大部分是正确的**,但存在 **几个关键问题和优化点**,我们来逐一分析并修正。 --- ## ✅ 总体评价 | 项目 | 状态 | |------|------| | 语法正确性 | 基本正确(有小错) | | 功能完整性 | 高(含预处理、合成、统计、导出) | | 逻辑合理性 | 合理(使用 `.median()` 去云) | | 潜在错误 | 存在(如 `.getInfo()` 使用不当、`clip` 位置、波段范围设置) | --- ## ❌ 主要问题与修改建议 ### 🔴 问题1:`.getInfo()` 在服务端表达式中不能直接用于 `max` 参数 你这行代码有问题: ```javascript Map.addLayer(count, {min: 0, max: annualCollection.size().getInfo(), palette: ['red', 'yellow', 'green']}, '📊 有效影像覆盖次数', false); ``` ❌ 错误原因: - `annualCollection.size()` 返回的是一个 `ee.Number` - `.getInfo()` 是客户端方法,在服务器脚本中 **会阻塞或报错** - GEE 编辑器允许运行是因为它“容忍”这种写法,但在任务调度或模块化时会失败 ✅ 正确做法:使用 `ee.Image.constant()` 和动态最大值 #### ✅ 修改为: ```javascript // 获取集合大小作为图像常量用于可视化 var imageCount = annualCollection.count().clip(study_area); var maxCount = annualCollection.size(); // ee.Number Map.addLayer(imageCount, {min: 0, max: maxCount, palette: ['red', 'yellow', 'green']}, '📊 有效影像覆盖次数', false); ``` > 💡 注意:GEE 自动将 `max: ee.Number` 解析为数值,无需 `.getInfo()` --- ### 🔴 问题2:`clip(study_area)` 的顺序应尽量靠后 虽然 `.clip()` 放在 `.median()` 后没问题,但更高效的做法是先裁剪再合成(减少计算量) #### ✅ 推荐修改: ```javascript var annualComposite = annualCollection .median() .clip(study_area); // ✅ 正确 ``` 也可以考虑用 `.reduceRegion(...).unmask()` 来避免边缘裁剪不全的问题,但当前做法可接受。 --- ### 🟡 问题3:波段可视化 `min/max` 设置可能不合理(特别是反射率单位) 你用了: ```javascript {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 0.3, gamma: 1.2} ``` ⚠️ 注意:Landsat Collection 2 Level-2 数据是 **表面反射率 × 10000 存储的整型**(即 scaled integers),不是 `[0,1]` 浮点! 所以你要么: - 使用原始缩放值(推荐) - 或者先除以 10000 转成浮点 #### ✅ 方案一(推荐):调整 `min/max` 到整数范围 ```javascript // 因为 SR_Bx 是 int16 类型,范围大约是 0~3000(对应 0.0~0.3) Map.addLayer(annualComposite, {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 3000, gamma: 1.2}, '📅 2020 年度真彩色合成', true); ``` #### ✅ 方案二(更通用):转为浮点 [0,1] ```javascript var annualCompositeFloat = annualComposite.divide(10000).copyProperties(annualComposite); // 然后再可视化 Map.addLayer(annualCompositeFloat, {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 0.3, gamma: 1.2}, '📅 2020 年度真彩色合成 (float)', true); ``` 📌 建议选择方案一,避免额外计算开销。 --- ### 🔴 问题4:`study_area.geometry()` 多余调用 你在 `.reduceRegion()` 中写了: ```javascript geometry: study_area.geometry() ``` 如果 `study_area` 已经是一个 `Geometry` 或 `Feature`,不需要 `.geometry()`。 ✅ 更简洁写法: ```javascript geometry: study_area ``` 除非你确定它是 `FeatureCollection` 才需要 `.geometry()` --- ### 🟡 问题5:未处理空结果导致 `print(get('NDVI'))` 报错 ```javascript print('研究区平均NDVI(植被指数):', meanNDVI.get('NDVI')); ``` 如果 `meanNDVI` 是空的(比如区域外、无数据),`.get('NDVI')` 不会报错,但打印出来是 `<Error>`。 ✅ 更安全写法: ```javascript meanNDVI.evaluate(function(dict) { if (dict && dict['NDVI'] !== null) { print('✅ 研究区平均NDVI:', dict['NDVI']); } else { print('❌ 平均NDVI 计算失败或无有效像素'); } }); ``` 同理适用于 `meanNDBI` --- ### ✅ 其他建议 | 建议 | 说明 | |------|------| | 添加 `Map.centerObject(study_area, 10)` | 确保地图居中显示 | | 给每个图层加透明度控制 | 如 `{opacity: 0.8}` | | 注释掉的导出任务提醒用户手动运行 | 已做得很好 ✅ | --- ## ✅ 修正后的完整代码(重点修改部分已标注) ```javascript // =================================================================== // 7. 创建年度合成影像(核心步骤) // =================================================================== // 定义时间范围 var startYear = '2020-01-01'; var endYear = '2020-12-31'; print('正在创建 ' + startYear + ' 到 ' + endYear + ' 的年度合成影像...'); // 创建完整的年度影像集合 var annualCollection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterBounds(study_area) .filterDate(startYear, endYear) .filter(ee.Filter.lt('CLOUD_COVER', 50)) .map(preprocessLandsat); // 应用预处理函数(需确保该函数存在) // 打印年度集合信息 print('年度影像集合大小:', annualCollection.size()); print('年度集合中的影像列表:', annualCollection); // 生成年度中值合成影像 var annualComposite = annualCollection.median().clip(study_area); print('年度合成影像完成!波段信息:'); print('合成影像波段:', annualComposite.bandNames()); // =================================================================== // 8. 可视化年度合成影像 // =================================================================== // --- 添加地图居中 --- Map.centerObject(study_area, 10); // 8.1 年度真彩色合成(使用整型反射率范围) Map.addLayer(annualComposite, {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 3000, gamma: 1.2}, '📅 2020 年度真彩色合成', true); // 8.2 年度假彩色合成(突出植被) Map.addLayer(annualComposite, {bands: ['SR_B5', 'SR_B4', 'SR_B3'], min: 0, max: 3000, gamma: 1.2}, '🌳 2020 年度假彩色合成', false); // 8.3 年度NDBI合成(建筑用地) var compositeNDBI = annualComposite.select('NDBI'); Map.addLayer(compositeNDBI, {min: -0.2, max: 0.4, palette: ['blue', 'white', 'orange', 'brown']}, '🏗️ 2020 年度NDBI合成', false); // 8.4 年度NDVI合成(植被) var compositeNDVI = annualComposite.select('NDVI'); Map.addLayer(compositeNDVI, {min: -0.2, max: 0.8, palette: ['brown', 'yellow', 'lightgreen', 'darkgreen']}, '🌿 2020 年度NDVI合成', false); // =================================================================== // 9. 影像质量检查与统计 // =================================================================== // 检查合成影像的有效像素覆盖率 var count = annualCollection.count().clip(study_area); var maxCount = annualCollection.size(); // 不使用 getInfo() Map.addLayer(count, {min: 0, max: maxCount, palette: ['red', 'yellow', 'green']}, '📊 有效影像覆盖次数', false); // 打印统计信息 print('=== 影像质量报告 ==='); print('参与合成的影像数量:', annualCollection.size()); print('时间范围:', startYear, '至', endYear); print('空间分辨率: 30米'); print('覆盖区域:', study_area.geometry ? study_area.geometry().area().divide(1e6) : study_area.area().divide(1e6), '平方公里'); // 计算研究区内平均NDVI和NDBI值(使用 evaluate 安全获取) var meanNDVI = compositeNDVI.reduceRegion({ reducer: ee.Reducer.mean(), geometry: study_area, scale: 30, maxPixels: 1e9 }); var meanNDBI = compositeNDBI.reduceRegion({ reducer: ee.Reducer.mean(), geometry: study_area, scale: 30, maxPixels: 1e9 }); // 安全输出统计结果 meanNDVI.evaluate(function(dict) { print('研究区平均NDVI(植被指数):', dict ? dict['NDVI'] : 'null'); }); meanNDBI.evaluate(function(dict) { print('研究区平均NDBI(建筑指数):', dict ? dict['NDBI'] : 'null'); }); // =================================================================== // 10. 导出功能(可选) // =================================================================== /* Export.image.toDrive({ image: annualComposite, description: 'LandUse_2020_Annual_Composite', folder: 'GEE_Exports', scale: 30, region: study_area, maxPixels: 1e13, fileFormat: 'GeoTIFF' }); Export.image.toDrive({ image: compositeNDBI, description: 'NDBI_2020_For_CGEI', folder: 'GEE_Exports', scale: 30, region: study_area, maxPixels: 1e13 }); */ // =================================================================== // 11. 使用说明 // =================================================================== print('=== 🎯 下一步行动指南 ==='); print('1. 检查"年度真彩色合成"图层是否完整覆盖研究区'); print('2. 查看"有效影像覆盖次数"图层,绿色区域表示数据质量好'); print('3. 切换NDBI图层,确认建筑用地(棕色)识别准确'); print('4. 如果结果满意,可以取消注释导出代码保存数据'); print('5. 准备好后,我们将开始绘制训练样本进行土地利用分类!'); print('=== 💡 质量控制提示 ==='); print('✅ 理想情况:研究区大部分为绿色(高覆盖次数)'); print('✅ NDBI图层:城市和建成区应显示为棕色/红色'); print('✅ NDVI图层:植被茂密区应显示为深绿色'); print('❌ 如果大片区域为红色:云覆盖严重,考虑调整时间范围'); print('=== 🎨 图层说明 ==='); print('红色边界: 研究区范围'); print('蓝色区域: 中方口岸缓冲区'); print('绿色区域: 越方口岸缓冲区'); print('棕色区域(NDBI): 建筑用地/建成区'); print('深绿色区域(NDVI): 茂密植被'); ``` --- ## ✅ 总结:修改清单 | 原始问题 | 是否修复 | 方法 | |--------|--------|------| | `.getInfo()` 在 `max` 中滥用 | ✅ | 改为 `ee.Number` 直接传入 | | 波段可视化范围错误(0~0.3) | ✅ | 改为 `0~3000`(整型) | | `study_area.geometry().geometry()` 冗余 | ✅ | 改为 `study_area` | | `print(get(...))` 可能出错 | ✅ | 使用 `.evaluate()` 安全读取 | | 地图未居中 | ✅ | 添加 `Map.centerObject` | --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值