Merge commit '04d530d692e91c917e9b2626333619aa8cc374e2' into label
This commit is contained in:
69
components/label/utils/geometry/areaFilter.ts
Normal file
69
components/label/utils/geometry/areaFilter.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import {
|
||||
normalizeMultiPolygon,
|
||||
type NormalizedMultiPolygon,
|
||||
type NormalizedRing,
|
||||
} from "./booleanAdapter"
|
||||
|
||||
export interface AreaFilterResult {
|
||||
geometry: NormalizedMultiPolygon
|
||||
removedOuterCount: number
|
||||
removedHoleCount: number
|
||||
}
|
||||
|
||||
const getRingArea = (ring: NormalizedRing) => {
|
||||
let area = 0
|
||||
for (let index = 0; index < ring.length - 1; index += 1) {
|
||||
const [x1, y1] = ring[index]
|
||||
const [x2, y2] = ring[index + 1]
|
||||
area += x1 * y2 - x2 * y1
|
||||
}
|
||||
return Math.abs(area / 2)
|
||||
}
|
||||
|
||||
export const filterMultiPolygonByAreaThreshold = ({
|
||||
geometry,
|
||||
minArea,
|
||||
}: {
|
||||
geometry: NormalizedMultiPolygon | null | undefined
|
||||
minArea: number
|
||||
}): AreaFilterResult => {
|
||||
const normalizedGeometry = normalizeMultiPolygon(geometry)
|
||||
const normalizedMinArea = Math.max(0, Number(minArea) || 0)
|
||||
|
||||
if (!normalizedMinArea) {
|
||||
return {
|
||||
geometry: normalizedGeometry,
|
||||
removedOuterCount: 0,
|
||||
removedHoleCount: 0,
|
||||
}
|
||||
}
|
||||
|
||||
let removedOuterCount = 0
|
||||
let removedHoleCount = 0
|
||||
|
||||
const nextGeometry = normalizedGeometry.flatMap((polygon) => {
|
||||
const [outerRing, ...holeRings] = polygon
|
||||
if (!outerRing) return []
|
||||
|
||||
if (getRingArea(outerRing) < normalizedMinArea) {
|
||||
removedOuterCount += 1
|
||||
return []
|
||||
}
|
||||
|
||||
const nextHoleRings = holeRings.filter((ring) => {
|
||||
const keep = getRingArea(ring) >= normalizedMinArea
|
||||
if (!keep) {
|
||||
removedHoleCount += 1
|
||||
}
|
||||
return keep
|
||||
})
|
||||
|
||||
return [[outerRing, ...nextHoleRings]]
|
||||
})
|
||||
|
||||
return {
|
||||
geometry: nextGeometry,
|
||||
removedOuterCount,
|
||||
removedHoleCount,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user