Skip to content

Commit

Permalink
feat: validate latitude and longitude (#16)
Browse files Browse the repository at this point in the history
It is now impossible to decode a position with an invalid
latitude or longitude.

There are two motivations for this change:

1. General correctness.

2. `@mapeo/mock-data` is currently generating invalid latitudes and
   longitudes because of the schema in this repo. That causes [some
   workarounds if you need valid coordinates][0], and I plan to add more
   tests that will require similar workarounds. I felt that fixing the
   problem here, at the source, was best.

[0]: https://github.com/digidem/comapeo-cloud/blob/d6ab53197ac3970ee8f287ddb30663a04c6449d1/test/add-alerts-endpoint.js#L240-L243
  • Loading branch information
EvanHahn authored Dec 9, 2024
1 parent 1eff27e commit eda2f94
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 15 deletions.
17 changes: 14 additions & 3 deletions json/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"type": "number"
}
"items": [
{
"type": "number",
"description": "longitude",
"minimum": -180,
"maximum": 180
},
{
"type": "number",
"description": "latitude",
"minimum": -90,
"maximum": 90
}
]
},
"linearRing": {
"title": "LinearRing",
Expand Down
15 changes: 15 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,22 @@ function validateRawCoords(rawCoords: number[]) {
if (rawCoords.length % 2 !== 0) {
throw new Error('`coordinates` must have an even number of elements')
}
for (let i = 0; i < rawCoords.length; i++) {
if (i % 2 === 0) {
validateLongitude(rawCoords[i])
} else {
validateLatitude(rawCoords[i])
}
}
}

const rangeValidator = (max: number) => (value: number) => {
if (Math.abs(value) > max) {
throw new Error(`Coordinate value must be between -${max} and ${max}`)
}
}
const validateLatitude = rangeValidator(90)
const validateLongitude = rangeValidator(180)

function validateLinearRing(ring: Position[]): asserts ring is LinearRing {
if (ring.length < 4) {
Expand Down
5 changes: 5 additions & 0 deletions test/fixture/bad-proto/bad-latitude.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "TYPE_POINT",
"coordinates": [123, 91],
"lengths": []
}
5 changes: 5 additions & 0 deletions test/fixture/bad-proto/bad-longitude.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "TYPE_POINT",
"coordinates": [181, 12],
"lengths": []
}
2 changes: 1 addition & 1 deletion test/fixture/bad-proto/bad-type.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "TYPE_UNSPECIFIED",
"coordinates": [100, 102],
"coordinates": [123, 45],
"lengths": []
}
2 changes: 1 addition & 1 deletion test/fixture/bad-proto/invalid-ring.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "TYPE_POLYGON",
"coordinates": [100, 101, 102, 103, 104, 105],
"coordinates": [1, 2, 3, 4, 5, 6],
"lengths": []
}
2 changes: 1 addition & 1 deletion test/fixture/bad-proto/missing-coordinates.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "TYPE_POLYGON",
"coordinates": [100, 101, 102, 103, 104, 105, 106, 107],
"coordinates": [0, 1, 2, 3, 4, 5, 6, 7],
"lengths": [5]
}
2 changes: 1 addition & 1 deletion test/fixture/bad-proto/odd-coordinates.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "TYPE_POINT",
"coordinates": [100, 101, 102],
"coordinates": [12, 34, 56],
"lengths": []
}
6 changes: 3 additions & 3 deletions test/fixture/good-geojson/multipolygon-single.geojson
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
[
[
[0, 0],
[100, 0],
[100, 100],
[0, 100],
[12, 0],
[123, 45],
[0, 12],
[0, 0]
]
]
Expand Down
10 changes: 5 additions & 5 deletions test/fixture/good-geojson/polygon-precision.geojson
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"type": "Polygon",
"coordinates": [
[
[5425435.733081569895148, 2012689.63544030720368],
[5425333.066045090556145, 2012658.8061882276088],
[5425324.357915714383125, 2012693.518385621719062],
[5425426.5193927353248, 2012720.238697179593146],
[5425435.733081569895148, 2012689.63544030720368]
[179.733081569895148, 89.63544030720368],
[179.066045090556145, 89.8061882276088],
[179.357915714383125, 89.518385621719062],
[179.5193927353248, 89.238697179593146],
[179.733081569895148, 89.63544030720368]
]
]
}

0 comments on commit eda2f94

Please sign in to comment.