文章目录
- 前言
- 一、三维测量,测距,高程是什么?
- 二、使用步骤
- 1.引入库
- 2.初始化Draw
- 3.初始化图层
- 4.测量距离功能
- 5.测量面积
- 5.测量高程
- 清理地图图层
前言
ArcGIS for JS广泛应用于需要在Web上展示和分析空间数据的各种场景中,包括教育、科研和商业领域。它特别适合GIS分析师、IT开发人员以及任何需要在Web上分享和利用地理信息的人员
一、三维测量,测距,高程是什么?
三维测量是指对物体进行全方位测量,确定其三维坐标测量数据。其测量原理包括测距、角位移、扫描和定向四个方面。根据三维技术原理研发的仪器主要有拍照式(结构光)三维扫描仪、激光三维扫描仪和三坐标测量机等
测距是三维测量中的一个重要组成部分,它通过测量物体与测量设备之间的距离来确定物体的位置。测距的方法有多种,包括激光测距、超声波测距、红外测距等。激光测距是最常见的一种,通过发射激光并测量其反射时间来计算距离。
高程指的是某点沿铅垂线方向到绝对基面的距离,称为绝对高程,简称高程。高程是地理测量中的一个重要概念,用于表示地面点的高低。高程系统采用不同的基准面表示地面点的高低,常见的系统包括正高、正常高、力高和大地高程等
高程测量主要有水准测量和三角高程测量等方法。水准测量是利用水平视线来测量两点间的高差,由于其精度较高,因此是高程测量中最主要的方法。三角高程测量则是通过测量两点间的水平距离或斜距和竖直角来计算高差,一般精度较低,仅在适当条件下采用
二、使用步骤
1.引入库
代码如下(示例):
import { Polyline } from '@arcgis/core/geometry';
import Graphic from '@arcgis/core/Graphic';
import Point from '@arcgis/core/geometry/Point';
import * as geometryEngine from '@arcgis/core/geometry/geometryEngine';
import Draw from '@arcgis/core/views/draw/Draw';
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer';
import Polygon from '@arcgis/core/geometry/Polygon';
import TextSymbol from '@arcgis/core/symbols/TextSymbol';
import ElevationLayer from '@arcgis/core/layers/ElevationLayer';
import SimpleMarkerSymbol from '@arcgis/core/symbols/SimpleMarkerSymbol';
2.初始化Draw
初始化的时候必须保证三维view初始化结束
drawBar = new Draw({ view: view3d });
3.初始化图层
必须初始化点线面的图层为的就是好管理地图操作
const newLineLayer = new GraphicsLayer({id: 'LandQueryDrawLayer',elevationInfo: {mode: 'on-the-ground',},});view3d.map.add(newLineLayer);const newPolygonLayer = new GraphicsLayer({id: 'LandQueryPolygonDrawLayer',elevationInfo: {mode: 'on-the-ground',},});view3d.map.add(newPolygonLayer);const newPointLayer = new GraphicsLayer({id: 'LandQueryPointDrawLayer',elevationInfo: {mode: 'on-the-ground',},});
4.测量距离功能
绘制点成线,利用arcgis的计算模块进行
测量距离const measureDistance = () => {clearMeasureActionAndGraphics();distanceMeasure = true; //激活距离测量let action = drawBar.create('polyline'); //创建画线实例view3d.focus();action.on(['vertex-add', // when a vertex is added 鼠标单击'vertex-remove', // when a vertex is removed 移除'cursor-update', // when the pointer moves 鼠标移动'draw-complete', // when the drawing is completed 鼠标双击],function (evt) {createLine(evt.vertices);},);};const createLine = (vertices) => {view3d.map.findLayerById('LandQueryDrawLayer').removeAll(); //清空上次绘制的线let symbol = {//点样式type: 'simple-marker',color: [47, 79, 79],width: 0.5,size: 4,outline: {color: [0, 0, 0],width: 1,},};//将起点添加到地图let startGraphics = new Graphic({geometry: new Point({type: 'point',x: vertices[0][0], //当底图是投影坐标系时用x,地理坐标系用longitudey: vertices[0][1], //当底图是投影坐标系时用y,地理坐标系用latitudespatialReference: view3d.spatialReference, //和底图相同的坐标系}),symbol: symbol,});view3d.map.findLayerById('LandQueryDrawLayer').add(startGraphics);//将线添加到地图let lineGraphics = new Graphic({geometry: new Polyline({paths: vertices,spatialReference: view.spatialReference,}),symbol: {//线样式type: 'simple-line', // autocasts as new SimpleFillSymbolstyle: 'dash',color: [176, 196, 222],width: 2,},});view3d.map.findLayerById('LandQueryDrawLayer').add(lineGraphics);//测距let linePath = []; //线段坐标集合let pointStart = []; //起点pointStart.push(vertices[0][0]);pointStart.push(vertices[0][1]);linePath.push(pointStart);for (let i = 1; i < vertices.length; i++) {//获得鼠标移动的坐标信息let point = {type: 'point',x: vertices[i][0],y: vertices[i][1],spatialReference: view3d.spatialReference,};//鼠标位置let mouseGraphics = new Graphic({geometry: point,symbol: symbol,});let xy = []; //鼠标当前经纬度xy.push(vertices[i][0]);xy.push(vertices[i][1]);linePath.push(xy);let line = new Polyline({//起点到当前鼠标的线段paths: linePath,spatialReference: view3d.spatialReference,});let length = geometryEngine.geodesicLength(line, 'meters').toFixed(2); //测距let lengthText = lengthFormat(length); //单位转换let textSymbol = {//距离标注type: 'text',color: 'white',haloColor: 'black',haloSize: '2px',text: lengthText,xoffset: '50px',yoffset: '-5px',font: {size: 12,family: 'sans-serif',weight: 'bold',},};let textGraphics = new Graphic({//标注位置为鼠标位置geometry: point,symbol: textSymbol,});//将标注和鼠标位置添加到地图view3d.map.findLayerById('LandQueryDrawLayer').addMany([textGraphics, mouseGraphics]);}};
5.测量面积
/*** 面积测量,对外暴露*/const measureArea = () => {clearMeasureActionAndGraphics();areaMeasure = true;let action = drawBar.create('polygon'); //创建画线实例view3d.focus();action.on(['vertex-add', // when a vertex is added 鼠标单击'vertex-remove', // when a vertex is removed 移除'cursor-update', // when the pointer moves 鼠标移动'draw-complete', // when the drawing is completed 鼠标双击],function (evt) {// 检查在绘制完成时,vertices 是否构成有效的多边形let vertices = evt.vertices;if (vertices.length < 3) {console.error('至少需要三个点来形成有效的多边形!');return;}// 确保多边形是封闭的:将第一个点添加到末尾if (!isPolygonClosed(vertices)) {vertices.push(vertices[0]); // 添加第一个点到末尾,封闭多边形}createPolygon(vertices); // 调用函数绘制多边形},);};//画面和测量面积const createPolygon = (vertices) => {view3d.map.findLayerById('LandQueryPolygonDrawLayer').removeAll();let symbol = {//点样式type: 'simple-marker',color: [47, 79, 79],width: 0.5,size: 4,outline: {color: [0, 0, 0],width: 1,},};let fillSymbol = {//面样式type: 'simple-fill', // autocasts as new SimpleFillSymbol()color: [3, 255, 240, 0.1],outline: {// autocasts as new SimpleLineSymbol()color: [255, 116, 3],width: 2,},};let polygon = new Polygon({rings: vertices,spatialReference: view3d.spatialReference,});let polygonGraphics = new Graphic({geometry: polygon,symbol: fillSymbol,});view3d.map.findLayerById('LandQueryPolygonDrawLayer').add(polygonGraphics);const area = Math.abs(geometryEngine.geodesicArea(polygon, 'square-meters'),);let areaText = areaFormat(area);let center = polygon.centroid;let pointCenter = {type: 'point',longitude: center.longitude,latitude: center.latitude,};let textSymbol = {//面积标注type: 'text',color: 'white',haloColor: 'black',haloSize: '2px',text: areaText,//xoffset: '50px',//yoffset: '-5px',font: {size: 12,family: 'sans-serif',weight: 'bold',},};let textGraphics = new Graphic({//标注为面中心位置geometry: pointCenter,symbol: textSymbol,});view3d.map.findLayerById('LandQueryPolygonDrawLayer').add(textGraphics);for (let i = 0; i < vertices.length; i++) {let point = {type: 'point',x: vertices[i][0],y: vertices[i][1],spatialReference: view3d.spatialReference,};let pointGraphics = new Graphic({geometry: point,symbol: symbol,});view3d.map.findLayerById('LandQueryPolygonDrawLayer').add(pointGraphics);}};
5.测量高程
添加地图点击事件
view3d.on('click', (event) => {const point = event.mapPoint;if (heightMeasure) {// 查询高程getElevation(point);}});
//获取高程const getElevation = (point) => {console.log(5555555, point);const pointGeometry = new Point({longitude: point.longitude,latitude: point.latitude,});displayElevationOnMap(pointGeometry, point.z);elevationLayer.queryElevation([pointGeometry]).then(function (result) {const elevation = result[0].z; // 获取返回的第一个样本的高程值console.log('Elevation at clicked point:', elevation);// 在地图上显示高程displayElevationOnMap(pointGeometry, point.z);}).catch(function (error) {console.error('Error fetching elevation:', error);});};// 显示高程信息在地图上const displayElevationOnMap = (point, elevation) => {if (view3d.map.findLayerById('LandQueryPointDrawLayer')) {view3d.map.findLayerById('LandQueryPointDrawLayer').removeAll();}// 创建文本符号const textSymbol = new TextSymbol({text: `高程值: ${elevation.toFixed(2)}米`,color: 'white',haloColor: 'black',haloSize: '2px',font: {size: 12,family: 'sans-serif',weight: 'bold',},});const markerSymbol = new SimpleMarkerSymbol({color: [226, 119, 40], // 设置标记颜色size: '10px', // 设置标记大小outline: {// 设置边框color: [255, 0, 0],width: 2,},});// 创建图形const graphicPoint = new Graphic({geometry: point,symbol: markerSymbol,});const graphicText = new Graphic({geometry: point,symbol: textSymbol,});// 将图形添加到视图中view3d.map.findLayerById('LandQueryPointDrawLayer').add(graphicPoint);view3d.map.findLayerById('LandQueryPointDrawLayer').add(graphicText);};const lengthFormat = (length) => {if (length < 2000) {return length + '米';} else {length = (length / 1000).toFixed(2);return length + '千米';}};const areaFormat = (area) => {if (area < 2000) {area = area.toFixed(2);return area + '平方米';} else {area = (area / 10000).toFixed(2);return area + '平方千米';}};const clearMeasureActionAndGraphics = () => {distanceMeasure = false;areaMeasure = false;heightMeasure = false;drawBar.destroy();};
清理地图图层
整个关于ARCGIS的测量功能就完美实现了
const clearMeasureActionAndGraphicsLine = () => {if (view3d.map.findLayerById('LandQueryDrawLayer')) {view3d.map.findLayerById('LandQueryDrawLayer').removeAll();}clearMeasureActionAndGraphics();};const clearMeasureActionAndGraphicsPolygon = () => {if (view3d.map.findLayerById('LandQueryPolygonDrawLayer')) {view3d.map.findLayerById('LandQueryPolygonDrawLayer').removeAll();}clearMeasureActionAndGraphics();};const clearMeasureActionAndGraphicsPoint = () => {if (view3d.map.findLayerById('LandQueryPointDrawLayer')) {view3d.map.findLayerById('LandQueryPointDrawLayer').removeAll();}clearMeasureActionAndGraphics();};