当前位置: 首页 > news >正文

GEE ui界面实现:用户自画多边形, 按面积比例在多边形中自动生成样点,导出多边形和样点shp,以及删除上一组多边形和样点(有视频效果展示)

零、背景

这几天在选样点,发现GEE有强大的ui功能,于是应用在我的工作上。

下述代码实现了几个功能:

①用户可以自己勾勒多边形,随后程序会按面积比例在多边形中自动生成样点,同时根据改多边形的区域生成区域平均月NDVI曲线;可以实现选取多个多边形。

②设置【Export】ui按钮,将已选的多边形和生成的样点以shp文件形式导出。

③如果对刚才画的多边形不满意,点击【Delete】ui按钮,即可将最近画的一个多边形,以及其上生成的样点删除。

一、录了个小视频,先来感受一下效果吧!

用户自画多边形, 按面积比例在多边形中自动生成样点,导出多边形

二、代码

GEE链接:https://code.earthengine.google.com/31d8edcd71f7b5d27201b88fc46c1e05

/*-----------                        --------------Sample
-------------                       --------------*/
// 创建地图
var map1 = ui.Map().setOptions('Hybrid').setZoom(4);
var map2 = ui.Map().setOptions('Hybrid').setZoom(4);// map1 监听 map2 的缩放级别变化;map2 监听 map1 的缩放级别变
map1.onChangeZoom(function(zoom){zoom = parseInt(zoom); // 转换为整数类型map2.setZoom(zoom);
});map2.onChangeZoom(function(zoom){zoom = parseInt(zoom);map1.setZoom(zoom);
});// 当在一个地图上平移时,其他两个地图会同步平移。
var linker = ui.Map.Linker([map1, map2], 'change-center');// 添加图层到地图面板
map1.centerObject(aoi,8);map1.addLayer(lucc_img.clip(aoi), luccVis, year+'_Land Cover Map');//lucc_img可替换为自己的可视化数据// 获取MODIS影像集合
var modisCollection = ee.ImageCollection('MODIS/061/MOD13Q1').filterBounds(aoi).filterDate(year+'-01-01', year+'-12-31'); // 修正日期范围// 创建时间序列面板
var chartPanel = ui.Panel({style: {width: '34%'}
});// 创建一个空的 FeatureCollection 来存储样本polygon
var polygonsCollection = ee.FeatureCollection([]);
// 创建一个空的 FeatureCollection 来存储样本points
var pointsCollection = ee.FeatureCollection([]);
var numPoints; // 全局变量// 创建region 的NDVI时间序列图表
var plotNDVI = function(geometry, title) {// 选择NDVI波段并将值乘以0.0001var adjustedModisCollection = modisCollection.map(function(image) {return image.reproject('EPSG:4326').select('NDVI').multiply(0.0001).copyProperties(image, ['system:time_start']);});// ee.Reducer.mean() 计算该区域内像素值的平均值var timeSeries = ui.Chart.image.series({imageCollection: adjustedModisCollection,region: geometry,reducer: ee.Reducer.mean(),scale: 250,xProperty: 'system:time_start'}).setOptions({title: title,vAxis: {title: 'NDVI'},hAxis: {title: 'Date'},lineWidth: 1,pointSize: 3});chartPanel.clear();chartPanel.add(timeSeries);
};// 导出函数
function exportPolygons_points() {// 检查 FeatureCollection 是否包含元素if (polygonsCollection.size().getInfo() > 0) {// 导出 FeatureCollection 到 Google Drive 为 SHP 格式Export.table.toDrive({collection: polygonsCollection,description: 'Exported_Polygons',fileFormat: 'SHP' // 指定文件格式为 SHP});print('Exporting polygons to Google Drive as SHP...');} else {print('No polygons to export.');}if (pointsCollection.size().getInfo() > 0) {// 导出 FeatureCollection 到 Google Drive 为 SHP 格式Export.table.toDrive({collection: pointsCollection,description: 'Exported_Points',fileFormat: 'SHP' // 指定文件格式为 SHP});print('Exporting points to Google Drive as SHP...');
} else {print('No points to export.');
}
}
// 创建导出按钮
var exportPolygons_points_Button = ui.Button({label: 'Export Polygons/points',onClick: exportPolygons_points
});
// 将导出按钮添加到 map2
map2.add(exportPolygons_points_Button);// Function to add drawing tools to the map
function addDrawingTools(map, mapTitle) {var drawingTools = map.drawingTools();drawingTools.addLayer([], 'geometry');drawingTools.setShape('polygon');drawingTools.draw();// Draw a polygonfunction onClickToDrawPoint(){var polygon = drawingTools.layers().get(0).getEeObject(); // Get the point drawn by the userdrawingTools.layers().reset(); // Clear the drawing toolsvar areaInMeters = polygon.area();print('areaInMeters',areaInMeters);// Create a feature with the coordinates as propertiesvar polygon_feature = ee.Feature(polygon);// Add the new point to the points collectionpolygonsCollection = polygonsCollection.merge(ee.FeatureCollection([polygon_feature])); // Merge the feature into the collection//print('polygonsCollection',polygonsCollection)// Calculate the number of random points based on the areanumPoints = areaInMeters.divide(1572500).ceil();  // Area / 1572500 (in square meters)不加var 即更新全局变量 numPoints,而不是定义局部变量print('numPoints', numPoints);// Generate random points within the polygonvar randomPoints = ee.FeatureCollection.randomPoints(polygon_feature.geometry(), numPoints);//print('randomPoints',randomPoints);pointsCollection = pointsCollection.merge(ee.FeatureCollection(randomPoints)); // Merge the feature into the collection//print('pointsCollection',pointsCollection)// Update the map with the new points collectionmap1.layers().set(4, ui.Map.Layer(polygonsCollection, {color: 'FF0000'}, 'Sample Polygons'));map2.layers().set(0, ui.Map.Layer(polygonsCollection, {color: 'FF0000'}, 'Sample Polygons'));map1.layers().set(5, ui.Map.Layer(pointsCollection, {color: '000000'}, 'Sample Points'));map2.layers().set(1, ui.Map.Layer(pointsCollection, {color: '000000'}, 'Sample Points'));// Redraw the NDVI chart (or any other chart you're displaying)plotNDVI(polygon_feature, mapTitle);drawingTools.draw();}drawingTools.onDraw(onClickToDrawPoint); // Enable drawing tools
}// Add drawing tools and delete button
addDrawingTools(map1, 'Click map 1 and add polygons!');
addDrawingTools(map2, 'Click map 2 and add polygons!');
addDeleteButton();  // Add the delete button to the UI// Function to add a delete button to remove the last drawn Polygon/Points
function addDeleteButton() {// Create the delete buttonvar deleteButton = ui.Button({label: 'Delete Last Polygon/Points',onClick: function() {// Delete last polygonif (polygonsCollection.size().getInfo() > 0) {// Get the index of the last featurevar lastPolygon = polygonsCollection.toList(polygonsCollection.size()).get(-1);  // Get the last polygon// Remove the last polygon by filtering it outpolygonsCollection = polygonsCollection.filter(ee.Filter.neq('system:index', ee.Feature(lastPolygon).get('system:index')));print('Last polygon deleted');} else {print('No polygon to delete');  // Print if no polygon exists}// Delete last pointsif (pointsCollection.size().getInfo() > 0) {// Calculate the size of the collectionvar collectionSize = pointsCollection.size();// Convert FeatureCollection to listvar pointsList = pointsCollection.toList(collectionSize);//var n = numPoints // assuming `numPoints` is defined elsewhere//print('numPoints2',numPoints)// Slice the list to exclude the last `n` pointsvar slicedPointsList = pointsList.slice(0, ee.Number(collectionSize).subtract(numPoints));  // Slice to remove last `numPoints` points// Convert the sliced list back to a FeatureCollectionpointsCollection = ee.FeatureCollection(slicedPointsList);// Update the map with the new polygon/points collectionmap1.layers().set(4, ui.Map.Layer(polygonsCollection, {color: 'FF0000'}, 'Sample Polygons'));map2.layers().set(0, ui.Map.Layer(polygonsCollection, {color: 'FF0000'}, 'Sample Polygons'));map1.layers().set(5, ui.Map.Layer(pointsCollection, {color: '000000'}, 'Sample Points'));map2.layers().set(1, ui.Map.Layer(pointsCollection, {color: '000000'}, 'Sample Points'));print('Last ' + numPoints.getInfo() + ' points deleted');} else {print('No points to delete.');}}});// Add the delete button to map2map2.add(deleteButton);
}// 创建水平分割面板(宽度为整个用户界面的66%),其中 map1 和 map2 分别位于左侧和右侧
var split1 = ui.Panel(ui.SplitPanel({firstPanel: map1,secondPanel: map2,orientation: 'horizontal',wipe: false,
}), null, {width: '66%', height:'100%'});// 创建水平分割面板(宽度为整个用户界面的34%),其中 chartPanel 位于map1和map2的右侧
var split2 = ui.Panel(ui.SplitPanel({firstPanel: split1,secondPanel: chartPanel,orientation: 'horizontal',wipe: false,
}), null, {width: '100%', height: '100%'});map2.setControlVisibility(false);//设置 map2 地图的控制面板(如缩放、平移、图层选择等控制元素)不显示
ui.root.clear(); // 清空当前用户界面上的所有内容
ui.root.insert(0, split2); // 将新的布局 split2 插入到用户界面的根容器中,位置索引为 0(即第一个位置)

完结撒花!

相关文章:

GEE ui界面实现:用户自画多边形, 按面积比例在多边形中自动生成样点,导出多边形和样点shp,以及删除上一组多边形和样点(有视频效果展示)

零、背景 这几天在选样点,发现GEE有强大的ui功能,于是应用在我的工作上。 下述代码实现了几个功能: ①用户可以自己勾勒多边形,随后程序会按面积比例在多边形中自动生成样点,同时根据改多边形的区域生成区域平均月N…...

React diff算法和Vue diff算法的主要区别

React和Vue都是流行的前端框架,它们各自实现了diff算法来优化虚拟DOM的更新过程。以下是React diff算法和Vue diff算法的主要区别: 1. diff策略 React diff算法: React的diff算法主要采用了同层级比较的策略,即它不会跨层级比较节…...

WSL 2 中 FastReport 与 FastCube 的设置方法与优化策略

软件开发人员长期以来一直在思考这个问题:“我们如何才能直接在 Windows 中运行 Linux 应用程序,而无需使用单独的虚拟机?” WSL 技术为这个问题提供了一个可能的答案。WSL 的历史始于 2016 年。当时,其实现涉及使用 Windows 内核…...

《线性代数》学习笔记

列向量无关 上个星期继续学线性代数,一个矩阵,如何判断它是的列向量有几个是线性无关呢?其实有好几个方法。第一个就是一个一个判断。 先选定一个,然后看下这两个,怎么看呢?如果两个列向量线性相关&#…...

Redis三种集群模式:主从模式、哨兵模式和Cluster模式

目录标题 1、背景及介绍2、 Redis 主从复制2.1、主从复制特点2.2、Redis主从复制原理2.3 PSYNC 工作原理2.3.1、启动或重连判断:2.3.2、第一次同步处理:2.3.3、断线重连处理:2.3.4、主节点响应2.3.5、全量同步触发条件:2.3.6、复制…...

CDH大数据平台部署

二、CDH简介 全称Cloudera’s Distribution Including Apache Hadoop。 hadoop的版本 (Apache、CDH、Hotonworks版本) 在公司中一般使用cdh多一些(收费的)、也有公司使用阿里云大数据平台、微软的大数据平台。 国内也有一些平台:星环大数…...

7.4、实验四:RIPv2 认证和触发式更新

源文件 一、引言:为什么要认证和采用触发式更新? 1. RIP v2 认证 RIP(Routing Information Protocol)版本 2 添加了认证功能,以提高网络的安全性。认证的作用主要包括以下几点: 防止路由欺骗 RIP v1 是不…...

【一步步开发AI运动小程序】二十一、如果将AI运动项目配置持久化到后端?

**说明:**本文所涉及的AI运动识别、计时、计数能力,都是基于云智「Ai运动识别引擎」实现。云智「Ai运动识别」插件识别引擎,可以为您的小程序或Uni APP赋于原生、本地、广覆盖、高性能的人体识别、姿态识别、10余种常见的运动计时、计数识别及…...

LED和QLED的区别

文章目录 1. 基础背光技术2. 量子点技术的引入3. 色彩表现4. 亮度和对比度5. 能效6. 寿命7. 价格总结 LED和 QLED都是基于液晶显示(LCD)技术的电视类型,但它们在显示技术、色彩表现和亮度方面有一些关键区别。以下是两者的详细区别&#xff…...

2024 年Postman 如何安装汉化中文版?

2024 年 Postman 的汉化中文版安装教程...

转化古老的Eclipse项目为使用gradle构建

很多古老的Java项目,是使用Eclipse作为IDE开发的。 那么,使用其它IDE的开发者,如何快速地进入这种古老项目的开发呢?或者说,一个Eclipse构建的古老项目,能不能转化成一个IDE无关的项目,进而所有…...

openGauss常见问题与故障处理(二)

2.网络故障定位手段 2.1 网络故障定位手段--常见网络故障引发的异常 在数据库正常工作的情况下,网络层对上层用户是透明的,但数据库在长期运行时,可能会由于各种原因导致出现网络异常或错误。 常见的因网络故障引发的异常有: 1>…...

Mysql 8迁移到达梦DM8遇到的报错

在实战迁移时,遇到两个报错。 一、列[tag]长度超出定义 在mysql中,tag字段的长度是varchar(20),在迁移到DM8后,这个长度不够用了。怎么解决? 在迁移过程中,“指定对象”时,选择转换。 在“列映…...

Android HandlerThread 基础

HandlerThread **一、HandlerThread的基本概念和用途**1. **目的**2. **与普通线程的区别** **二、HandlerThread的使用步骤**1. **创建HandlerThread对象并启动线程**2. **创建Handler并关联到HandlerThread的消息队列**3. **发送消息到HandlerThread的消息队列** **三、Handl…...

【智能算法应用】人工水母搜索算法求解二维路径规划问题

摘要 本文基于人工水母搜索算法(Jellyfish Search Algorithm, JSA),对二维路径规划问题进行了研究。JSA作为一种新兴的群体智能优化算法,模仿了水母在海洋中觅食和迁移的行为,以求解非线性、复杂的优化问题。实验结果…...

【Altium】原理图如何利用参数管理器批量修改元器件属性

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决在使用AD设计原理图的时候,使用参数管理器批量修改元器件的属性。 2、 问题场景 客户在使用ad时,想大批量修改元器件的属性,类似于Cadence中,批量修改Manufactur…...

基于Spring Boot与Redis的令牌主动失效机制实现

目录 前言1. 项目结构和依赖配置1.1 项目依赖配置1.2 Redis连接配置 2. 令牌主动失效机制的实现流程2.1 登录成功后将令牌存储到Redis中2.2 使用拦截器验证令牌2.3 用户修改密码后删除旧令牌 3. Redis的配置与测试4. 可能的扩展与优化结语 前言 在现代Web系统中,用…...

深度学习之循环神经网络(RNN)

1 为什么需要RNN? ​ 时间序列数据是指在不同时间点上收集到的数据,这类数据反映了某一事物、现象等随时间的变化状态或程度。一般的神经网络,在训练数据足够、算法模型优越的情况下,给定特定的x,就能得到期望y。其一…...

Autosar CP Network Management模块规范导读

Network Management模块的主要功能 网络管理适配:作为通信管理器和总线特定网络管理模块之间的适配层,实现不同总线网络管理功能的统一接口,确保系统中各种网络的协同工作。协调功能 网络协调关闭:使用协调算法协调多个网络的关闭,确保它们在合适的时间同步进入睡眠模式,…...

Xshell 7 偏好设置

1 Xshell7 工具——更改用户数据文件夹 就是此电脑目录下的文档 该目录下的7 Xshell下的 applog ColorScheme Files 配色方案文件目录 HighlightSet Files 突出显示集目录 Logs 日志 QuickButton Files 快速命令集 Scripts 脚本文件 Sessions 会话文件 会话文件目录就…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

在rocky linux 9.5上在线安装 docker

前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...