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

Arcgis地图实战三:自定义导航功能的实现

文章目录

    • 1.最终效果预览
    • 2.计算两点之间的距离
    • 3.将点线画到地图上
    • 4.动态展示点线的变化
    • 5.动态画线
    • 6.动态画点

1.最终效果预览

loc222

2.计算两点之间的距离

let dis = this.utilsTools.returnDisByCoorTrans(qdXYData, zdXYData, "4549")

当距离小于我们在配置文件中预设置的值时调用我们自定义开发的导航,大于预设值则调用百度或者高德导航

在utilsTools工具类中我们封装了如下方法

returnDisByCoorTrans(curxy, tarxy, wikid) {let dis = "0";let pxy1 = this.coordinateUtil.coorConvert(curxy["latitude"], curxy["longitude"], wikid)let pxy2 = this.coordinateUtil.coorConvert(tarxy["y"], tarxy["x"], wikid)let pA = {x: pxy1.x,y: pxy1.y,}let pB = {x: pxy2.x,y: pxy2.y,}dis = this.returnDistanceByTwoPoint(pA, pB)return dis}

在坐标转换工具类coordinateUtil中我们封装了如下方法,参数以江苏通州为例

 coorConvert(lat, lon, targetWikid): any {if (targetWikid == "4549") {this.aAxis_Target = 6378137;this.bAxis_Target = 6356752.31414;this.m_dbMidLongitude = 120;return this.gaussBLtoXY(lat, lon, this.aAxis_Target, this.bAxis_Target, this.m_dbMidLongitude);}    }public gaussBLtoXY(mX: number, mY: number, Axis_Target_a: number, Axis_Target_b: number, m_dbMidLongitude: number): any {let m_aAxis = Axis_Target_a; //参考椭球长半轴let m_bAxis = Axis_Target_b; //参考椭球短半轴//double m_dbMidLongitude = transParaSeven.daihao*3;//中央子午线经度 济南117 威海123 巴州 87 通州120let m_xOffset = 500000;let m_yOffset = 0.0;try {//角度到弧度的系数let dblD2R = Math.PI / 180;//代表e的平方let e1 = (Math.pow(m_aAxis, 2) - Math.pow(m_bAxis, 2)) / Math.pow(m_aAxis, 2);//代表e'的平方let e2 = (Math.pow(m_aAxis, 2) - Math.pow(m_bAxis, 2)) / Math.pow(m_bAxis, 2);//a0let a0 = m_aAxis * (1 - e1) * (1.0 + (3.0 / 4.0) * e1 + (45.0 / 64.0) * Math.pow(e1, 2) + (175.0 / 256.0) * Math.pow(e1, 3) + (11025.0 / 16384.0) * Math.pow(e1, 4));//a2                let a2 = -0.5 * m_aAxis * (1 - e1) * (3.0 / 4 * e1 + 60.0 / 64 * Math.pow(e1, 2) + 525.0 / 512.0 * Math.pow(e1, 3) + 17640.0 / 16384.0 * Math.pow(e1, 4));//a4let a4 = 0.25 * m_aAxis * (1 - e1) * (15.0 / 64 * Math.pow(e1, 2) + 210.0 / 512.0 * Math.pow(e1, 3) + 8820.0 / 16384.0 * Math.pow(e1, 4));//a6let a6 = (-1.0 / 6.0) * m_aAxis * (1 - e1) * (35.0 / 512.0 * Math.pow(e1, 3) + 2520.0 / 16384.0 * Math.pow(e1, 4));//a8let a8 = 0.125 * m_aAxis * (1 - e1) * (315.0 / 16384.0 * Math.pow(e1, 4));纬度转换为弧度表示//Blet B = mX * dblD2R;//llet l = (mY - m_dbMidLongitude) * dblD2R;Xlet X = a0 * B + a2 * Math.sin(2.0 * B) + a4 * Math.sin(4.0 * B) + a6 * Math.sin(6.0 * B) + a8 * Math.sin(8.0 * B);//let ll = Math.pow(Math.cos(B), 2) * e2;let c = m_aAxis * m_aAxis / m_bAxis;//Nlet N = c / Math.sqrt(1 + ll);//tlet t = Math.tan(B);let p = Math.cos(B) * l;let dby = X + N * t * (1 + ((5.0 - t * t + (9.0 + 4.0 * ll) * ll) + ((61.0 + (t * t - 58.0) * t * t + (9.0 - 11.0 * t * t) * 30.0 * ll) + (1385.0 + (-31111.0 + (543 - t * t) * t * t) * t * t) * p * p / 56.0) * p * p / 30.0) * p * p / 12.0) * p * p / 2.0;let dbx;dbx = N * (1.0 + ((1.0 - t * t + ll) + ((5.0 + t * t * (t * t - 18.0 - 58.0 * ll) + 14 * ll) + (61.0 + (-479.0 + (179.0 - t * t) * t * t) * t * t) * p * p / 42.0) * p * p / 20.0) * p * p / 6.0) * p;let mTargetX = dbx + m_xOffset;let mTargetY = dby + m_yOffset;return { x: mTargetX, y: mTargetY };}catch (ex) {console.error(ex);return null;}}

3.将点线画到地图上

 this.utilsTools.navigationByPointsSelf(curXY, tarXY, 2, this.angleValue)

在utilsTools工具类中封装了画点及画线的方法如下

navigationByPointsSelf(beginPoint, endPoint, expand, angle) {this.locatedByBeginNavigationPoint(beginPoint, ['pointerArrow'], 'navigationLayer', angle)this.locatedByEndNavigationPoint(endPoint, ['runendsymbol'], 'navigationPointLayer')this.drawNavigationFirstLine(beginPoint, endPoint, "navigationLayer", 'polylineDASH')this.drawNavigationLineFirstByLocation(beginPoint, endPoint, expand)}

画当前点locatedByBeginNavigationPoint
画终点locatedByEndNavigationPoint
画当前点与终点的连线drawNavigationFirstLine
将点线的范围缩放到页面适当位置drawNavigationLineFirstByLocation

locatedByEndNavigationPoint(endPoint, endSymbol, layerName) {let pointEndObj = {x: Number(endPoint.longitude),y: Number(endPoint.latitude),spatialReference: { wkid: this.mapConfig.wkid, latestWkid: this.mapConfig.wkid }}let geoJson = JSON.stringify(pointEndObj)let attObj = ""let oneObj = { geomertyJSON: geoJson, attributes: attObj };let symbol = { "point": endSymbol };this.mapTool.AddGraphicToLayer(layerName, [oneObj], symbol);}locatedByBeginNavigationPoint(beginPoint, beginSymbols, layerName, angleValue) {let pointBeginObj = {x: Number(beginPoint.longitude),y: Number(beginPoint.latitude),spatialReference: { wkid: this.mapConfig.wkid, latestWkid: this.mapConfig.wkid }}let pgeoJson = JSON.stringify(pointBeginObj)let pattObj = {angle: angleValue}let beginObj = { geomertyJSON: pgeoJson, attributes: pattObj };let symbolpoint = { "point": beginSymbols };this.mapTool.AddGraphicToLayer(layerName, [beginObj], symbolpoint)}drawNavigationLineFirstByLocation(beginPoint, endPoint, expand) {let geoObj = {type: "polyline",paths: [[[Number(beginPoint.longitude), Number(beginPoint.latitude)],[Number(endPoint.longitude), Number(endPoint.latitude)]]],spatialReference: { wkid: this.mapConfig.wkid, latestWkid: this.mapConfig.wkid }}this.mapTool.setExtentByGeo(geoObj, expand)}drawNavigationFirstLine(beginPoint, endPoint, layerName, lineSymbol) {let geoObj = {paths: [[[Number(beginPoint.longitude), Number(beginPoint.latitude)],[Number(endPoint.longitude), Number(endPoint.latitude)]]],spatialReference: { wkid: this.mapConfig.wkid, latestWkid: this.mapConfig.wkid }}let geoJson = JSON.stringify(geoObj)let attObj = {}let oneObj = { geomertyJSON: geoJson, attributes: attObj };let symbol = { "polyline": [lineSymbol] };this.mapTool.AddGraphicToLayer(layerName, [oneObj], symbol);}

在mapTool工具类中封装了将点或者线添加到地图上的操作

4.动态展示点线的变化

 this.navigationInterval = setInterval(() => {this.setIntervalData(curXY, tarXY)}, 1500);
async setIntervalData(curXY, tarXY) {this.angleValue = await this.utilsTools.getAngleData()curXY = await this.utilsTools.getDynamicCurXY(curXY)this.topNavigationMsg = this.utilsTools.getTopNavigationBoxMgs(curXY, tarXY)this.utilsTools.getCaluShowNavigationByInterval(curXY, tarXY, this.angleValue, 2)}

在工具类utilsTools中封装了获取当前设备角度的方法getAngleData
在工具类utilsTools中封装了动态获取当前位置的方法getDynamicCurXY
在工具类utilsTools中封装了动态展示导航顶部弹框数据方法getTopNavigationBoxMgs
在工具类utilsTools中封装了动态画点及线的方法getCaluShowNavigationByInterval

动态获取当前设备旋转角度

getAngleData() {return new Promise((resolve, reject) => {let value = 0if (this.mapConfig.isTestData) {value = this.getRandomInt(0, 360)resolve(value)} else {this.deviceOrientation.getCurrentHeading().then((data: DeviceOrientationCompassHeading) => {value = data["magneticHeading"]resolve(value)},(error: any) => {reject(value)});}});}

动态获取当前坐标

async getDynamicCurXY(xyData) {if (this.mapConfig.isTestData) {xyData.longitude = xyData.longitude - 0.0008xyData.latitude = xyData.latitude - 0.0008} else {let obj = Object.assign({}, this.mapConfig.mapLocationObj)obj.isKeepCallBack = falsexyData = await this.getXYLocationDataByDeviceType(obj)}return xyData}

导航顶部信息展示

getTopNavigationBoxMgs(beginPoint, endPoint) {let topNavigationMsg = {up: true,upDistance: "",down: false,downDistance: "",left: true,leftDistance: "",right: false,rightDistance: "",difDistance: "",lineDistance: "",}let pxy1 = this.coordinateUtil.coorConvert(beginPoint.latitude, beginPoint.longitude, "4549")let pxy2 = this.coordinateUtil.coorConvert(endPoint.latitude, endPoint.longitude, "4549")let pA = {x: pxy1.x,y: pxy1.y,}let pB = {x: pxy2.x,y: pxy2.y,}let dis: any = this.returnDistanceByTwoPoint(pA, pB)let dx = (pA.x - pB.x)let dy = (pA.y - pB.y)if (dx >= 0) {topNavigationMsg.right = falsetopNavigationMsg.left = truetopNavigationMsg.leftDistance = Math.abs(dx).toFixed(2)} else {topNavigationMsg.right = truetopNavigationMsg.left = falsetopNavigationMsg.rightDistance = Math.abs(dx).toFixed(2)}if (dy > 0) {topNavigationMsg.down = truetopNavigationMsg.up = falsetopNavigationMsg.downDistance = Math.abs(dy).toFixed(2)} else {topNavigationMsg.down = falsetopNavigationMsg.up = truetopNavigationMsg.upDistance = Math.abs(dy).toFixed(2)}topNavigationMsg.lineDistance = distopNavigationMsg.difDistance = "0"return topNavigationMsg}

动态画当前点与线的变化

getCaluShowNavigationByInterval(curxy, tarxy, angle, expand) {this.drawNavigationLineDynamic(curxy, tarxy, "navigationLayer", 'polylineDASH', expand)this.locatedByBeginNavigationPoint(curxy, ['pointerArrow'], "navigationLayer", angle)}

5.动态画线

drawNavigationLineDynamic(beginPoint, endPoint, layerName, lineSymbol, expand) {let geoObj = {type: "polyline",paths: [[[Number(beginPoint.longitude), Number(beginPoint.latitude)],[Number(endPoint.longitude), Number(endPoint.latitude)]]],spatialReference: { wkid: this.mapConfig.wkid, latestWkid: this.mapConfig.wkid }}let geoJson = JSON.stringify(geoObj)let attObj = {}let oneObj = { geomertyJSON: geoJson, attributes: attObj };let symbol = { "polyline": [lineSymbol] };this.mapTool.ClearGraphicLayerById(layerName)this.mapTool.AddGraphicToLayer(layerName, [oneObj], symbol);this.mapTool.setCenterByGeo(geoObj, expand, 0.0001)

每次画线前需要将之前图层的起点与线清除ClearGraphicLayerById
画完点线后根据设定的距离判断是否进行缩放setCenterByGeo,0.0001度大约是11米,在mapTool工具类中封装了所有的地图方面的操作,方法基本都是集成的arcgis中的方法

6.动态画点

画带有角度的当前位置点

locatedByBeginNavigationPoint(beginPoint, beginSymbols, layerName, angleValue) {let pointBeginObj = {x: Number(beginPoint.longitude),y: Number(beginPoint.latitude),spatialReference: { wkid: this.mapConfig.wkid, latestWkid: this.mapConfig.wkid }}let pgeoJson = JSON.stringify(pointBeginObj)let pattObj = {angle: angleValue}let beginObj = { geomertyJSON: pgeoJson, attributes: pattObj };let symbolpoint = { "point": beginSymbols };this.mapTool.AddGraphicToLayer(layerName, [beginObj], symbolpoint)}

相关文章:

Arcgis地图实战三:自定义导航功能的实现

文章目录 1.最终效果预览2.计算两点之间的距离3.将点线画到地图上4.动态展示点线的变化5.动态画线6.动态画点 1.最终效果预览 2.计算两点之间的距离 let dis this.utilsTools.returnDisByCoorTrans(qdXYData, zdXYData, "4549")当距离小于我们在配置文件中预设置的…...

LLaMA-Factory 上手即用教程

LLaMA-Factory 是一个高效的大型语言模型微调工具,支持多种模型和训练方法,包括预训练、监督微调、强化学习等,同时提供量化技术和实验监控,旨在提高训练速度和模型性能。 官方开源地址:https://github.com/hiyouga/L…...

黑马点评 秒杀下单出现的问题:服务器异常---java.lang.NullPointerException: null(已解决)

前言: 在此之前找了好多资料,查了很多,都没有找到对应解决的方法,虽然知道是userid为空,但不知道要修改哪里,还是自己的debug能力不足,以后得多加练习。。。 问题如下: 点击限时抢…...

购物街项目TabBar的封装

1.TabBar介绍 在购物街项目中 不论页面如何滚动 始终存在一个TabBar固定在该项目的底部 他在该项目中 扮演者选项卡栏的角色 内部存在若干选项 而选项中 固定存在两部分(图片文本) 其中主要涉及到TabBar/TabBarItem这些和业务无关的共享组件(建议存放于components/common中)、…...

C++游戏开发面试题及参考答案

目录 在游戏开发中,为什么选择 C++ 作为编程语言? 为什么 C++ 语言更适合游戏开发? 描述游戏中的碰撞检测的基本原理。 解释游戏中的碰撞检测机制,并用 C++ 举例说明如何实现。 描述游戏中的物理模拟的基本原理。 阐述游戏中的物理模拟,如重力模拟在 C++ 中的实现方…...

字符串的基本操作(C语言版)

一、实验内容: 采用顺序结构存储串,编写一个函数substring(strl,str2),用于判定str2是否为strl的子串;编写一个函数,实现在两个已知字符串中找出所有非空最长公共子串的长度和最长公共子串的个数; ①字符…...

C缺陷与陷阱 — 7 可移植性缺陷

目录 1 应对C语言标准变更 2 标识符的名称限制 3 整数的大小 4 字符是有符号整数还是无符号整数 5 移位运算符 6 内存位置0 7 除法运算时发生的截断 1 应对C语言标准变更 使用新特性可以使代码更容易编写且减少错误,但可能会导致代码在旧编译器上无法编译。…...

应急响应:玄机_Linux后门应急

https://xj.edisec.net/challenges/95 11关做出拿到万能密码,ATMB6666,后面都在root权限下操作 1、主机后门用户名称:提交格式如:flag{backdoor} cat /etc/passwd,发现后门用户 flag{backdoor} 2、主机排查项中可以…...

C++:捕获 shared_from_this()和捕获this的区别

两种方法的主要区别在于对象的生命周期管理以及捕获方式的不同。以下是对两种方法的详细对比&#xff1a; 第一种&#xff1a;捕获 shared_from_this() 的方法 event.subscribe([self shared_from_this()]() {std::cout << "Event triggered, object is alive.&qu…...

网络协议之TCP

一、定义 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC 793定义。TCP旨在适应支持多网络应用的分层协议层次结构。在因特网协议族&#xff08;Internet p…...

《澳鹏AI全景报告2024》分析最新的数据挑战

华盛顿州柯克兰市&#xff0c;2024 年 10 月 22 日 —— Appen Limited&#xff08;澳大利亚证券交易所代码&#xff1a;APX&#xff09;&#xff0c;一家为人工智能生命周期提供高质量数据的领先供应商&#xff0c;发布了其《2024 年人工智能现状报告》。该报告对美国多个行业…...

【Java每日面试题】—— String、StringBuilder和StringBuffer的区别?

1、String 不可变性:String对象创建后不可变,内容不能被修改,对字符串修改会产生一个新的字符串对象。 线程:线程安全 适用:字符串内容不发生变化或少量字符串操作 String str = "Hello"; str = str + " World"; 2、StringBuffer 不可变性:对…...

【设计模式】【创建型模式(Creational Patterns)】之单例模式

单例模式是一种常用的创建型设计模式&#xff0c;其目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 单例模式的原理 单例模式的核心在于控制类的实例化过程&#xff0c;通常通过以下方式实现&#xff1a; 私有化构造函数&#xff0c;防止外部直接实例化。…...

form表单的使用

模板 <template><el-form :model"formData" ref"form1Ref" :rules"rules"><el-form-item label"手机号" prop"tel"><el-input v-model"formData.tel" /></el-form-item><el-f…...

PDF内容提取,MinerU使用

准备环境 # python 3.10 python3 -m pip install huggingface_hub python3 -m pip install modelscope python3 -m pip install -U magic-pdf[full] --extra-index-url https://wheels.myhloli.com下载需要的模型 import json import osimport requests from huggingface_hub…...

SpringCloud篇(服务网关 - GateWay)

目录 一、简介 二、为什么需要网关 二、gateway快速入门 1. 创建gateway服务&#xff0c;引入依赖 2. 编写启动类 3. 编写基础配置和路由规则 4. 重启测试 5. 网关路由的流程图 6. 总结 三、断言工厂 四、过滤器工厂 1. 路由过滤器的种类 2. 请求头过滤器 3. 默认…...

自动化测试之unittest框架详解

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 unittest 1、什么是Unittest框架&#xff1f; python自带一种单元测试框架 2、为什么使用UnitTest框架&#xff1f; >批量执行用例 >提供丰富的断…...

Vue3 provide 和 inject的使用

在 Vue 中&#xff0c;provide 和 inject 是 Composition API 的一对功能&#xff0c;用于父子组件之间的依赖注入。它们的作用是让父组件可以向其所有子组件提供数据或方法&#xff0c;而不需要通过逐层传递 props。 1. provide provide 用于父组件中&#xff0c;提供数据或…...

掌握Git分布式版本控制工具:从基础到实践

一、引言 在软件开发过程中&#xff0c;版本控制是不可或缺的一环。Git作为一种分布式版本控制工具&#xff0c;以其高效、灵活的特点&#xff0c;受到了广大开发者的青睐。本文将详细介绍Git的基本概念、工作流程、常用命令&#xff0c;以及在IntelliJ IDEA中的操作方法。 二、…...

AndroidStudio与开发板调试时连接失败或APP闪退的解决方案,涉及SELINUX及获取Root权限

现象 用AndroidStudio打开工程代码,点击运行后,报错: 解决方案 具体原因是尝试运行 su(通常用于获取超级用户权限)时失败了,提示 “Permission denied” 通过 CONFIG_SECURITY_SELINUX 变量控制 SElinux 开启或关闭 在vim /rk3568_android_sdk/device/rockchip/rk…...

浏览器访问 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&…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...