fix(foundry): isolate HGeoZone projection faults
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Canonicalize a provider-neutral GeoJSON linear ring before it reaches a
|
||||
* Cesium geometry worker. GeoJSON closes a ring by repeating its first
|
||||
* coordinate, while GroundPolylineGeometry with `loop: true` expects an open
|
||||
* sequence. Some source snapshots contain both adjacent duplicates and more
|
||||
* than one closing coordinate; forwarding either shape can create a
|
||||
* zero-length segment and stop Cesium's render loop.
|
||||
*
|
||||
* Invalid coordinates invalidate the complete ring. Silently retaining a
|
||||
* partial polygon would display a boundary the provider never published.
|
||||
*
|
||||
* @param {Array<[number, number]>} ring
|
||||
* @returns {Array<[number, number]>}
|
||||
*/
|
||||
export function normalizeHGeoZoneRing(ring) {
|
||||
if (!Array.isArray(ring)) return [];
|
||||
/** @type {Array<[number, number]>} */
|
||||
const normalized = [];
|
||||
for (const coordinate of ring) {
|
||||
if (
|
||||
!Array.isArray(coordinate)
|
||||
|| coordinate.length < 2
|
||||
|| !Number.isFinite(coordinate[0])
|
||||
|| !Number.isFinite(coordinate[1])
|
||||
|| coordinate[0] < -180
|
||||
|| coordinate[0] > 180
|
||||
|| coordinate[1] < -90
|
||||
|| coordinate[1] > 90
|
||||
) return [];
|
||||
const next = /** @type {[number, number]} */ ([coordinate[0], coordinate[1]]);
|
||||
if (!sameCoordinate(normalized.at(-1), next)) normalized.push(next);
|
||||
}
|
||||
|
||||
while (normalized.length > 1 && sameCoordinate(normalized[0], normalized.at(-1))) {
|
||||
normalized.pop();
|
||||
}
|
||||
const distinct = new Set(normalized.map(([longitude, latitude]) => `${longitude}:${latitude}`));
|
||||
return distinct.size >= 3 ? normalized : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[number, number] | undefined} left
|
||||
* @param {[number, number] | undefined} right
|
||||
*/
|
||||
function sameCoordinate(left, right) {
|
||||
return Boolean(left && right && left[0] === right[0] && left[1] === right[1]);
|
||||
}
|
||||
Reference in New Issue
Block a user