You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Turf.js如何计算考虑多边形旋转的最小外接矩形bbox

Turf.js 实现旋转贴合的最小矩形边界方案

你之前使用的turf.bboxPolygon、turf.envelope接口生成的都是轴对齐包围盒(AABB),矩形边强制与经纬度坐标轴平行,遇到整体存在旋转角度的多边形组时,必然会在两侧产生冗余空白,无法满足贴合最外侧点位的需求。你需要的是可随要素旋转的最小有向包围盒(OBB,所有内角为90度、包裹所有要素的面积最小矩形),Turf.js没有提供直接生成该结果的单API,但可以通过现有接口组合实现,计算逻辑如下:

  • 第一步:将所有输入多边形合并为要素集,调用turf.convex()计算所有要素的整体凸包。最小外接矩形必然与凸包的某条边共边,先算凸包可以大幅减少后续遍历的计算量。
  • 第二步:遍历凸包的每一条边,计算边对应的方向角,也就是将该边旋转至与X轴平行需要的角度。
  • 第三步:对每个遍历到的角度,将凸包反向旋转使当前边与X轴对齐,调用turf.bbox()计算旋转后凸包的轴对齐包围盒,记录该包围盒的面积、对应旋转角度、包围盒坐标参数。
  • 第四步:所有边遍历完成后,筛选出面积最小的一组包围盒参数,将对应的轴对齐矩形按记录的角度正向旋转回原坐标系,得到的就是完全贴合所有要素最外侧点位的最小矩形。

核心实现代码

import * as turf from '@turf/turf'

/**
 * 计算要素集的最小旋转外接矩形(内角均为90度)
 * @param {GeoJSON.Feature[]} features 输入多边形要素数组
 * @returns {GeoJSON.Feature<Polygon>} 最小外接矩形要素
 */
function getMinRotatedBoundingRect(features) {
  const featureCollection = turf.featureCollection(features)
  const convexHull = turf.convex(featureCollection)
  if (!convexHull) throw new Error('无法为输入要素生成凸包,请检查要素有效性')

  const hullCoordinates = convexHull.geometry.coordinates[0]
  let minArea = Number.POSITIVE_INFINITY
  let optimalBbox = null
  let optimalRotateAngle = 0

  // 遍历凸包所有边找最小面积对应的旋转角
  for (let i = 0; i < hullCoordinates.length - 1; i++) {
    const startPoint = hullCoordinates[i]
    const endPoint = hullCoordinates[i + 1]
    // 计算当前边的方向角
    const angle = Math.atan2(
      endPoint[1] - startPoint[1],
      endPoint[0] - startPoint[0]
    ) * 180 / Math.PI
    // 旋转凸包使当前边与X轴平行
    const rotatedHull = turf.transformRotate(convexHull, -angle, { pivot: startPoint })
    // 计算旋转后的轴对齐包围盒与面积
    const currentBbox = turf.bbox(rotatedHull)
    const currentArea = (currentBbox[2] - currentBbox[0]) * (currentBbox[3] - currentBbox[1])
    // 更新最小面积记录
    if (currentArea < minArea) {
      minArea = currentArea
      optimalBbox = currentBbox
      optimalRotateAngle = angle
    }
  }

  // 将最优轴对齐包围盒旋转回原角度
  const axisAlignedRect = turf.bboxPolygon(optimalBbox)
  return turf.transformRotate(axisAlignedRect, optimalRotateAngle)
}

注意事项

  • 上述代码要求输入坐标为平面投影坐标(如UTM投影、高斯克吕格投影,单位为米),如果直接传入WGS84经纬度坐标,由于经纬度单位“度”在不同纬度对应的实际距离不一致,计算出的角度、面积会存在偏差,仅适合小范围、中低纬度场景近似使用,大范围或高纬度场景需要先完成坐标投影转换再计算。
  • 该算法计算出的矩形会自动贴合要素最外侧的凸顶点,刚好满足你提到的贴住多边形101最顶部点位、多边形202最底部点位的需求,不会产生多余空白。

效果参考

bbox生成效果对比图

内容的提问来源于stack exchange,提问作者myoda999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:18:25