Arcgis地图实战三:自定义导航功能的实现
文章目录
- 1.最终效果预览
- 2.计算两点之间的距离
- 3.将点线画到地图上
- 4.动态展示点线的变化
- 5.动态画线
- 6.动态画点
1.最终效果预览
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的区别
两种方法的主要区别在于对象的生命周期管理以及捕获方式的不同。以下是对两种方法的详细对比: 第一种:捕获 shared_from_this() 的方法 event.subscribe([self shared_from_this()]() {std::cout << "Event triggered, object is alive.&qu…...
网络协议之TCP
一、定义 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。TCP旨在适应支持多网络应用的分层协议层次结构。在因特网协议族(Internet p…...

《澳鹏AI全景报告2024》分析最新的数据挑战
华盛顿州柯克兰市,2024 年 10 月 22 日 —— Appen Limited(澳大利亚证券交易所代码:APX),一家为人工智能生命周期提供高质量数据的领先供应商,发布了其《2024 年人工智能现状报告》。该报告对美国多个行业…...
【Java每日面试题】—— String、StringBuilder和StringBuffer的区别?
1、String 不可变性:String对象创建后不可变,内容不能被修改,对字符串修改会产生一个新的字符串对象。 线程:线程安全 适用:字符串内容不发生变化或少量字符串操作 String str = "Hello"; str = str + " World"; 2、StringBuffer 不可变性:对…...
【设计模式】【创建型模式(Creational Patterns)】之单例模式
单例模式是一种常用的创建型设计模式,其目的是确保一个类只有一个实例,并提供一个全局访问点。 单例模式的原理 单例模式的核心在于控制类的实例化过程,通常通过以下方式实现: 私有化构造函数,防止外部直接实例化。…...
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服务,引入依赖 2. 编写启动类 3. 编写基础配置和路由规则 4. 重启测试 5. 网关路由的流程图 6. 总结 三、断言工厂 四、过滤器工厂 1. 路由过滤器的种类 2. 请求头过滤器 3. 默认…...

自动化测试之unittest框架详解
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 unittest 1、什么是Unittest框架? python自带一种单元测试框架 2、为什么使用UnitTest框架? >批量执行用例 >提供丰富的断…...
Vue3 provide 和 inject的使用
在 Vue 中,provide 和 inject 是 Composition API 的一对功能,用于父子组件之间的依赖注入。它们的作用是让父组件可以向其所有子组件提供数据或方法,而不需要通过逐层传递 props。 1. provide provide 用于父组件中,提供数据或…...
掌握Git分布式版本控制工具:从基础到实践
一、引言 在软件开发过程中,版本控制是不可或缺的一环。Git作为一种分布式版本控制工具,以其高效、灵活的特点,受到了广大开发者的青睐。本文将详细介绍Git的基本概念、工作流程、常用命令,以及在IntelliJ IDEA中的操作方法。 二、…...

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

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...