SuperMap iClient3D for WebGL三维场景与二维地图联动

作者:Lzzzz

在城市规划,应急救援,旅游规划等项目场景中,普遍存在通过二维地图定位区域或路线,三维场景展示布局细节的情况,那么,如何使三维场景与二维地图联动起来呢,一起来看看如何实现吧!

最终效果

实现步骤

  • 监听二维地图的平移事件,并更新三维场景的相机位置。
  • 在三维场景移动时,获取相机位置,同时更新二维地图的中心点。

关键代码

定义信号变量

定义信号变量,保证地图联动效果和场景联动效果同一时间只能触发一个  防止循环调用。

        // 监听鼠标进入地图和 SuperMap3D 容器的区域,以确定当前激活的是哪个
        var activeMap = true;
        document.getElementById('map').addEventListener('pointerenter', () => {
            activeMap = true;
        });
        // 监听鼠标进入 SuperMap3D 容器的区域,以确定当前激活的是地图还是场景
        document.getElementById('Container').addEventListener('pointerenter', () => {
            activeMap = false;
        });

地图监听

// 监听地图中心变化,并更新 SuperMap3D 的相机位置
        map.getView().on('change:center', () => {
            if (activeMap) {
                const center = map.getView().getCenter();
                const cartographic = SuperMap3D.Cartographic.fromCartesian(viewer.camera.position);
                const height = cartographic.height; // 获取高度
                // 更新 MySuperMap3D 的相机位置
                const cartesian = SuperMap3D.Cartesian3.fromDegrees(center[0], center[1], height); // 设定一定高度
                viewer.camera.flyTo({
                    destination: cartesian,
                    duration: 0 // 立即移动
                });
            };
        });

场景监听

        // 监听相机位置变化事件,以更新 OpenLayers 地图的视点
        viewer.camera.changed.addEventListener(() => {
            if (activeMap) return;
            const camera = viewer.camera;

            // 从相机的世界坐标获取经纬度
            const cartographic = SuperMap3D.Cartographic.fromCartesian(camera.position);
            // 获取高度并打印以检查
            const latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);
            const longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);

            // 更新 OpenLayers 地图的视点
            map.getView().setCenter([longitude, latitude]);
        });

项目完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <title>地图场景联动</title>
    <link href="../../Build/SuperMap3D/Widgets/widgets.css" rel="stylesheet">
    <link href="./css/bootstrap.min.css" rel="stylesheet">
    <link href="./css/pretty.css" rel="stylesheet">
    <link href="./css/bootstrap-select.min.css" rel="stylesheet">
    <script src="./js/jquery.min.js"></script>
    <script src="./js/bootstrap.min.js"></script>
    <script src="./js/bootstrap-select.min.js"></script>
    <script src="./js/config.js"></script>
    <script type="text/javascript" src="../../Build/SuperMap3D/SuperMap3D.js"></script>
    <script type="text/javascript" src="/examples/js/include-web.js"></script>
    <script type="text/javascript" src="/examples/dist/openlayers/include-openlayers.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="map" class="map" style="width:400px;height: 450px; position: absolute;top:580px">
</div>

<script>
	function onload(SuperMap3D) {
        var EngineType = getEngineType();
        var viewer = new SuperMap3D.Viewer('Container', {
            contextOptions: {
                contextType: Number(EngineType), // Webgl2:2 ; WebGPU:3
            }
        });
        
        viewer.scenePromise.then(function(scene){
            init(SuperMap3D, scene, viewer);
        });
    }

    function init(SuperMap3D, scene, viewer) {
        viewer.resolutionScale = window.devicePixelRatio;
        viewer.imageryLayers.addImageryProvider(new SuperMap3D.TiandituImageryProvider({
            credit : new SuperMap3D.Credit('天地图全球影像服务     数据来源:国家地理信息公共服务平台 & 四川省测绘地理信息局'),
            token: URL_CONFIG.TOKEN_TIANDITU
        }));
        var imageryLayers = viewer.imageryLayers;
        //初始化天地图全球中文注记服务,并添加至影像图层
        var labelImagery = new SuperMap3D.TiandituImageryProvider({
            mapStyle : SuperMap3D.TiandituMapsStyle.CIA_C, //天地图全球中文注记服务(经纬度投影)
            token: URL_CONFIG.TOKEN_TIANDITU
        });
        imageryLayers.addImageryProvider(labelImagery);


        var map = new ol.Map({
            target: 'map',
            view: new ol.View({
                center: [0,0],
                zoom: 1,
                projection: "EPSG:4326",
                multiWorld: true
            }),

            layers: [new ol.layer.Tile({
                source: new ol.source.Tianditu({
                    key: "1d109683f4d84198e37a38c442d68311",
                    projection: "EPSG:4326"
                })
            }), new ol.layer.Tile({
                source: new ol.source.Tianditu({
                    key: "1d109683f4d84198e37a38c442d68311",
                    isLabel: true,
                    projection: "EPSG:4326"
                })
            })]
        });

        // 监听鼠标进入地图和 SuperMap3D 容器的区域,以确定当前激活的是哪个
        var activeMap = true;
        document.getElementById('map').addEventListener('pointerenter', () => {
            activeMap = true;
        });
        // 监听鼠标进入 SuperMap3D 容器的区域,以确定当前激活的是地图还是场景
        document.getElementById('Container').addEventListener('pointerenter', () => {
            activeMap = false;
        });

        // 监听地图中心变化,并更新 SuperMap3D 的相机位置
        map.getView().on('change:center', () => {
            if (activeMap) {
                const center = map.getView().getCenter();
                const cartographic = SuperMap3D.Cartographic.fromCartesian(viewer.camera.position);
                const height = cartographic.height; // 获取高度
                // 更新 MySuperMap3D 的相机位置
                const cartesian = SuperMap3D.Cartesian3.fromDegrees(center[0], center[1], height); // 设定一定高度
                viewer.camera.flyTo({
                    destination: cartesian,
                    duration: 0 // 立即移动
                });
            };
        });

        // 监听相机位置变化事件,以更新 OpenLayers 地图的视点
        viewer.camera.changed.addEventListener(() => {
            if (activeMap) return;
            const camera = viewer.camera;

            // 从相机的世界坐标获取经纬度
            const cartographic = SuperMap3D.Cartographic.fromCartesian(camera.position);
            // 获取高度并打印以检查
            const latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);
            const longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);

            // 更新 OpenLayers 地图的视点
            map.getView().setCenter([longitude, latitude]);
        });


        $('#loadingbar').remove();
	}


    if (typeof SuperMap3D !== 'undefined') {
        window.startupCalled = true;
        onload(SuperMap3D);
    }
</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980903.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3dsmax烘焙光照贴图然后在unity中使用

效果预览 看不清[完蛋&#xff01;] 实现步骤 使用 软件 软体名称地址photoshophttps://www.adobe.com/products/photoshop.htmlunity3Dhttps://unity.com/3dsmaxhttps://www.autodesk.com.cn/products/3ds-max/free-trialpacker-iohttps://www.uv-packer.com/HDR 贴图地址…

ThinkPHP使用phpword读取模板word文件并添加表格

1.安装phpword包composer require phpoffice/phpword 2.模板文件结构 如上图框住的是要替换的文本和要复制表格样式 实现代码 <?phpnamespace app\api\logic;use PhpOffice\PhpWord\Element\Table; use PhpOffice\PhpWord\SimpleType\TblWidth; use PhpOffice\PhpWord\…

Solon AI —— 流程编排

说明 Solon 的流程编排&#xff0c;使用了 solon-flow 做流程编排&#xff0c;因此需要先对 solon-flow 有所了解&#xff0c;下面是 Solon flow的一些简单介绍&#xff0c;更具体的介绍可以参考官网 https://solon.noear.org/article/learn-solon-flow 。 solon-flow Solon…

性能调优-cpu的性能指标【经典篇】

一 cpu查看core数命令 1.1 查看物理core数 1.查看物理CPU的个数&#xff1a;cat /proc/cpuinfo 这个虚拟机的物理cpu2个&#xff0c;每个物理cpu的逻辑CPU个数为1个&#xff0c;所以逻辑CPU的个数就是2个。 1.2 查看逻辑cpu个数 cat /proc/cpuinfo| grep "processo…

Unity中动态切换光照贴图LightProbe的方法

关键代码&#xff1a;LightmapSettings.lightmaps lightmapDatas; LightmapData中操作三张图&#xff1a;lightmapColor,lightmapDir,以及一张ShadowMap 这里只操作前两张&#xff1a; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI;public cl…

计算机毕业设计Python+DeepSeek-R1大模型微博舆情分析系统 微博舆情预测 微博爬虫 微博大数 据(源码+LW文档+PPT+详细讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

[Computer Vision]实验八:图像分割

目录 一、实验内容 二、实验过程 2.1 交互式分割实验 2.1.1 交互式分割 实验代码 2.1.2 实验结果 2.2 聚类算法实现图像分割 2.2.1 聚类算法实现分割 实验代码 2.2.2 实验结果 三、实验总结 一、实验内容 了解图割操作&#xff0c;实现用户交互式分割&#xff0c;通过…

Django与数据库

我叫补三补四&#xff0c;很高兴见到大家&#xff0c;欢迎一起学习交流和进步 今天来讲一讲alpha策略制定后的测试问题 mysql配置 Django模型体现了面向对象的编程技术&#xff0c;是一种面向对象的编程语言和不兼容类型能相互转化的编程技术&#xff0c;这种技术也叫ORM&#…

命名管道——进程间通信

个人主页&#xff1a;敲上瘾-CSDN博客 匿名管道&#xff1a;进程池的制作&#xff08;linux进程间通信&#xff0c;匿名管道... ...&#xff09;-CSDN博客 一、命名管道的使用 1.创建命名管道 1.1.在命令行中&#xff1a; 创建&#xff1a; mkfifo 管道名 删除&#xff1a…

摄像头应用编程(三):多平面视频采集

文章目录 1、前言2、环境介绍3、步骤4、应用程序编写5、测试5.1、编译应用程序5.2、运行应用程序 6、总结 1、前言 在查看摄像头类型时&#xff0c;大致可以分为两类&#xff1a;Video Capture 和 Video Capture Multiplanar。 本次应用程序主要针对类型为Video Capture Multi…

QT实现计算器

1&#xff1a;在注册登录的练习里面&#xff0c; 追加一个QListWidget 项目列表 要求&#xff1a;点击注册之后&#xff0c;将账号显示到 listWidget上面去 以及&#xff0c;在listWidget中双击某个账号的时候&#xff0c;将该账号删除 Widget.h #ifndef WIDGET_H #define…

Spring IoC配置(xml+组件类的生命周期方法)

文末有本篇文章对应的项目源码文件可供下载 生命周期方法概念 我们可以在组件类中定义一个或者两个方法&#xff0c;然后当Spring IoC容器实例化和销毁组件类对象的时候进行自动调用.我们定义的方法就叫做组件的生命周期方法. 类似于Servlet的init/destroy方法,Tomcat可以在…

一篇吃透模型:all-MiniLM-L6-v2

MiniLM 是什么&#xff1f; MiniLM 是微软研究院开发的一种轻量级的语言模型&#xff0c;旨在以较小的参数量和计算成本实现与大型语言模型&#xff08;如 BERT&#xff09;相当的性能。它是基于 Transformer 架构的预训练模型&#xff0c;通过深度自注意力蒸馏&#xff08;De…

vue3之echarts仪表盘

vue3之echarts仪表盘 效果如下&#xff1a; 版本 "echarts": "^5.5.1" 核心代码&#xff1a; <template><div ref"chartRef" class"circle"></div> </template> <script lang"ts" setup>…

【C语言初阶】操作符_作业详解的一些疑问

前言&#xff1a; b站鹏哥视频&#xff0c;来源以下链接 76. 【C语言初阶】操作符_作业讲解_哔哩哔哩_bilibili 目的&#xff1a; 记录视频里面没有理解的相关知识 疑惑的地方&#xff1a; 对c语言的那个&#xff0c;\n不是特别了解&#xff0c;就是输入了一个字符&#x…

本地部署 DeepSeek:从 Ollama 配置到 Spring Boot 集成

前言 随着人工智能技术的迅猛发展&#xff0c;越来越多的开发者希望在本地环境中部署和调用 AI 模型&#xff0c;以满足特定的业务需求。本文将详细介绍如何在本地环境中使用 Ollama 配置 DeepSeek 模型&#xff0c;并在 IntelliJ IDEA 中创建一个 Spring Boot 项目来调用该模型…

【网络编程】之TCP实现客户端远程控制服务器端及断线重连

【网络编程】之TCP实现客户端远程控制服务器端及断线重连 TCP网络通信实现客户端简单远程控制主机基本功能演示通信过程代码实现服务器模块执行命令模块popen系列函数 客户端模块服务器主程序 windows作为客户端与服务器通信#pragma comment介绍 客户端使用状态机断线重连代码实…

ROS环境搭建

ROS首次搭建环境 注&#xff1a;以下内容都是在已经安装好ros的情况下如何搭建workplace 一、创建工作空间二、创建ROS包三、注意 注&#xff1a;以下内容都是在已经安装好ros的情况下如何搭建workplace 如果没有安装好&#xff0c;建议鱼香ros一步到位:鱼香ROS 我也是装了好久…

centos7操作系统下安装docker,及查看docker进程是否启动

centos7下安装docker&#xff0c;需要用到的yun命令 &#xff08;yum命令用于添加卸载程序&#xff09; 1.设置仓库&#xff1a; yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 2.安装 Docker Engine-Community yum in…

IO基础知识和练习

一、思维导图 二、练习 1.使用标准IO函数&#xff0c;实现文件的拷贝 #include <head.h> int main(int argc, const char *argv[]) {FILE *pfopen("./one.txt","r");FILE *fpfopen("./two.txt","r");if(pNULL)PRINT_ERROR(&qu…