基於百度地圖的區域重疊判斷


原文鏈接: Fyerl's Blog

前些日的一個小需求:
用戶在后台划不規則區域,區域之間不能重疊,如圖
圖片描述

判斷分兩步:
1、判斷多變形是否有相交線段,無則進行第二步判斷(公式)
2、判斷多變形之間是否存在頂點與多邊形的包含關系(BMapLib.GeoUtils.isPointInPolygon)

代碼如下:

/**
 * 點: { lat: xxx, lng: xxx }
 * 線: [{ lat: xxx, lng: xxx }, { lat: xxx, lng: xxx }]
 * 面: [{ lat: xxx, lng: xxx }, { lat: xxx, lng: xxx }, { lat: xxx, lng: xxx }...]
 * */
const { BMap, BMapLib } = window;

/**
 * 線段是否相交
 * seg: [{ lat: xxx, lng: xxx }, { lat: xxx, lng: xxx }]
 * */
function isSegmentsIntersectant(segA, segB) {
  const abc = (segA[0].lat - segB[0].lat) * (segA[1].lng - segB[0].lng) - (segA[0].lng - segB[0].lng) * (segA[1].lat - segB[0].lat);
  const abd = (segA[0].lat - segB[1].lat) * (segA[1].lng - segB[1].lng) - (segA[0].lng - segB[1].lng) * (segA[1].lat - segB[1].lat);
  if (abc * abd >= 0) {
    return false;
  }

  const cda = (segB[0].lat - segA[0].lat) * (segB[1].lng - segA[0].lng) - (segB[0].lng - segA[0].lng) * (segB[1].lat - segA[0].lat);
  const cdb = cda + abc - abd;
  return !(cda * cdb >= 0);
}

/**
 * 判斷兩多邊形邊界是否相交
 */
function isPolygonsIntersectant(plyA, plyB) {
  for (let i = 0, il = plyA.length; i < il; i++) {
    for (let j = 0, jl = plyB.length; j < jl; j++) {
      const segA = [plyA[i], plyA[i === il - 1 ? 0 : i + 1]];
      const segB = [plyB[j], plyB[j === jl - 1 ? 0 : j + 1]];
      if (isSegmentsIntersectant(segA, segB)) {
        return true;
      }
    }
  }
  return false;
}

/**
 * 判斷兩多變形是否存在點與區域的包含關系(A的點在B的區域內或B的點在A的區域內)
 */
function isPointInPolygonBidirectional(plyA, plyB) {
  const [pA, pB] = [[], []];
  plyA.forEach((item) => {
    pA.push(new BMap.Point(item.lng, item.lat));
  });

  plyB.forEach((item) => {
    pB.push(new BMap.Point(item.lng, item.lat));
  });


  let [a, b] = [false, false];
  a = pA.some(item => BMapLib.GeoUtils.isPointInPolygon(item, new BMap.Polygon(pB)));
  if (!a) {
    b = pB.some(item => BMapLib.GeoUtils.isPointInPolygon(item, new BMap.Polygon(pA)));
  }

  return a || b;
}


/**
 * 判斷多邊形是否重疊
 * */
export function isPolygonsOverlap(plyA, plyB) {
  return isPolygonsIntersectant(plyA, plyB) || isPointInPolygonBidirectional(plyA, plyB);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM