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)

	}
相关推荐
WineMonk1 天前
ArcGIS Pro ADGeoDatabase DAML
arcgis·gis·arcgis pro sdk·arcgis pro·daml
WineMonk1 天前
ArcGIS Pro ADCore DAML
arcgis·gis·arcgis pro sdk·arcgis pro·daml
道一云黑板报2 天前
前端搭建低代码平台,微前端如何选型?
低代码·arcgis·iframe·微前端·无界·fronts
笨小古2 天前
路径规划——RRT-Connect算法
算法·路径规划·导航
我不当帕鲁谁当帕鲁2 天前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
没有出口的猎户座2 天前
arcgis做buffer
arcgis
GIS思维3 天前
ArcGIS的汉字(亚洲文本)垂直标注
arcgis·arcgis标注·arcgis垂直标注
GIS思维3 天前
ArcGIS Pro属性表乱码与字段名3个汉字解决方案大总结
字符编码·arcgis·arcgis pro·arcgis pro属性表乱码·shp编码·shp限制
我不当帕鲁谁当帕鲁4 天前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段方式二
前端·javascript·arcgis