多边形编辑器
多边形编辑工具 AMap.PolygonEditor , 语法:new AMap.PolygonEditor(map, polygon?, opts?)。
opts 参数如下:
| 名称 | 描述 |
|---|---|
| opts.createOptions | 新创建的多边形样式 |
| opts.editOptions | 编辑多边形样式 |
| opts.controlPoint | 顶点样式 |
| opts.midControlPoint | 中间点样式 |
修改多边形编辑器样式
如果想实现下图的多边形编辑器样式,可以通过修改第三个参数 opts 属性来实现。
代码如下:
// tips: 第二个参数为 null,是因为在其他地方使用 addAdsorbPolygons 添加了多边形
const polyEditor = new AMap.PolygonEditor(map, null, {
// 编辑时,设置背景色与边框颜色为绿色
editOptions: {
fillColor: "green",
strokeColor: "green",
strokeWeight: 4,
},
// 设置路径顶点颜色为红色
controlPoint: {
fillColor: "red",
strokeColor: "red",
},
// 设置中间点颜色为黄色
midControlPoint: {
fillColor: "yellow",
strokeColor: "yellow",
}
})设置 opts.createOptions 颜色,画的过程中没有生效,后续待补充。
可以修改的 style 样式有哪些?
高德 API 里没有详细说明可以修改的编辑器 style 样式。尝试通过 add 事件打印的 event.target 看下当前编辑的多边形。
// polyEditor 是上文的 polyEditor, 没有设置 createOptions
polyEditor.on('add', event => {
console.log('polyEditor add', event.target)
})输出结果的 _opts 属性如下图,因为未设置 createOptions ,此处打印的是默认的 createOptions,理论情况下这些属性就是可以修改的 style 样式。其他属性也可以通过此方法查看。
多边形关系判断
判断多边形关系使用的是 turf 地理空间分析库,其包含各种地图算法。
前提:使用高德 api 画多边形。判断一个多边形与其他多边形关系:
let path1 = polygonPath.map(({ lng, lat }) => [lng, lat])
path1.push(path1[0]) // turf.js 的多边形路径必须首尾相同
polygonList.forEach(itm => {
const { path: computePath, areaId: computeAreaId } = itm
if (polygonAreaId === computeAreaId) {
return
}
let path2 = computePath
path2.push(path2[0]) // turf.js 的多边形路径必须首尾相同
const curPolygon = turf.polygon([path1])
const computePolygon = turf.polygon([path2])
// 是否相等
const booleanEqual = turfBooleanEqual(computePolygon, curPolygon)
if (booleanEqual) {
equalPolygons.push(itm)
return
}
// computePolygon 是否包含 curPolygon
const booleanContains1 = turfBooleanContains(computePolygon, curPolygon)
if (booleanContains1) {
parentPolygons.push(itm)
return
}
// curPolygon 是否包含 computePolygon
const booleanContains2 = turfBooleanContains(curPolygon, computePolygon)
if (booleanContains2) {
innerPolygons.push(itm)
return
}
// 是否重叠
const booleanOverlap = turfBooleanOverlap(curPolygon, computePolygon)
if (booleanOverlap) {
const result = turfIntersect(curPolygon, computePolygon)
const { type, coordinates = [] } = result?.geometry || {}
console.log('判断关系 - 重叠结果', result)
if (type === 'Polygon' && coordinates?.[0]) {
const iPath = coordinates[0].map(([lng, lat]) => [
Number(lng.toFixed(6)),
Number(lat.toFixed(6)),
])
const iPolygon = turf.polygon([iPath])
const area = turfArea(iPolygon)
console.log('相交区域面积', area)
if (area > 0) {
intersectPolygons.push(itm)
}
} else if (result) {
intersectPolygons.push(itm)
}
}
})
return { equalPolygons, parentPolygons, innerPolygons, intersectPolygons }
}" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
</div><pre class="js hljs language-javascript"><span class="hljs-comment">/**
* 判断一个多边形与其他多边形关系
* <span class="hljs-doctag">@param</span> {<span class="hljs-type">object</span>} polygon 当前多边形
* <span class="hljs-doctag">@param</span> {<span class="hljs-type">array</span>} polygonList 对比多边形数组
* <span class="hljs-doctag">@returns</span> {<span class="hljs-type">object</span>}
* <span class="hljs-doctag">@param</span> equalPolygons 与当前多边形相等的多边形
* <span class="hljs-doctag">@param</span> parentPolygons 当前多边形在某个多边形内部(父多边形)
* <span class="hljs-doctag">@param</span> innerPolygons 当前多边形包含的其他多边形(子多边形)
* <span class="hljs-doctag">@param</span> intersectPolygons 与当前多边形相交的多边形
*/</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">comparePolygonRelations</span>(<span class="hljs-params">polygon, polygonList</span>) {
<span class="hljs-keyword">const</span> { <span class="hljs-attr">path</span>: polygonPath, <span class="hljs-attr">areaId</span>: polygonAreaId } = polygon
<span class="hljs-keyword">let</span> equalPolygons = []
<span class="hljs-keyword">let</span> parentPolygons = []
<span class="hljs-keyword">let</span> innerPolygons = []
<span class="hljs-keyword">let</span> intersectPolygons = []
<span class="hljs-keyword">let</span> path1 = polygonPath.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">{ lng, lat }</span>) =></span> [lng, lat])
path1.<span class="hljs-title function_">push</span>(path1[<span class="hljs-number">0</span>]) <span class="hljs-comment">// turf.js 的多边形路径必须首尾相同</span>
polygonList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">itm</span> =></span> {
<span class="hljs-keyword">const</span> { <span class="hljs-attr">path</span>: computePath, <span class="hljs-attr">areaId</span>: computeAreaId } = itm
<span class="hljs-keyword">if</span> (polygonAreaId === computeAreaId) {
<span class="hljs-keyword">return</span>
}
<span class="hljs-keyword">let</span> path2 = computePath
path2.<span class="hljs-title function_">push</span>(path2[<span class="hljs-number">0</span>]) <span class="hljs-comment">// turf.js 的多边形路径必须首尾相同</span>
<span class="hljs-keyword">const</span> curPolygon = turf.<span class="hljs-title function_">polygon</span>([path1])
<span class="hljs-keyword">const</span> computePolygon = turf.<span class="hljs-title function_">polygon</span>([path2])
<span class="hljs-comment">// 是否相等</span>
<span class="hljs-keyword">const</span> booleanEqual = <span class="hljs-title function_">turfBooleanEqual</span>(computePolygon, curPolygon)
<span class="hljs-keyword">if</span> (booleanEqual) {
equalPolygons.<span class="hljs-title function_">push</span>(itm)
<span class="hljs-keyword">return</span>
}
<span class="hljs-comment">// computePolygon 是否包含 curPolygon</span>
<span class="hljs-keyword">const</span> booleanContains1 = <span class="hljs-title function_">turfBooleanContains</span>(computePolygon, curPolygon)
<span class="hljs-keyword">if</span> (booleanContains1) {
parentPolygons.<span class="hljs-title function_">push</span>(itm)
<span class="hljs-keyword">return</span>
}
<span class="hljs-comment">// curPolygon 是否包含 computePolygon</span>
<span class="hljs-keyword">const</span> booleanContains2 = <span class="hljs-title function_">turfBooleanContains</span>(curPolygon, computePolygon)
<span class="hljs-keyword">if</span> (booleanContains2) {
innerPolygons.<span class="hljs-title function_">push</span>(itm)
<span class="hljs-keyword">return</span>
}
<span class="hljs-comment">// 是否重叠</span>
<span class="hljs-keyword">const</span> booleanOverlap = <span class="hljs-title function_">turfBooleanOverlap</span>(curPolygon, computePolygon)
<span class="hljs-keyword">if</span> (booleanOverlap) {
<span class="hljs-keyword">const</span> result = <span class="hljs-title function_">turfIntersect</span>(curPolygon, computePolygon)
<span class="hljs-keyword">const</span> { type, coordinates = [] } = result?.<span class="hljs-property">geometry</span> || {}
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'判断关系 - 重叠结果'</span>, result)
<span class="hljs-keyword">if</span> (type === <span class="hljs-string">'Polygon'</span> && coordinates?.[<span class="hljs-number">0</span>]) {
<span class="hljs-keyword">const</span> iPath = coordinates[<span class="hljs-number">0</span>].<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">[lng, lat]</span>) =></span> [
<span class="hljs-title class_">Number</span>(lng.<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">6</span>)),
<span class="hljs-title class_">Number</span>(lat.<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">6</span>)),
])
<span class="hljs-keyword">const</span> iPolygon = turf.<span class="hljs-title function_">polygon</span>([iPath])
<span class="hljs-keyword">const</span> area = <span class="hljs-title function_">turfArea</span>(iPolygon)
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'相交区域面积'</span>, area)
<span class="hljs-keyword">if</span> (area > <span class="hljs-number">0</span>) {
intersectPolygons.<span class="hljs-title function_">push</span>(itm)
}
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (result) {
intersectPolygons.<span class="hljs-title function_">push</span>(itm)
}
}
})
<span class="hljs-keyword">return</span> { equalPolygons, parentPolygons, innerPolygons, intersectPolygons }
}</pre>