主题
查找长度和面积
字数统计: 2.3k 字
阅读时长: 约 6 分钟
当前版本: 4.29
了解如何计算几何的长度和面积。
geometryEngine 提供了计算线长度和面积的功能。几何定义的坐标系 (或空间参考)影响测量结果。如果几何的空间参考是 Web Mercator (3857) 或 WGS84 (4326),则应使用大地测量学方式计算,考虑地球的曲率。如果空间参考与 Web Mercator (3857) 或 WGS84 (4326) 不同,是平面坐标系,则应使用基于欧氏距离。
在本教程中,我们使用 Sketch 微件在视图上绘制图形,并使用 geometryEngine 来计算测地线和平面长度及面积,以查看两个测量值之间的差异。
注: 了解有关使用 Measurement 微件执行测量的更多信息,请访问参考手册
步骤
创建新 Pen
- 开始之前,先完成显示地图教程。
设置 HTML
创建
measurements
div
用于显示计算结果,为其添加一些 CSS 样式来设置字体大小和边距。html#viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } #measurements { padding: 4px 8px; font-size: 16px; bottom: 15px; left: 50%; margin-right: -50%; transform: translate(-50%,-50%); } </style> <link rel="stylesheet" href="https://js.geoscene.cn/4.29/geoscene/themes/light/main.css"> <script src="https://js.geoscene.cn/4.29/"></script> <script> require([ "geoscene/config", "geoscene/Map", "geoscene/views/MapView" ], ( geosceneConfig, Map, MapView, ) => { const map = new Map({ basemap: "tianditu-vector", // Basemap layer service }); const view = new MapView({ container: "viewDiv", map: map, }); </script> </head> <body> <div id="viewDiv"> <div id="measurements" class="geoscene-widget">
添加模块
在
require
语句中,添加模块。GeoScene Maps SDK for JavaScript 提供了 AMD 模块和 ES 模块,本教程中我们是以 AMD 为例。指定
"geoscene/Map"
来加载 Map 模块。加载模块后,它们将作为参数 (例如,Map
) 传递给回调函数,以便在应用程序中使用。保持模块引用和回调参数的顺序相同是很重要的。有关不同类型模块的更多信息,请访问工具指南主题。html<link rel="stylesheet" href="https://js.geoscene.cn/4.29/geoscene/themes/light/main.css"> <script src="https://js.geoscene.cn/4.29/"></script> <script> require([ "geoscene/config", "geoscene/Map", "geoscene/views/MapView", "geoscene/widgets/ScaleBar", "geoscene/widgets/Sketch", "geoscene/Graphic", "geoscene/layers/GraphicsLayer", "geoscene/geometry/geometryEngine", ], ( geosceneConfig, Map, MapView, ScaleBar, Sketch, Graphic, GraphicsLayer, geometryEngine, ) => { const map = new Map({ basemap: "tianditu-vector", // Basemap layer service }); const view = new MapView({ container: "viewDiv", map: map,
重定位并添加比例尺
ScaleBar 微件将在地图上显示比例尺。您可以选择公制或非公制值。例如,如果指定 metric
,则会根据比例显示公里或米。
- js
const view = new MapView({ container: "viewDiv", map: map, center: [-10, 30], zoom: 3, });
创建
scalebar
并将view
参数设置为view
。将unit
指定为metric
。jscenter: [-10, 30], zoom: 3, }); const scalebar = new ScaleBar({ view: view, unit: "metric" });
将
scalebar
添加至view
的bottom-right
。jscenter: [-10, 30], zoom: 3, }); const scalebar = new ScaleBar({ view: view, unit: "metric" }); view.ui.add(scalebar, "bottom-right");
运行应用程序以验证
center
和zoom
级别中的更改。scalebar
应显示在视图的底部。
添加草绘微件
Sketch 微件提供的 UI 允许您在 MapView 中创建和更新图形。
创建
graphicsLayer
,将GraphicsLayer
添加到map
。jsconst scalebar = new ScaleBar({ view: view, unit: "metric" }); view.ui.add(scalebar, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer);
创建
sketch
微件,layer
参数设置为graphicsLayer
。这样使用微件绘制的任何几何都将添加到graphicsLayer
中。设置一些属性控制要素的显示,availableCreateTools
设置为仅显示polyline
、polygon
和rectangle
,禁用在visibleElements
和selectionTools
的默认值。jsconst scalebar = new ScaleBar({ view: view, unit: "metric" }); view.ui.add(scalebar, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer); const sketch = new Sketch({ layer: graphicsLayer, view: view, availableCreateTools: ["polyline", "polygon", "rectangle"], creationMode: "update", updateOnGraphicClick: true, visibleElements: { createTools: { point: false, circle: false }, selectionTools:{ "lasso-selection": false, "rectangle-selection":false, }, settingsMenu: false, undoRedoMenu: false } });
将
sketch
微件添加到view
的top-right
处。jsconst sketch = new Sketch({ layer: graphicsLayer, view: view, availableCreateTools: ["polyline", "polygon", "rectangle"], creationMode: "update", updateOnGraphicClick: true, visibleElements: { createTools: { point: false, circle: false }, selectionTools:{ "lasso-selection": false, "rectangle-selection":false, }, settingsMenu: false, undoRedoMenu: false } }); view.ui.add(sketch, "top-right");
将
measurements
元素添加到view
中以在绘制几何时显示测量值。jsview.ui.add(sketch, "top-right"); const measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual");
运行应用程序以验证微件是否显示在视图中,以及您是否能够绘制几何。
计算长度和面积
geometryEngine
提供了计算几何的平面长度/面积或测地线长度/面积的功能。由于此应用程序中的几何使用的是 Web Mercator 投影,因此最佳做法是使用测地线测量。但是,我们要展示测地线计算和平面计算之间的差异,需要在绘制几何时同时测量这两者。
定义
getArea
函数,参数为polygon
。调用geodesicArea()
方法和planarArea()
方法来计算多边形的面积,以square-kilometers
为单位。jsconst measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual"); function getArea(polygon) { const geodesicArea = geometryEngine.geodesicArea(polygon, "square-kilometers"); const planarArea = geometryEngine.planarArea(polygon, "square-kilometers"); }
将计算结果追加到
measurements
的innerHTML
中。jsfunction getArea(polygon) { const geodesicArea = geometryEngine.geodesicArea(polygon, "square-kilometers"); const planarArea = geometryEngine.planarArea(polygon, "square-kilometers"); measurements.innerHTML = "<b>Geodesic area</b>: " + geodesicArea.toFixed(2) + " km\xB2" + "| <b>Planar area</b>: " + planarArea.toFixed(2) + " km\xB2"; }
定义
getLength
函数,参数为line
。调用geodesicLength
和planarLength
方法来计算line
的长度,以千米为单位。jsmeasurements.innerHTML = "<b>Geodesic area</b>: " + geodesicArea.toFixed(2) + " km\xB2" + "| <b>Planar area</b>: " + planarArea.toFixed(2) + " km\xB2"; } function getLength(line) { const geodesicLength = geometryEngine.geodesicLength(line, "kilometers"); const planarLength = geometryEngine.planarLength(line, "kilometers"); }
将测地线长度计算的结果追加到
measurements
的innerHTML
中。jsfunction getLength(line) { const geodesicLength = geometryEngine.geodesicLength(line, "kilometers"); const planarLength = geometryEngine.planarLength(line, "kilometers"); measurements.innerHTML = "<b>Geodesic length</b>: " + geodesicLength.toFixed(2) + " km" + "| <b>Planar length</b>: " + planarLength.toFixed(2) + " km"; }
增加判断
switch
语句,几何为polygon
时,调用getArea
函数;几何为polyline
时,调用getLength
函数。jsfunction getLength(line) { const geodesicLength = geometryEngine.geodesicLength(line, "kilometers"); const planarLength = geometryEngine.planarLength(line, "kilometers"); measurements.innerHTML = "<b>Geodesic length</b>: " + geodesicLength.toFixed(2) + " km" + "| <b>Planar length</b>: " + planarLength.toFixed(2) + " km"; } function switchType(geom) { switch (geom.type) { case "polygon": getArea(geom); break; case "polyline": getLength(geom); break; default: console.log("No value found"); } }
创建默认图形以测量
要向用户展示与应用程序交互的方式,请创建一个默认多边形,并在应用程序启动时显示其区域。
创建
polygon
。将type
设置为polygon
,并将spatialReference
属性中的wkid
设置为3857
(Web Mercator)。创建simplePolygonSymbol
来设置图形样式。jsconst measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual"); const polygon = { type: "polygon", spatialReference: { wkid: 3857, }, rings: [ [ [-4508069.082189632, 3599936.936171892], [-4508069.082189632, 5478453.343307884], [-2629552.6750536393, 5478453.343307884], [-2629552.6750536393, 3599936.936171892], [-4508069.082189632, 3599936.936171892], ], ], }; const simplePolygonSymbol = { type: "simple-fill", outline: { color: [200, 0, 0], width: 2, }, };
创建 Graphic 类实例。将
geometry
和symbol
属性设置为polygon
和simplePolygonSymbol
。将图形添加到graphicsLayer
。jsconst measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual"); const polygon = { type: "polygon", spatialReference: { wkid: 3857, }, rings: [ [ [-4508069.082189632, 3599936.936171892], [-4508069.082189632, 5478453.343307884], [-2629552.6750536393, 5478453.343307884], [-2629552.6750536393, 3599936.936171892], [-4508069.082189632, 3599936.936171892], ], ], }; const simplePolygonSymbol = { type: "simple-fill", outline: { color: [200, 0, 0], width: 2, }, }; const polygonGraphic = new Graphic({ geometry: polygon, symbol: simplePolygonSymbol }); graphicsLayer.add(polygonGraphic);
when
加载view
时,调用polygonGraphic
上的update
方法,并基于polygonGraphic
的geometry
调用getArea
函数。jsgraphicsLayer.add(polygonGraphic); view.when(() => { sketch.update(polygonGraphic); getArea(polygonGraphic.geometry); });
添加事件监听器
Sketch 微件的设置允许编辑视图中的几何。创建事件监听器,监听几何的更新状态,动态测量其面积或长度。
创建一个事件监听器,用于在创建、调整大小或移动图形时监听
update
on
的更改。使用事件中第一个图形的geometry
设置geometry
元素。jsview.when(() => { sketch.update(polygonGraphic); getArea(polygonGraphic.geometry); }); sketch.on("update", (e) => { const geometry = e.graphics[0].geometry; });
根据
sketch
事件的state
是start
、complete
,还是处于更改状态而创建条件语句。对于每个状态 (complete
除外),调用switchType
语句,其中geometry
为其参数。当事件complete
后,从graphicsLayer
中移除图形并清除innerHTML
。jssketch.on("update", (e) => { const geometry = e.graphics[0].geometry; if (e.state === "start") { switchType(geometry); } if (e.state === "complete") { graphicsLayer.remove(graphicsLayer.graphics.getItemAt(0)); measurements.innerHTML = null; } if ( e.toolEventInfo && (e.toolEventInfo.type === "scale-stop"|| e.toolEventInfo.type === "reshape-stop"|| e.toolEventInfo.type === "move-stop") ) { switchType(geometry); } });
运行应用程序
在 CodePen 中,运行代码以显示地图。
运行应用程序时,您将看到一个面及其计算出的测地线面积和平面面积。您可以使用草绘微件绘制其他几何并显示其测量值。如果移动几何,测地线测量值将更改,但平面测量值不会更改。
下一步是什么?
要了解如何使用其他API 功能,请参阅以下教程: