判断坐标点是否处于某个范围内(射线法)

判断坐标点是否处于某个范围内(射线法)

Vue

/**
 * 判断点是否多边形内
 * @param {Point} point 点对象
 * @param {Polyline} polygon 多边形对象
 * @returns {Boolean} 点在多边形内返回true,否则返回false
 */
export function isPointInPolygon(point, polygon) {
  // 检查类型
  // eslint-disable-next-line no-undef
  if (!(point instanceof BMap.Point) ||
    // eslint-disable-next-line no-undef
    !(polygon instanceof BMap.Polygon)) {
    return false
  }

  // 首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false
  const polygonBounds = polygon.getBounds()
  if (!isPointInRect(point, polygonBounds)) {
    return false
  }

  const pts = polygon.getPath()// 获取多边形点

  // 下述代码来源:http:// paulbourke.net/geometry/insidepoly/,进行了部分修改
  // 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
  // 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。

  const N = pts.length
  const boundOrVertex = true // 如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
  let intersectCount = 0// cross points count of x
  const precision = 2e-10 // 浮点类型计算时候与0比较时候的容差
  let p1, p2// neighbour bound vertices
  const p = point // 测试点

  p1 = pts[0]// left vertex
  for (let i = 1; i <= N; ++i) {
    // check all rays
    if (p.equals(p1)) {
      return boundOrVertex// p is an vertex
    }

    p2 = pts[i % N]
    // right vertex
    if (p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)) {
      // ray is outside of our interests
      p1 = p2
      continue
      // next ray left point
    }

    if (p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)) {
      // ray is crossing over by the algorithm (common part of)
      if (p.lng <= Math.max(p1.lng, p2.lng)) {
        // x is before of ray
        if (p1.lat === p2.lat && p.lng >= Math.min(p1.lng, p2.lng)) {
          // overlies on a horizontal ray
          return boundOrVertex
        }

        if (p1.lng === p2.lng) {
          // ray is vertical
          if (p1.lng === p.lng) {
            // overlies on a vertical ray
            return boundOrVertex
          } else {
            // before ray
            ++intersectCount
          }
        } else {
          // cross point on the left side
          const xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng
          // cross point of lng
          if (Math.abs(p.lng - xinters) < precision) {
            // overlies on a ray
            return boundOrVertex
          }

          if (p.lng < xinters) {
            // before ray
            ++intersectCount
          }
        }
      }
    } else {
      // special case when ray is crossing through the vertex
      if (p.lat === p2.lat && p.lng <= p2.lng) {
        // p crossing over p2
        const p3 = pts[(i + 1) % N]
        //  next vertex
        if (p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)) {
          // p.lat lies between p1.lat & p3.lat
          ++intersectCount
        } else {
          intersectCount += 2
        }
      }
    }
    p1 = p2
    //  next ray left point
  }

  if (intersectCount % 2 === 0) {
    //  偶数在多边形外
    return false
  } else {
    //  奇数在多边形内
    return true
  }
}

/**
 * 判断点是否在矩形内
 * @param {Point} point 点对象
 * @param {Bounds} bounds 矩形边界对象
 * @returns {Boolean} 点在矩形内返回true,否则返回false
 */
export function isPointInRect(point, bounds) {
  // 检查类型是否正确
  // eslint-disable-next-line no-undef
  if (!(point instanceof BMap.Point) ||
    // eslint-disable-next-line no-undef
    !(bounds instanceof BMap.Bounds)) {
    return false
  }
  const sw = bounds.getSouthWest()
  // 西南脚点
  const ne = bounds.getNorthEast()
  // 东北脚点
  return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat)
}

测试

// 判断经纬度在那个网格内
gridRange() {
  noPageGridList().then(res => {
    res.data.data.forEach(result => {
      const pointArray = []
      JSON.parse(result.path).forEach(everyPoint => {
        // eslint-disable-next-line no-undef
        pointArray.push(new BMap.Point(everyPoint.lng, everyPoint.lat))
      })

      // eslint-disable-next-line no-undef
      const judgePolygon = new BMap.Polygon(pointArray)
      const jsonPoint = JSON.parse(this.temp.coordinates)

      // eslint-disable-next-line no-undef
      const site = new BMap.Point(jsonPoint.lng, jsonPoint.lat)
      const judgement = isPointInPolygon(site, judgePolygon)
      if (judgement) {
        this.organizationId = result.organizationId
        return
      }
    })
  })
}

Java

待完成

声明

代码资源来源于百度地图官方

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值