Skip to content

Commit 70829ee

Browse files
committed
Update cell.test.ts
- Test failed for resolution 1: caused by a5cellContainsPoint - Test failed for resolution 31: caused by cellToBoundary for tiny geometry
1 parent 388c010 commit 70829ee

1 file changed

Lines changed: 122 additions & 5 deletions

File tree

tests/cell.test.ts

Lines changed: 122 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,123 @@
1-
import { describe, it, expect } from 'vitest'
2-
import { cellToBoundary, cellToLonLat, lonLatToCell } from 'a5/core/cell'
1+
import { describe, it, expect } from 'vitest';
2+
import type {Degrees,LonLat } from "a5/core/coordinate-systems";
3+
import { cellToBoundary, cellToLonLat, lonLatToCell,a5cellContainsPoint } from 'a5/core/cell'
4+
import { deserialize, MAX_RESOLUTION } from 'a5/core/serialization';
35

4-
describe('cell', () => {
5-
it('passes', () => {})
6-
})
6+
interface GeoJSONFeature {
7+
type: 'Feature';
8+
properties: {
9+
resolution: number;
10+
};
11+
geometry: {
12+
type: 'Polygon';
13+
coordinates: number[][][];
14+
};
15+
}
16+
17+
interface GeoJSONFeatureCollection {
18+
type: 'FeatureCollection';
19+
features: GeoJSONFeature[];
20+
}
21+
22+
function boundaryToGeoJSON(boundary: LonLat[], resolution: number): GeoJSONFeatureCollection {
23+
// Create coordinates list with first point appended at the end to close the polygon
24+
const coordinates = boundary.map(([lon, lat]) => [lon, lat]);
25+
if (coordinates.length > 0) {
26+
coordinates.push(coordinates[0]); // Close the polygon
27+
}
28+
29+
// Create a polygon feature
30+
const feature: GeoJSONFeature = {
31+
type: 'Feature',
32+
properties: {
33+
resolution
34+
},
35+
geometry: {
36+
type: 'Polygon',
37+
coordinates: [coordinates] // Wrap in list as per GeoJSON spec
38+
}
39+
};
40+
41+
// Create a feature collection
42+
const featureCollection: GeoJSONFeatureCollection = {
43+
type: 'FeatureCollection',
44+
features: [feature]
45+
};
46+
47+
return featureCollection;
48+
}
49+
50+
describe('Cell Boundary Tests', () => {
51+
it('should contain point and have valid boundaries for all resolutions', () => {
52+
// Test coordinates
53+
const testLonlat = [106.706360 as Degrees, 10.775305 as Degrees] as LonLat;
54+
55+
// Dictionary to store failures for each resolution
56+
const failures: Record<number, string[]> = {};
57+
// Test resolutions from 0 to MAX_RESOLUTION
58+
for (let resolution = 1; resolution <= MAX_RESOLUTION; resolution++) {
59+
const resolutionFailures: string[] = [];
60+
61+
try {
62+
// Get cell ID for the coordinates
63+
const cellId = lonLatToCell(testLonlat, resolution);
64+
65+
// Get cell boundary
66+
const boundary = cellToBoundary(cellId);
67+
68+
// Convert boundary to GeoJSON and print it
69+
const geojson = boundaryToGeoJSON(boundary, resolution);
70+
console.log(`\nResolution ${resolution} GeoJSON:\n`, JSON.stringify(geojson));
71+
72+
// Verify the original point is contained within the cell
73+
const cell = deserialize(cellId);
74+
if (!a5cellContainsPoint(cell, testLonlat)) {
75+
resolutionFailures.push(`Cell does not contain the original point ${testLonlat}`);
76+
// Add cell center for reference
77+
const center = cellToLonLat(cellId);
78+
resolutionFailures.push(`Cell center is at ${center}`);
79+
}
80+
81+
// Verify boundary points are valid coordinates
82+
boundary.forEach((point, i) => {
83+
if (!Array.isArray(point)) {
84+
resolutionFailures.push(`Boundary point ${i} is not an array, got ${typeof point}`);
85+
} else if (point.length !== 2) {
86+
resolutionFailures.push(`Boundary point ${i} should have 2 coordinates, got ${point.length}`);
87+
} else {
88+
const [lon, lat] = point;
89+
if (lon < -180 || lon > 180) {
90+
resolutionFailures.push(`Boundary point ${i} has invalid longitude: ${lon}`);
91+
}
92+
if (lat < -90 || lat > 90) {
93+
resolutionFailures.push(`Boundary point ${i} has invalid latitude: ${lat}`);
94+
}
95+
}
96+
});
97+
98+
} catch (e) {
99+
resolutionFailures.push(`Unexpected error: ${e instanceof Error ? e.message : String(e)}`);
100+
if (e instanceof Error && e.stack) {
101+
resolutionFailures.push(`Traceback: ${e.stack}`);
102+
}
103+
}
104+
105+
// Store failures for this resolution if any occurred
106+
if (resolutionFailures.length > 0) {
107+
failures[resolution] = resolutionFailures;
108+
}
109+
}
110+
111+
// Report all failures
112+
if (Object.keys(failures).length > 0) {
113+
let failureMessage = '\nFailures by resolution:\n';
114+
for (const [resolution, resolutionFailures] of Object.entries(failures)) {
115+
failureMessage += `\nResolution ${resolution}:\n`;
116+
for (const failure of resolutionFailures) {
117+
failureMessage += ` - ${failure}\n`;
118+
}
119+
}
120+
throw new Error(failureMessage);
121+
}
122+
});
123+
});

0 commit comments

Comments
 (0)