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

SuperMap iClient3D for WebGL 影像数据可视范围控制

在共享同一影像底图的服务场景中,如何基于用户权限体系实现差异化的数据可视范围控制?SuperMap iClient3D for WebGL提供了自定义区域影像裁剪的方法。让我们一起看看吧!

一、数据制作

对于上述视频中的地图制作,此处不做讲述,如有需要可访问:Online 开发者中心

可视化案例中提供了详细的代码、数据下载链接及数据制作过程。

二、实现思路

影像数据可视范围控制的实现思路如下图所示:

三、关键代码

遍历Geojson数据获取坐标数组关键代码如下:

if (data.type === "MultiPolygon") {// 处理 MultiPolygon 类型的数据,可能包含多个多边形for (let i = 0; i < data.coordinates.length; i++) {for (let j = 0; j < data.coordinates[i].length; j++) {// 获取当前多边形的坐标数组let positions = data.coordinates[i][j];// 用于存储转换后的笛卡尔坐标let superMapPositions = [];for (let k = 0; k < positions.length; k++) {// 将经纬度坐标转换为地理坐标对象,高度设为 0var cartographic = SuperMap3D.Cartographic.fromDegrees(positions[k][0], positions[k][1], 0);// 将地理坐标对象转换为笛卡尔坐标var cartesian = SuperMap3D.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);superMapPositions.push(cartesian);}// 转换为经纬度和高度数组let finalPositions = [];for (let k = 0, len = superMapPositions.length; k < len; k++) {// 将笛卡尔坐标转换为地理坐标对象var cartographic = SuperMap3D.Cartographic.fromCartesian(superMapPositions[k]);// 将弧度制的经度转换为角度制var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);// 将弧度制的纬度转换为角度制var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);// 获取高度值var h = cartographic.height;// 将经纬度和高度值依次添加到数组中finalPositions.push(longitude);finalPositions.push(latitude);finalPositions.push(h);}// 将当前多边形的位置信息添加到 allPositions 数组中allPositions = allPositions.concat(finalPositions);}}
} else if (data.type === "Polygon") {// 处理 Polygon 类型的数据,只包含一个多边形let positions = data.coordinates[0];let superMapPositions = [];for (let i = 0; i < positions.length; i++) {var cartographic = SuperMap3D.Cartographic.fromDegrees(positions[i][0], positions[i][1], 0);var cartesian = SuperMap3D.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);superMapPositions.push(cartesian);}// 转换为经纬度和高度数组let finalPositions = [];for (let i = 0, len = superMapPositions.length; i < len; i++) {var cartographic = SuperMap3D.Cartographic.fromCartesian(superMapPositions[i]);var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);var h = cartographic.height;finalPositions.push(longitude);finalPositions.push(latitude);finalPositions.push(h);}// 将当前多边形的位置信息赋值给 allPositions 数组allPositions = finalPositions;
}

四、示例完整代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>自定义区域影像裁剪</title><link href="../../Build/SuperMap3D/Widgets/widgets.css" rel="stylesheet"><link href="./css/pretty.css" rel="stylesheet"><script src="./js/jquery.min.js"></script><script src="./js/spectrum.js"></script><script src="./js/config.js"></script><script src="./js/tooltip.js"></script><script type="text/javascript" src="../../Build/SuperMap3D/SuperMap3D.js"></script>
</head><body><div id="Container"></div><div id='loadingbar' class="spinner"><div class="spinner-container container1"><div class="circle1"></div><div class="circle2"></div><div class="circle3"></div><div class="circle4"></div></div><div class="spinner-container container2"><div class="circle1"></div><div class="circle2"></div><div class="circle3"></div><div class="circle4"></div></div><div class="spinner-container container3"><div class="circle1"></div><div class="circle2"></div><div class="circle3"></div><div class="circle4"></div></div></div><div id="toolbar" class="param-container tool-bar"><div class="param-item"><select id="citySelector" style="width: 150px"><option value="" selected disabled hidden>请选择所属区域</option><option value="guiyang_city">贵阳市</option><option value="anshun_city">安顺市</option><option value="bijie_city">毕节市</option><option value="liupanshui_city">六盘水市</option><option value="tongren_city">铜仁市</option><option value="zunyi_city">遵义市</option><option value="qiandongnan_prefecture">黔东南</option><option value="qiannan_prefecture">黔南</option><option value="qianxinan_prefecture">黔西南</option></select></div></div><script>// 定义各城市中心点经纬度信息const cityCenters = {"guiyang_city": [106.713478, 26.578341],"anshun_city": [105.934854, 26.224645],"bijie_city": [105.291238, 27.302327],"liupanshui_city": [104.831343, 26.590612],"tongren_city": [109.188523, 27.704321],"zunyi_city": [106.932211, 27.707422],"qiandongnan_prefecture": [107.983421, 26.587345],"qiannan_prefecture": [107.501234, 26.234567],"qianxinan_prefecture": [104.902345, 25.098765]};// 页面加载完成后执行的函数,初始化 SuperMap3D 地图function onload(SuperMap3D) {// 通过 config.js 中的 getEngineType 函数,获取引擎类型(EngineType),用于设置启动方式let EngineType = getEngineType();// 创建一个 SuperMap3D 的 Viewer 实例,将其显示在 id 为 'Container' 的容器中let viewer = new SuperMap3D.Viewer('Container', {contextOptions: {// 设置 WebGL 上下文类型,Webgl2 对应值为 2,WebGPU 对应值为 3contextType: Number(EngineType),}});// 当场景加载完成后,调用 init 函数进行初始化操作viewer.scenePromise.then(function (scene) {init(SuperMap3D, scene, viewer);});}// 初始化地图场景的函数function init(SuperMap3D, scene, viewer) {// 设置地图的分辨率比例,根据设备的像素比进行调整viewer.resolutionScale = window.devicePixelRatio;$('#loadingbar').remove();// 存储添加的影像图层let tmpLayer = viewer.imageryLayers.addImageryProvider(new SuperMap3D.SuperMapImageryProvider({url: "http://localhost:8090/iserver/services/map-GuiZhou/rest/maps/%E8%B4%B5%E5%B7%9E%E7%9C%81%E5%9C%B0%E5%BD%A2%E5%9B%BE",}));// 设置所加载的影像背景透明,将白色背景设为透明tmpLayer.transparentBackColor = SuperMap3D.Color.fromCssColorString('#ffffff');// 设置透明背景的容差,即与指定颜色相近的颜色也会被视为透明tmpLayer.transparentBackColorTolerance = Number(0.1);// 让地图飞到影像所在的位置,以便用户能看到影像viewer.flyTo(tmpLayer);// 监听城市选择框的 change 事件,当用户选择不同的城市时触发$('#citySelector').change(function () {// 获取用户选择的城市的值var selectedCity = $(this).val();if (selectedCity) {// 根据选择的城市加载对应的 JSON 边界数据文件$.getJSON('./data/json/' + selectedCity + '.json', function (data) {// 用于存储所有多边形的位置信息let allPositions = [];if (data.type === "MultiPolygon") {// 处理 MultiPolygon 类型的数据,可能包含多个多边形for (let i = 0; i < data.coordinates.length; i++) {for (let j = 0; j < data.coordinates[i].length; j++) {// 获取当前多边形的坐标数组let positions = data.coordinates[i][j];// 用于存储转换后的笛卡尔坐标let superMapPositions = [];for (let k = 0; k < positions.length; k++) {// 将经纬度坐标转换为地理坐标对象,高度设为 0var cartographic = SuperMap3D.Cartographic.fromDegrees(positions[k][0], positions[k][1], 0);// 将地理坐标对象转换为笛卡尔坐标var cartesian = SuperMap3D.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);superMapPositions.push(cartesian);}// 转换为经纬度和高度数组let finalPositions = [];for (let k = 0, len = superMapPositions.length; k < len; k++) {// 将笛卡尔坐标转换为地理坐标对象var cartographic = SuperMap3D.Cartographic.fromCartesian(superMapPositions[k]);// 将弧度制的经度转换为角度制var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);// 将弧度制的纬度转换为角度制var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);// 获取高度值var h = cartographic.height;// 将经纬度和高度值依次添加到数组中finalPositions.push(longitude);finalPositions.push(latitude);finalPositions.push(h);}// 将当前多边形的位置信息添加到 allPositions 数组中allPositions = allPositions.concat(finalPositions);}}} else if (data.type === "Polygon") {// 处理 Polygon 类型的数据,只包含一个多边形let positions = data.coordinates[0];let superMapPositions = [];for (let i = 0; i < positions.length; i++) {var cartographic = SuperMap3D.Cartographic.fromDegrees(positions[i][0], positions[i][1], 0);var cartesian = SuperMap3D.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);superMapPositions.push(cartesian);}// 转换为经纬度和高度数组let finalPositions = [];for (let i = 0, len = superMapPositions.length; i < len; i++) {var cartographic = SuperMap3D.Cartographic.fromCartesian(superMapPositions[i]);var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);var h = cartographic.height;finalPositions.push(longitude);finalPositions.push(latitude);finalPositions.push(h);}// 将当前多边形的位置信息赋值给 allPositions 数组allPositions = finalPositions;}// 移除之前的裁剪区域,避免重叠viewer.scene.globe.removeImageryClipRegion("clip", [tmpLayer]);// 添加新的裁剪区域,根据选择的城市边界对影像进行裁剪viewer.scene.globe.addImageryClipRegions({position: allPositions,layers: [tmpLayer],name: "clip"});// 获取所选城市的中心点坐标const [lon, lat] = cityCenters[selectedCity];// 创建地理坐标对象const center = SuperMap3D.Cartographic.fromDegrees(lon, lat);// 创建笛卡尔坐标对象const centerCartesian = SuperMap3D.Cartesian3.fromRadians(center.longitude, center.latitude, 530000);// 让地图飞到城市中心点viewer.camera.flyTo({destination: centerCartesian,duration: 3 // 飞行时间,单位为秒});});}});}// 检查 SuperMap3D 是否已经定义,如果已经定义则调用 onload 函数进行初始化if (typeof SuperMap3D!== 'undefined') {onload(SuperMap3D);}</script>
</body></html>

相关文章:

SuperMap iClient3D for WebGL 影像数据可视范围控制

在共享同一影像底图的服务场景中&#xff0c;如何基于用户权限体系实现差异化的数据可视范围控制&#xff1f;SuperMap iClient3D for WebGL提供了自定义区域影像裁剪的方法。让我们一起看看吧&#xff01; 一、数据制作 对于上述视频中的地图制作&#xff0c;此处不做讲述&am…...

API网关相关知识点

目录 API网关基础知识总结 | JavaGuide Spring Cloud Gateway常见问题总结 | JavaGuide API网关 | 小傅哥 bugstack 虫洞栈 美团: 百亿规模API网关服务Shepherd的设计与实现 vivo: 微服务 API 网关架构实践 唯品会: 高吞吐消息网关的探索与思考 API网关基础知识总结 | J…...

Opencv 图像形态学操作

3.1 形态学-腐蚀操作 img cv2.imread(CSDN.png) cv2.imshow(CSDN, img) cv2.waitKey(0) cv2.destroyAllWindows如果腐蚀核的覆盖区域内的所有像素值都满足条件&#xff08;阈值&#xff09;&#xff0c;则中心像素的值保持不变&#xff1b;如果有任何像素值不满足条件&#x…...

Readability.js 与 Newspaper提取网页内容和元数据

在当今信息爆炸的时代&#xff0c;网页内容的提取和处理变得尤为重要。无论是从新闻网站、博客还是教程网站中提取内容&#xff0c;都需要一个高效、准确的工具来帮助我们去除无关信息&#xff0c;提取出有价值的正文内容。这不仅能够提高我们的工作效率&#xff0c;还能让我们…...

小程序Three Dof识别 实现景区AR体验

代码工程 GitCode - 全球开发者的开源社区,开源代码托管平台 dof...

腾讯2025年软件测试面试题

以下是基于腾讯等一线互联网公司软件测试岗位的面试趋势和技术要求,025年出现的软件测试面试题。这些问题涵盖了基础知识、自动化测试、性能测试、安全测试、编程能力等多个方面,供参考和准备。 一、基础知识 软件测试的基本概念...

SSL域名证书怎么续期?

在当今数字化时代&#xff0c;网站的安全性已成为企业和个人不可忽视的重要因素。SSL域名证书作为保障网站数据传输安全的关键工具&#xff0c;其重要性不言而喻。然而&#xff0c;SSL证书并非永久有效&#xff0c;它们通常有一个固定的有效期&#xff0c;到期后需要进行续期以…...

Grok3使用体验与模型版本对比分析

文章目录 Grok的功能DeepSearch思考功能绘画功能Grok 3的独特功能 Grok 3的版本和特点与其他AI模型的比较 最新新闻&#xff1a;Grok3被誉为“地球上最聪明的AI” 最近&#xff0c;xAI公司正式发布了Grok3&#xff0c;并宣称其在多项基准测试中展现了惊艳的表现。据官方消息&am…...

《算法宝典:全类型题目索引》

目录 &#x1f334;递归、搜索与回溯 一、递归 二、二叉树中的深搜 三、穷举vs暴搜vs深搜vs回溯vs剪枝 四、综合练习 五、FloodFill 算法 六、记忆化搜索 &#x1f335;优选算法 一、双指针 二、滑动窗口 三、二分查找 四、前缀和 五、位运算 六、模拟 七、分治 …...

Windows 11 部署 GPUStack 运行 DeepSeek

1. 介绍 DeepSeek 是一个强大的深度学习框架&#xff0c;适用于图像识别、自然语言处理等任务。GPUStack 是一个高效的 GPU 资源管理工具&#xff0c;能够帮助用户更好地利用 GPU 资源进行深度学习任务。本文将详细介绍如何在 Windows 11 系统上部署 GPUStack 并运行 DeepSeek…...

LangChain教程 - RAG - PDF问答

系列文章索引 LangChain教程 - 系列文章 在现代自然语言处理&#xff08;NLP&#xff09;中&#xff0c;基于文档内容的问答系统变得愈发重要&#xff0c;尤其是当我们需要从大量文档中提取信息时。通过结合文档检索和生成模型&#xff08;如RAG&#xff0c;Retrieval-Augment…...

Windows 图形显示驱动开发-WDDM 3.2-自动显示切换(十二)

API 更改 ADS 功能增加了以下公共 API 功能&#xff1a; 枚举系统中的多路复用器设备。查询有关多路复用器的信息&#xff0c;例如&#xff0c;它连接了哪些目标&#xff0c;以及当前切换到哪个目标。触发多路复用器切换。如何检测多路复用器是否已切换。 枚举系统中的多路复…...

《当齐天大圣踏入3A游戏世界:黑神话·悟空的破壁传奇》:此文为AI自动生成

国产 3A 游戏的破晓之光 2024 年 8 月 20 日,这一天注定被铭记在中国游戏发展的史册上。国产首款 3A 游戏《黑神话・悟空》震撼上线,犹如一颗重磅炸弹,在全球游戏市场掀起了惊涛骇浪。仅仅上线 3 小时,其同时在线人数便突破了 140 万,一举打破 Steam 纯单机游戏最高在线纪…...

Graphics View画一个可调速的风机(pyqt)

效果如图&#xff1a; 风机具备调节转速的功能&#xff0c;转速通过扇叶旋转的快慢来区别&#xff0c;共分为四档&#xff0c;其中零档为静止状态&#xff0c;而一、二、三档则依次增加转速。在代码中&#xff0c;BlowerWrapper 类包含了可旋转的扇叶、风机外框以及选项三个主要…...

基于django图书信息管理系统的搭建(增删改查)

✍django项目搭建教程 ☞ ----------------- 教程 本文主要讲解django如何连接数据库MySQL并且可视化展示&#xff0c;实现增删改查功能 目录 一. 创建django应用 二. 数据库配置 三. 查看数据库 四. 编写代码 4.1视图函数 4.2 配置URL 4.3创建模板文件 4.…...

Python 编程题 第四节:斐波那契数列、列表的复制、暂停后输出、成绩评级、统计字符

斐波那契数列 方法一&#xff08;递归&#xff09; def f(a):if a1:return 1elif a2:return 1else:return f(a-1)f(a-2) print(f(3)) 方法二&#xff08;非递归&#xff09; nint(input()) lst[1,1] for i in range(2,n1):lst.append(lst[i-1]lst[i-2]) print(lst[n-1]) 列…...

【华为OD机考】华为OD笔试真题解析(15)--异常的打卡记录

题目描述 考勤记录是分析和考核职工工作时间利用情况的原始依据&#xff0c;也是计算职工工资的原始依据&#xff0c;为了正确地计算职工工资和监督工资基金使用情况&#xff0c;公司决定对员工的手机打卡记录进行异常排查。 如果出现以下两种情况&#xff0c;则认为打卡异常…...

跟我学C++中级篇——定时器的设计

一、定时器 谈到定时器&#xff0c;理论上讲是各种语言和各种设计都无法避开的一个技术点。对于定时器来说&#xff0c;表面上就是一种时间间隔的处理约定&#xff0c;但对程序来说&#xff0c;可能就是设计层面、接口层面和库或框架以及系统应用的一个大集合。不同的系统&…...

HTTP 请求时传递多部分表单数据

HTTP 请求时传递多部分表单数据&#xff08;multipart/form-data&#xff09; --data-raw $------demo11111\r\nContent-Disposition: form-data; name"Filedata"; filename"截屏2025-02-27 15.45.46.png"\r\nContent-Type: image/png\r\n\r\n\r\n------d…...

第J3-1周:DenseNet算法 实现乳腺癌识别

文章目录 一、前言二、前期准备1.设置GPU2.划分数据集 三、搭建网络模型1.DenseLayer模块2.DenseBlock模块3.Transition模块4.构建DenseNet5.构建densenet121 四、训练模型1.编写训练函数2.编写测试函数3.正式训练 五、结果可视化1.Loss与Accuracy图2.模型评估 总结&#xff1a…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...