高德多边形相关 API 使用

591 阅读3分钟

多边形编辑器

多边形编辑工具 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>) =&gt;</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> =&gt;</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> &amp;&amp; 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>) =&gt;</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 &gt; <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>