使用turf.js进行最小外接矩形计算

487 阅读1分钟

1、思路

  • 1.计算图形中心点和凸多边形
  • 2.计算凸多边形每条边的倾斜角,并旋转凸多边形
  • 3.计算旋转后的多变形的外包矩形并比较面积,获取面积最小的外包矩形
  • 4.将最小外包矩形逆旋转对应角度

2.效果

image.png

3. 代码

/* eslint-disable no-undef */
// eslint-disable-next-line no-undef
window.CESIUM_BASE_URL = window.CESIUM_BASE_URL
  ? window.CESIUM_BASE_URL
  : "./CesiumUnminified/";

import * as Cesium from "./CesiumUnminified/index.js";


const viewer = new Cesium.Viewer('cesiumContainer', {
  baseLayer: Cesium.ImageryLayer.fromProviderAsync(
    Cesium.ArcGisMapServerImageryProvider.fromBasemapType(
      Cesium.ArcGisBaseMapType.SATELLITE
    )
  ),
})

const line = turf.lineString([
  [104.99467, 30.071677],
  [107.13797, 36.550462],
  [112.607082, 34.991467],
  [110.607082, 33.991467]
]);


viewer.dataSources.add(Cesium.GeoJsonDataSource.load(line, {
  stroke: Cesium.Color.HOTPINK,
  fill: Cesium.Color.PINK,
  strokeWidth: 3,
  markerSymbol: '?'
}));

//计算中心点
const center = turf.center(line);
const options = { pivot: center };
//生成凸多边形
const hull = turf.convex(line);
let minArea = 10000000000000000000
let minBBoxAngle = 0
let minBBox = null
const coordinates = hull.geometry.coordinates[0]
for (let i = 0; i < coordinates.length - 1; i++) {
  const point1 = turf.point(coordinates[i]);
  const point2 = turf.point(coordinates[i + 1]);




  const theta = turf.bearing(point1, point2);

  //旋转

  const rotatedPoly = turf.transformRotate(hull, theta, options);
  //计算面积
  const rotatebbox = turf.bbox(rotatedPoly);

  const rotatebboxBboxPolygon = turf.bboxPolygon(rotatebbox);

  const area = turf.area(rotatebboxBboxPolygon);

  if (area < minArea) {
    minArea=area
    minBBox = rotatebboxBboxPolygon
    minBBoxAngle = theta
  }


}
//将最小bbox旋转回去
const inverseRotatedPoly = turf.transformRotate(minBBox, -minBBoxAngle, options);
viewer.dataSources.add(Cesium.GeoJsonDataSource.load(inverseRotatedPoly, {
  stroke: Cesium.Color.RED,
  fill: Cesium.Color.YELLOW,
  strokeWidth: 3,
  markerSymbol: '?'
}));