源码:https://github.com/sueRimn/Ar…
这个功能主要实现鼠标在地图上点击两点进行测距。
在 ArcGIS for qml
中是没有直接封装好的测距模块的,查看文档可以看见:
文档明确说明,不能在 QML
中声明或创建 Distance
组件
1. 确认所需
实现测距功能,首先还是明确需求,利用鼠标点击进行测距,点击第一次确定起始点,第二次确定终点,终点确定,距离路径出现,随之距离显示出来。
由此可知,需要两个点,一条路径,一个文本。
2. 布局
(1)地图测距,地基肯定是地图底图,MapView{Map{} }
(2)要在地图上添加点以及路径,需要符号,所以需要图层来承载 GraphicsOverlay{Graphic{ Symbol:}}
(3)显示距离,需要一个 Text
固定位置显示,在最上层 Text{}
3. 计算距离
(1)单位
查看文档中对 Distance
的说明,可以看的一个相关的类型叫 liearUnit->
实例或线性测量操作的特定测量单位
是从 Unit
类型继承的类型实例被初始化为特定的度量单位。每个实例都具有单元名称的属性(单数,复数和缩写),并提供单位转换的方法。
往上查看 linearUnit
的父级可以看到
Unit
是测量单位的基本类型,但是不允许在 QML
中进行声明和创建。但是 Unit
下面的子类型有三个:LinearUnit
(线性单位)、AngularUnit
(度量单位)、AreaUnit
(面积单位)都是可以在 qml
中声明创建的。测距所需的肯定就是线性单位了。
(2)路径线(Path)
关于线段,几何图形都得由 polygon
来创建,路径是线段,所以选择其中PolylineBuilder
,至于如何生成随机鼠标点击的两点之间的线呢
在文档中搜索Distance
,可以得到 6 个类型结果
其中,有一个 GeodeticDistanceResult
类型,距离结果,点开看发现不能在 QMl
中声明创建,但是有一句话
所以点击蓝色标注的地方,可以知道,几何引擎 提供一组方法以对几何实例执行几何操作,关于几何的计算都可以在此找到。
有一个方法
返回点集成的线,所需参数都给出了,完全可以得到。这样就得到了 path
,path
是起始点和终点之间的点集成的路径线,每个点之间的距离长度可以根据 maxSegmentLength
进行自行设置。
(3)计算
目前我们所需的就是如何得到地面距离长度,依然在几何引擎中找所需要的参数依然很容易得到,所以可以完成功能了。
4. 核心代码
onMouseClicked: {
clickNum++
if(clickNum == 1){// 鼠标点击第一次 确实起点位置 并添加图形
console.log(clickNum)
dis_startPoint = mouse.mapPoint
//graphicsOverlayer.graphics.append(createGraphic(dis_startPoint,startMarkSymbol))
var dis_start = GeometryEngine.project(dis_startPoint,spatialReference.createWgs84())
dis_startGraphic.geometry = dis_start
console.log(dis_startPoint)
}
if(clickNum == 2){// 鼠标点击第二次 确定终点位置 并添加图形
console.log(clickNum)
clickNum = 0;
dis_endPoint = mouse.mapPoint
var dis_end = GeometryEngine.project(dis_endPoint,spatialReference.createWgs84())
dis_endGraphic.geometry = dis_end
console.log(dis_endPoint)
// 创建路径线
var polylineBuilder = ArcGISRuntimeEnvironment.createObject("PolylineBuilder", {spatialReference:SpatialReference.createWgs84()});
polylineBuilder.addPoints([dis_startGraphic.geometry,dis_endGraphic.geometry])
var polyline = polylineBuilder.geometry;
// 生成路径线
var maxSegmentLength = 1;
var unitOfMeasurement = ArcGISRuntimeEnvironment.createObject("LinearUnit", {linearUnitId: Enums.LinearUnitIdKilometers});
var curveType = Enums.GeodeticCurveTypeGeodesic;
var pathGeometry = GeometryEngine.densifyGeodetic(polyline, maxSegmentLength, unitOfMeasurement, curveType);
pathGraphic.geometry = pathGeometry;
// 计算距离
distanceText = GeometryEngine.lengthGeodetic(pathGeometry,unitOfMeasurement,curveType).toFixed(2)
console.log("polyline builded",distanceText + "km")
}
}