主题
查找空间关系
字数统计: 2k 字
阅读时长: 约 5 分钟
当前版本: 4.29
了解如何确定几何之间的空间关系。
空间关系 (*spatial relation*) 指一个几何与另一个几何的拓扑关联关系。这种关联关系通过要素内部、边界和外部确定。
在本教程中,我们演示如何使用 geometryEngine
来确定两个几何之间的空间关系。要确定空间关系是否存在,可以尝试 intersects
、disjoint
和 within
等操作。如果操作成功,则存在对应空间关系。
步骤
创建新 Pen
- 在此之前,先了解显示地图教程 。
添加模块
通过
require
引入Graphic
、GraphicsLayer
、Sketch
和geometryEngine
模块。更多信息
GeoScene Maps SDK for JavaScript 提供了 AMD 模块和 ES 模块,本教程中我们是以 AMD 为例。AMD 使用
require
函数加载模块 - 例如,您可以指定"geoscene/Map"
来加载 Map 模块。加载后,它们将作为参数 (例如,Map
) 传递给回调函数,以便在应用程序中使用。保持引用模块和回调参数的顺序相同是很重要的。有关不同类型模块的更多信息,请访问工具指南主题。jsrequire([ "geoscene/config", "geoscene/Map", "geoscene/views/MapView", "geoscene/Graphic", "geoscene/layers/GraphicsLayer", "geoscene/widgets/Sketch", "geoscene/geometry/geometryEngine" ], (geosceneConfig, Map, MapView, Graphic, GraphicsLayer, Sketch, geometryEngine) => {
添加 HTML 元素
添加 <div>
元素,显示各种空间关系情况。
使用 HTML 创建
div
元素以显示要评估的每种空间关系。html<div id="viewDiv"></div> <div id="relationshipResults" class="geoscene-widget"> <div><b>Spatial relationships</b></div> <div id="Contains"></div> <div id="Crosses"></div> <div id="Disjoint"></div> <div id="Equals"></div> <div id="Intersects"></div> <div id="Overlaps"></div> <div id="Touches"></div> <div id="Within"></div> </div>
将
relationshipResults
添加至视图 UI 的右下角。jsconst view = new MapView({ map: map, center: [118.80500, 34.02700], //经度,纬度 zoom: 12, container: "viewDiv" }); const relationshipDiv = document.getElementById("relationshipResults"); view.ui.add(relationshipDiv, "bottom-right");
为
relationshipResults
<div>
设置CSS样式 。js.viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } .relationshipResults { width: 175px; padding: 10px; }
创建图形
执行空间关系需要两个几何图形。我们创建一个折线和一个面图形来演示空间关系。
注 :了解更多关于图形添加到地图的信息,请访问添加点、线和面教程。
创建一个
GraphicsLayer
类,添加到map
中。jsconst view = new MapView({ map: map, center: [118.80500, 34.02700], //经度,纬度 zoom: 12, container: "viewDiv" }); const relationshipDiv = document.getElementById("relationshipResults"); view.ui.add(relationshipDiv, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer);
定义一个折线图形,添加至
graphicsLayer
。jsconst view = new MapView({ map: map, center: [118.80500, 34.02700], //经度,纬度 zoom: 12, container: "viewDiv" }); const relationshipDiv = document.getElementById("relationshipResults"); view.ui.add(relationshipDiv, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer); const polyline = { type: "polyline", paths: [ [13227000.704542402, 4032506.197638312], [13223540.698857695, 4034443.92109266], [13222135.94452635, 4032506.197638312], [13221470.479577951, 4033494.9524006792], [13221470.404932415, 4033494.9524006792] ], spatialReference: { wkid: 102100 } }; const simpleLineSymbol = { type: "simple-line", width: 2 }; const polylineGraphic = new Graphic({ geometry: polyline, symbol: simpleLineSymbol }); graphicsLayer.add(polylineGraphic);
创建面图形并将其添加至
graphicsLayer
。jsconst view = new MapView({ map: map, center: [118.80500, 34.02700], //经度,纬度 zoom: 12, container: "viewDiv" }); const relationshipDiv = document.getElementById("relationshipResults"); view.ui.add(relationshipDiv, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer); const polyline = { type: "polyline", paths: [ [13227000.704542402, 4032506.197638312], [13223540.698857695, 4034443.92109266], [13222135.94452635, 4032506.197638312], [13221470.479577951, 4033494.9524006792], [13221470.404932415, 4033494.9524006792] ], spatialReference: { wkid: 102100 } }; const simpleLineSymbol = { type: "simple-line", width: 2 }; const polylineGraphic = new Graphic({ geometry: polyline, symbol: simpleLineSymbol }); graphicsLayer.add(polylineGraphic); // Create a polygon geometry const polygon = { type: "polygon", rings: [ [13228098.704542402, 4035365.9427463487], [13226362.225451587, 4035365.9427463487], [13226362.225451587, 4032059.2948176656], [13228098.704542402, 4032059.2948176656], [13228098.704542402, 4035365.9427463487] ], spatialReference: { wkid: 102100 } }; const simpleFillSymbol = { type: "simple-fill" }; const polygonGraphic = new Graphic({ geometry: polygon, symbol: simpleFillSymbol }); graphicsLayer.add(polygonGraphic);
将图形添加至
selectedGraphics
数组。jsgraphicsLayer.add(polygonGraphic); let selectedGraphics = [polygonGraphic, polylineGraphic];
运行代码以验证图形是否显示在视图中。
创建草绘微件
使用 Sketch 和 GraphicsLayer 类,我们进一步展示如何根据草绘图形的变化实时更新空间关系。
定义 Sketch 微件对象,设置
layer
值为之前定义的graphicsLayer
。这样可以通过草图微件移动和更新在上一步中创建的线和折线图形。在 Sketch 微件上启用snappingOptions
设置。最后,设置微件的visibleElements
,移除不需要的工具。jslet selectedGraphics = [polygonGraphic, polylineGraphic]; const sketch = new Sketch({ view: view, layer: graphicsLayer, updateOnGraphicClick: true, snappingOptions: { enabled: true, featureSources: [{ layer: graphicsLayer }] }, visibleElements: { createTools: { point: false }, selectionTools: { "lasso-selection": false, "rectangle-selection": false, }, settingsMenu: false, undoRedoMenu: false } });
将草绘微件添加到视图
UI
的右上角。jsconst sketch = new Sketch({ view: view, layer: graphicsLayer, updateOnGraphicClick: true, snappingOptions: { enabled: true, featureSources: [{ layer: graphicsLayer }] }, visibleElements: { createTools: { point: false }, selectionTools: { "lasso-selection": false, "rectangle-selection": false, }, settingsMenu: false, undoRedoMenu: false } }); view.ui.add(sketch, "top-right");
运行代码以验证草绘微件是否显示在视图中。
确定空间关系
空间关系是根据两个几何的内部、边界和外部确定的。使用 contains()
和 intersects()
等方法查找草图几何之间的空间关系。
定义
showSpatialRelationship
函数,根据空间关系更新元素中的显示值。如果空间关系的value
为 true,则以粗体显示。jsview.ui.add(sketch, "top-right"); function showSpatialRelationship(string, value) { const element = document.getElementById(string) if (value) { element.innerHTML = "<b>" + string + ": " + value + "</b>"; } else { element.innerHTML = string + ": " + value; } }
定义函数
onGraphicUpdate
,处理图形变化时的操作。jsview.ui.add(sketch, "top-right"); function onGraphicUpdate() { } function showSpatialRelationship(string, value) { const element = document.getElementById(string) if (value) { element.innerHTML = "<b>" + string + ": " + value + "</b>"; } else { element.innerHTML = string + ": " + value; } }
图形更新时,从
selectedGraphics
数组中提取几何,接下来分析它们的空间关系。jsfunction onGraphicUpdate() { let geometry1 = selectedGraphics[0].geometry; let geometry2 = selectedGraphics[1].geometry; }
判断两个几何每种空间关系的结果,并在
relationshipResults
div 块级元素中显示结果。调用showSpatialRelationship
函数显示结果。jsfunction onGraphicUpdate() { let geometry1 = selectedGraphics[0].geometry; let geometry2 = selectedGraphics[1].geometry; const contains = geometryEngine.contains(geometry1, geometry2); showSpatialRelationship("Contains", contains) const crosses = geometryEngine.crosses(geometry1, geometry2); showSpatialRelationship("Crosses", crosses) const disjoint = geometryEngine.disjoint(geometry1, geometry2); showSpatialRelationship("Disjoint", disjoint) const equals = geometryEngine.equals(geometry1, geometry2); showSpatialRelationship("Equals", equals) const intersects = geometryEngine.intersects(geometry1, geometry2); showSpatialRelationship("Intersects", intersects) const overlaps = geometryEngine.overlaps(geometry1, geometry2); showSpatialRelationship("Overlaps", overlaps) const touches = geometryEngine.touches(geometry1, geometry2); showSpatialRelationship("Touches", touches) const within = geometryEngine.within(geometry1, geometry2); showSpatialRelationship("Within", within) }
添加事件监听器
创建事件监听器,在绘制或更新新几何时触发。如果绘制新几何,则会从 selectedGraphics
数组中移除最后一个几何。调用 onGraphicUpdate
函数,确定其余几何之间的空间关系。
监听 Sketch 微件上的事件。监视
update
、undo
或redo
事件,并调用onGraphicUpdate
方法以确定这些事件发生时的空间关系。jsview.ui.add(sketch, "top-right"); sketch.on(["update", "undo", "redo"], onGraphicUpdate);
监听 Sketch 微件上的
create
事件。创建新图形时,从selectedGraphics
数组中获取最后一个图形,并从graphicsLayer
中移除该图形,以便在view
中一次仅显示两个图形。调用onGraphicUpdate
函数,确定几何之间的空间关系。jssketch.on(["update", "undo", "redo"], onGraphicUpdate); sketch.on("create", (event) => { if (event.state === "start") { const arrVal = selectedGraphics.pop(); graphicsLayer.remove(arrVal); } if (event.state === "complete") { selectedGraphics.unshift(event.graphic); onGraphicUpdate(); } })
when
加载应用程序时,可调用onGraphicUpdate
来计算空间关系。使用草绘微件的update
方法选择折线图形,以便用户知道他们可以移动该图形。jssketch.on("create", (event) => { if (event.state === "start") { const arrVal = selectedGraphics.pop(); graphicsLayer.remove(arrVal); } if (event.state === "complete") { selectedGraphics.unshift(event.graphic); onGraphicUpdate(); } }) view.when(() => { sketch.update(polylineGraphic).then(onGraphicUpdate) });
运行应用程序
在 CodePen 中,运行代码,显示地图。
地图加载并显示线和面图形。同时在右下角,会显示图形之间的空间关系。移动图形时空间关系会随之变化。还可以进一步使用 Sketch 微件创建新图形,探索不同几何类型之间的空间关系。
下一步是什么?
要了解如何使用其他API 功能,请参阅以下教程: