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…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
