当前位置: 首页 > 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…...

SDMatte在跨境电商中的提效实践:多语言商品图批量生成透明底素材

SDMatte在跨境电商中的提效实践&#xff1a;多语言商品图批量生成透明底素材 1. 跨境电商的图片处理痛点 跨境电商运营每天面临的最大挑战之一&#xff0c;就是为不同语言市场的商品生成高质量的透明底素材。传统处理方式存在三大痛点&#xff1a; 人工成本高&#xff1a;设…...

告别低效写作:盘点2026年备受推崇的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。最新实测显示&#xff0c;2026年AI论文写作工具正在重新定义学术效率&#xff0c;覆盖选题构思、文献综述、内容生成、格式排版等核心场景&#xff0c;真正帮你高效搞定论文&#xff0c;省时又省力。 一、全流程王者&#xff1a;一站…...

2026年智慧景区一体化平台服务商精选指南

一、行业背景与筛选逻辑《2025-2026中国智慧旅游发展报告》显示&#xff0c;2025年国内智慧景区市场规模达326亿元&#xff0c;年复合增长率25.6%。但68%的景区面临系统割裂、会员不通、二次消费偏低的核心痛点&#xff0c;全域旅游平台成为数字化转型关键。本文基于技术实力、…...

从入门到精通:Java 异常处理完全指南

Java 异常处理&#xff1a;从原理到实战最佳实践 摘要 异常处理是 Java 开发的核心基础能力&#xff0c;也是区分初级开发者与资深开发者的重要标志。优秀的异常处理能够提升程序的健壮性、可维护性、可调试性&#xff0c;避免程序崩溃、数据丢失、日志混乱等生产问题。本文将…...

3大优势解决UI测试痛点:Maestro跨平台自动化框架实战指南

3大优势解决UI测试痛点&#xff1a;Maestro跨平台自动化框架实战指南 【免费下载链接】maestro Painless Mobile UI Automation 项目地址: https://gitcode.com/GitHub_Trending/ma/maestro UI自动化测试一直是移动应用开发中的关键环节&#xff0c;但传统工具往往面临跨…...

基于springboot框架洪涝灾害救援应急物资管理系统设计与实现-idea maven vue

目录技术栈选型系统模块设计数据库设计关键代码示例实施步骤测试与部署注意事项项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术栈选型 后端框架&#xff1a;Spring Boot 2.7.x&#xff08;简化配置&#xff0c;内置Tomcat…...

2026年AI Agent崛起:从知识库到智慧助手,收藏这份程序员必看指南!

2026年&#xff0c;AI智能体将大规模部署&#xff0c;成为企业数字化核心。与传统AI知识库不同&#xff0c;智能体具备规划、执行、反思和记忆能力&#xff0c;能自主完成任务。核心应用包括跨系统自动化、智能客服、IT运维等。企业需关注多智能体协同、与RPA融合、开放协议及人…...

javaweb项目完整案例SSM框架实现的校园二手交易网站

目录 一、项目介绍 二、项目相关截图 三、源码获取 一、项介绍 计算机毕业设计项目定制|源码定做ssm校园二手交易网站设计与实现_哔哩哔哩_bilibili计算机毕业设计项目定制|源码定做ssm校园二手交易网站设计与实现共计2条视频&#xff0c;包括&#xff1a;A256 964-ssm校园…...

3步掌握OpenCore Legacy Patcher:让老旧Mac重获新生的终极方案

3步掌握OpenCore Legacy Patcher&#xff1a;让老旧Mac重获新生的终极方案 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否有一台被苹果官方抛弃的老旧Intel Mac&am…...

5个Kubernetes网络策略常见误区:从Network Policy Recipes中学习正确配置

5个Kubernetes网络策略常见误区&#xff1a;从Network Policy Recipes中学习正确配置 【免费下载链接】kubernetes-network-policy-recipes Example recipes for Kubernetes Network Policies that you can just copy paste 项目地址: https://gitcode.com/gh_mirrors/ku/kub…...