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

文章目录

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 通州120
        let 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);
            //a0
            let 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));
            //a4
            let 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));
            //a6
            let 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));
            //a8
            let a8 = 0.125 * m_aAxis * (1 - e1) * (315.0 / 16384.0 * Math.pow(e1, 4));
            纬度转换为弧度表示
            //B
            let B = mX * dblD2R;
            //l
            let l = (mY - m_dbMidLongitude) * dblD2R;
            X
            let 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;
            //N
            let N = c / Math.sqrt(1 + ll);
            //t
            let 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 = 0
			if (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.0008
			xyData.latitude = xyData.latitude - 0.0008
		} else {
			let obj = Object.assign({}, this.mapConfig.mapLocationObj)
			obj.isKeepCallBack = false
			xyData = 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 = false
			topNavigationMsg.left = true
			topNavigationMsg.leftDistance = Math.abs(dx).toFixed(2)
		} else {
			topNavigationMsg.right = true
			topNavigationMsg.left = false
			topNavigationMsg.rightDistance = Math.abs(dx).toFixed(2)
		}
		if (dy > 0) {
			topNavigationMsg.down = true
			topNavigationMsg.up = false
			topNavigationMsg.downDistance = Math.abs(dy).toFixed(2)
		} else {
			topNavigationMsg.down = false
			topNavigationMsg.up = true
			topNavigationMsg.upDistance = Math.abs(dy).toFixed(2)
		}
		topNavigationMsg.lineDistance = dis
		topNavigationMsg.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)

	}
相关推荐
GISerQ.19 小时前
ArcGIS计算土地转移矩阵
arcgis·土地利用·土地转移矩阵
小仙有礼了2 天前
Arcgis for javascript 开发学习经验
javascript·学习·arcgis
规划GIS会2 天前
【ArcGIS Pro】实现一下完美的坐标点标注
arcgis
中科GIS地理信息培训2 天前
ArcGIS Pro 3.4新功能3:空间统计新特性,基于森林和增强分类与回归,过滤空间自相关
arcgis·分类·回归·arcgis pro
赵钰老师2 天前
【ArcGIS Pro】水文水资源、水生态与水环境
人工智能·python·机器学习·arcgis·chatgpt·数据分析
中科GIS地理信息培训2 天前
ArcGIS Pro 3.4新功能2:Spatial Analyst新特性,密度、距离、水文、太阳能、表面、区域分析
arcgis·arcgis pro
规划GIS会3 天前
【ArcGIS Pro】做个宽度渐变的河流符号
arcgis
我不当帕鲁谁当帕鲁3 天前
arcgis for js实现地图截图、地图打印
前端·javascript·arcgis
i小杨4 天前
Express (nodejs) 相关
arcgis·express
杨超越luckly4 天前
利用高德API获取整个城市的公交路线并可视化(七)
大数据·算法·arcgis·信息可视化·数据挖掘·数据分析