|
| 1 | +import type * as geojson from 'geojson' |
| 2 | +import { Rect } from '../s2/Rect' |
| 3 | +import { Interval as R1Interval } from '../r1/Interval' |
| 4 | +import { Interval as S1Interval } from '../s1/Interval' |
| 5 | +import { Point } from '../s2/Point' |
| 6 | +import { Loop } from '../s2/Loop' |
| 7 | +import { Polygon } from '../s2/Polygon' |
| 8 | +import * as polygon from './polygon' |
| 9 | +import { DEGREE } from '../s1/angle_constants' |
| 10 | + |
| 11 | +/** |
| 12 | + * Returns a geojson Polygon geometry given an s2 Rect. |
| 13 | + * @category Constructors |
| 14 | + */ |
| 15 | +export const marshal = (rect: Rect): geojson.Polygon => { |
| 16 | + const loop = new Loop(Array.from({ length: 4 }, (_, i) => Point.fromLatLng(rect.vertex(i)))) |
| 17 | + return polygon.marshal(Polygon.fromOrientedLoops([loop])) |
| 18 | +} |
| 19 | + |
| 20 | +/** |
| 21 | + * Constructs an s2 Rect given a geojson Polygon geometry. |
| 22 | + * @category Constructors |
| 23 | + */ |
| 24 | +export const unmarshal = (geometry: geojson.Polygon): Rect => { |
| 25 | + const ring = geometry.coordinates[0] |
| 26 | + const lngLo = Math.min(ring[0][0], ring[2][0]) |
| 27 | + const lngHi = Math.max(ring[0][0], ring[2][0]) |
| 28 | + const latLo = Math.min(ring[0][1], ring[2][1]) |
| 29 | + const latHi = Math.max(ring[0][1], ring[2][1]) |
| 30 | + |
| 31 | + return new Rect( |
| 32 | + new R1Interval(latLo * DEGREE, latHi * DEGREE), |
| 33 | + S1Interval.fromEndpoints(lngLo * DEGREE, lngHi * DEGREE) |
| 34 | + ) |
| 35 | +} |
| 36 | + |
| 37 | +/** |
| 38 | + * Returns true iff the geojson Polygon represents a valid Rect. |
| 39 | + * @category Constructors |
| 40 | + */ |
| 41 | +export const valid = (geometry: geojson.Polygon): boolean => { |
| 42 | + if (geometry?.type !== 'Polygon') return false |
| 43 | + if (geometry?.coordinates.length !== 1) return false |
| 44 | + const ring = geometry.coordinates[0] |
| 45 | + if (ring.length !== 5) return false |
| 46 | + if (!pointsEqual(ring[0], ring[4])) return false |
| 47 | + if (!lngEqual(ring[0], ring[3])) return false |
| 48 | + if (!lngEqual(ring[1], ring[2])) return false |
| 49 | + if (!latEqual(ring[0], ring[1])) return false |
| 50 | + if (!latEqual(ring[2], ring[3])) return false |
| 51 | + return true |
| 52 | +} |
| 53 | + |
| 54 | +const lngEqual = (a: geojson.Position, b: geojson.Position) => a[0] === b[0] |
| 55 | +const latEqual = (a: geojson.Position, b: geojson.Position) => a[1] === b[1] |
| 56 | +const pointsEqual = (a: geojson.Position, b: geojson.Position) => lngEqual(a, b) && latEqual(a, b) |
0 commit comments