geohash-kit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +21 -0
- package/README.md +250 -0
- package/dist/core.d.ts +39 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +213 -0
- package/dist/core.js.map +1 -0
- package/dist/coverage.d.ts +86 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +555 -0
- package/dist/coverage.js.map +1 -0
- package/dist/geojson.d.ts +13 -0
- package/dist/geojson.d.ts.map +1 -0
- package/dist/geojson.js +3 -0
- package/dist/geojson.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/nostr.d.ts +31 -0
- package/dist/nostr.d.ts.map +1 -0
- package/dist/nostr.js +87 -0
- package/dist/nostr.js.map +1 -0
- package/llms-full.txt +454 -0
- package/llms.txt +74 -0
- package/package.json +66 -0
package/dist/coverage.js
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
// geohash-kit/coverage — polygon-to-geohash coverage, GeoJSON, convex hull
|
|
2
|
+
import { bounds as geohashBounds, children as geohashChildren } from './core.js';
|
|
3
|
+
// --- Validation ---
|
|
4
|
+
const BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz';
|
|
5
|
+
function validateGeohash(hash) {
|
|
6
|
+
for (const ch of hash) {
|
|
7
|
+
if (!BASE32.includes(ch)) {
|
|
8
|
+
throw new TypeError(`Invalid geohash character: '${ch}' in "${hash}"`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
// --- Point-in-polygon (ray-casting) ---
|
|
13
|
+
/**
|
|
14
|
+
* Ray-casting algorithm: test whether a point [x, y] lies inside a polygon.
|
|
15
|
+
* Polygon is an array of [x, y] vertices (closed automatically).
|
|
16
|
+
*/
|
|
17
|
+
export function pointInPolygon(point, polygon) {
|
|
18
|
+
const [px, py] = point;
|
|
19
|
+
let inside = false;
|
|
20
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
21
|
+
const [xi, yi] = polygon[i];
|
|
22
|
+
const [xj, yj] = polygon[j];
|
|
23
|
+
if ((yi > py) !== (yj > py) && px < ((xj - xi) * (py - yi)) / (yj - yi) + xi) {
|
|
24
|
+
inside = !inside;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return inside;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Test whether all four corners of bounds lie inside the polygon.
|
|
31
|
+
*/
|
|
32
|
+
export function boundsFullyInsidePolygon(bounds, polygon) {
|
|
33
|
+
const corners = [
|
|
34
|
+
[bounds.minLon, bounds.minLat],
|
|
35
|
+
[bounds.maxLon, bounds.minLat],
|
|
36
|
+
[bounds.maxLon, bounds.maxLat],
|
|
37
|
+
[bounds.minLon, bounds.maxLat],
|
|
38
|
+
];
|
|
39
|
+
if (!corners.every((c) => pointInPolygon(c, polygon)))
|
|
40
|
+
return false;
|
|
41
|
+
// For concave polygons, all corners can be inside while the polygon edge
|
|
42
|
+
// cuts through the cell. If any polygon edge intersects a cell edge, the
|
|
43
|
+
// cell is not fully inside.
|
|
44
|
+
const boundsEdges = [
|
|
45
|
+
[corners[0], corners[1]],
|
|
46
|
+
[corners[1], corners[2]],
|
|
47
|
+
[corners[2], corners[3]],
|
|
48
|
+
[corners[3], corners[0]],
|
|
49
|
+
];
|
|
50
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
51
|
+
for (const be of boundsEdges) {
|
|
52
|
+
if (segmentsIntersect(be[0], be[1], polygon[j], polygon[i]))
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Test whether a bounds rectangle overlaps a polygon at all.
|
|
60
|
+
* Checks: (1) any bounds corner inside polygon, (2) any polygon vertex inside bounds,
|
|
61
|
+
* (3) any edge intersection.
|
|
62
|
+
*/
|
|
63
|
+
export function boundsOverlapsPolygon(bounds, polygon) {
|
|
64
|
+
const corners = [
|
|
65
|
+
[bounds.minLon, bounds.minLat],
|
|
66
|
+
[bounds.maxLon, bounds.minLat],
|
|
67
|
+
[bounds.maxLon, bounds.maxLat],
|
|
68
|
+
[bounds.minLon, bounds.maxLat],
|
|
69
|
+
];
|
|
70
|
+
// Any bounds corner inside polygon?
|
|
71
|
+
if (corners.some((c) => pointInPolygon(c, polygon)))
|
|
72
|
+
return true;
|
|
73
|
+
// Any polygon vertex inside bounds?
|
|
74
|
+
for (const [px, py] of polygon) {
|
|
75
|
+
if (px >= bounds.minLon && px <= bounds.maxLon && py >= bounds.minLat && py <= bounds.maxLat) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check edge intersections between bounds edges and polygon edges
|
|
80
|
+
const boundsEdges = [
|
|
81
|
+
[corners[0], corners[1]],
|
|
82
|
+
[corners[1], corners[2]],
|
|
83
|
+
[corners[2], corners[3]],
|
|
84
|
+
[corners[3], corners[0]],
|
|
85
|
+
];
|
|
86
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
87
|
+
const polyEdge = [polygon[j], polygon[i]];
|
|
88
|
+
for (const boundsEdge of boundsEdges) {
|
|
89
|
+
if (segmentsIntersect(boundsEdge[0], boundsEdge[1], polyEdge[0], polyEdge[1])) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
/** Test whether two line segments (a1->a2) and (b1->b2) intersect. */
|
|
97
|
+
function segmentsIntersect(a1, a2, b1, b2) {
|
|
98
|
+
const d1 = cross(b1, b2, a1);
|
|
99
|
+
const d2 = cross(b1, b2, a2);
|
|
100
|
+
const d3 = cross(a1, a2, b1);
|
|
101
|
+
const d4 = cross(a1, a2, b2);
|
|
102
|
+
if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
|
|
103
|
+
((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
if (d1 === 0 && onSegment(b1, b2, a1))
|
|
107
|
+
return true;
|
|
108
|
+
if (d2 === 0 && onSegment(b1, b2, a2))
|
|
109
|
+
return true;
|
|
110
|
+
if (d3 === 0 && onSegment(a1, a2, b1))
|
|
111
|
+
return true;
|
|
112
|
+
if (d4 === 0 && onSegment(a1, a2, b2))
|
|
113
|
+
return true;
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
function cross(a, b, c) {
|
|
117
|
+
return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
|
|
118
|
+
}
|
|
119
|
+
function onSegment(a, b, p) {
|
|
120
|
+
return Math.min(a[0], b[0]) <= p[0] && p[0] <= Math.max(a[0], b[0]) &&
|
|
121
|
+
Math.min(a[1], b[1]) <= p[1] && p[1] <= Math.max(a[1], b[1]);
|
|
122
|
+
}
|
|
123
|
+
/** Strip closing vertex from a ring if it duplicates the first vertex. */
|
|
124
|
+
function stripClosingVertex(ring) {
|
|
125
|
+
if (ring.length > 1 &&
|
|
126
|
+
ring[0][0] === ring[ring.length - 1][0] &&
|
|
127
|
+
ring[0][1] === ring[ring.length - 1][1]) {
|
|
128
|
+
return ring.slice(0, -1);
|
|
129
|
+
}
|
|
130
|
+
return ring;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Normalise a PolygonInput to a NormalisedPolygon with outer ring and holes.
|
|
134
|
+
* - `[number, number][]` → outer ring only, no holes
|
|
135
|
+
* - GeoJSON Polygon → outer ring + inner rings (holes) extracted
|
|
136
|
+
* - GeoJSON MultiPolygon → not handled here (caller processes each polygon separately)
|
|
137
|
+
*/
|
|
138
|
+
function normalisePolygonInput(input) {
|
|
139
|
+
if (Array.isArray(input)) {
|
|
140
|
+
return { outer: input, holes: [] };
|
|
141
|
+
}
|
|
142
|
+
if (input.type === 'Polygon') {
|
|
143
|
+
const ring = input.coordinates[0];
|
|
144
|
+
if (!ring || ring.length === 0) {
|
|
145
|
+
throw new Error('GeoJSON Polygon has no outer ring');
|
|
146
|
+
}
|
|
147
|
+
const outer = stripClosingVertex(ring);
|
|
148
|
+
// Extract inner rings (holes), stripping closing vertices and ignoring degenerate rings
|
|
149
|
+
const holes = [];
|
|
150
|
+
for (let i = 1; i < input.coordinates.length; i++) {
|
|
151
|
+
const holeRing = stripClosingVertex(input.coordinates[i]);
|
|
152
|
+
if (holeRing.length >= 3) {
|
|
153
|
+
holes.push(holeRing);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { outer, holes };
|
|
157
|
+
}
|
|
158
|
+
throw new Error(`Unsupported input type: ${input.type}`);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Convert a polygon (array of [lon, lat] vertices) to an efficient set of
|
|
162
|
+
* multi-precision geohash strings using recursive subdivision.
|
|
163
|
+
*
|
|
164
|
+
* Edges always subdivide to maxPrecision for a tight boundary. Interior
|
|
165
|
+
* cells use the coarsest precision allowed by mergeThreshold. If the result
|
|
166
|
+
* exceeds maxCells, maxPrecision is stepped down until it fits.
|
|
167
|
+
*
|
|
168
|
+
* Throws RangeError if the polygon cannot be covered within maxCells at
|
|
169
|
+
* the given minPrecision.
|
|
170
|
+
*
|
|
171
|
+
* **Antimeridian:** polygons crossing ±180° longitude are not supported.
|
|
172
|
+
* Split at the antimeridian and cover each half separately.
|
|
173
|
+
*/
|
|
174
|
+
export function polygonToGeohashes(input, options = {}) {
|
|
175
|
+
// Parse and validate options upfront (shared by single and multi paths)
|
|
176
|
+
const { minPrecision: rawMin = 1, maxPrecision: rawMax = 9, maxCells = 500, mergeThreshold: rawThreshold = 1.0 } = options;
|
|
177
|
+
if (!Number.isFinite(rawMin))
|
|
178
|
+
throw new RangeError(`Invalid minPrecision: ${rawMin}`);
|
|
179
|
+
if (!Number.isFinite(rawMax))
|
|
180
|
+
throw new RangeError(`Invalid maxPrecision: ${rawMax}`);
|
|
181
|
+
if (!Number.isFinite(maxCells) || maxCells < 1)
|
|
182
|
+
throw new RangeError(`Invalid maxCells: ${maxCells}`);
|
|
183
|
+
if (!Number.isFinite(rawThreshold))
|
|
184
|
+
throw new RangeError(`Invalid mergeThreshold: ${rawThreshold}`);
|
|
185
|
+
const minPrecision = Math.max(1, Math.min(9, Math.round(rawMin)));
|
|
186
|
+
const maxPrecision = Math.max(minPrecision, Math.min(9, Math.round(rawMax)));
|
|
187
|
+
const threshold = Math.max(0, Math.min(1, rawThreshold));
|
|
188
|
+
// Handle MultiPolygon: global maxCells cap across all child polygons
|
|
189
|
+
if (!Array.isArray(input) && input.type === 'MultiPolygon') {
|
|
190
|
+
if (input.coordinates.length === 0)
|
|
191
|
+
return [];
|
|
192
|
+
// Normalise all children upfront
|
|
193
|
+
const children = input.coordinates.map((polyCoords) => normalisePolygonInput({ type: 'Polygon', coordinates: polyCoords }));
|
|
194
|
+
// Validate all children before computing
|
|
195
|
+
for (const { outer } of children) {
|
|
196
|
+
if (outer.length < 3) {
|
|
197
|
+
throw new Error('Polygon must have at least 3 vertices');
|
|
198
|
+
}
|
|
199
|
+
for (let i = 0; i < outer.length; i++) {
|
|
200
|
+
const j = (i + 1) % outer.length;
|
|
201
|
+
if (Math.abs(outer[i][0] - outer[j][0]) > 180) {
|
|
202
|
+
throw new Error('Polygons crossing the antimeridian (±180° longitude) are not supported');
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Retry loop from maxPrecision down to minPrecision
|
|
207
|
+
const bailout = maxCells * 4;
|
|
208
|
+
for (let mp = maxPrecision; mp >= minPrecision; mp--) {
|
|
209
|
+
const allHashes = [];
|
|
210
|
+
let bailed = false;
|
|
211
|
+
for (const { outer, holes } of children) {
|
|
212
|
+
const result = computeGeohashes(outer, holes, minPrecision, mp, threshold, bailout);
|
|
213
|
+
if (result === null) {
|
|
214
|
+
bailed = true;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
allHashes.push(...result);
|
|
218
|
+
}
|
|
219
|
+
if (bailed)
|
|
220
|
+
continue;
|
|
221
|
+
const merged = deduplicateGeohashes(allHashes);
|
|
222
|
+
if (merged.length <= maxCells)
|
|
223
|
+
return merged;
|
|
224
|
+
}
|
|
225
|
+
// Fallback: minPrecision with threshold=0
|
|
226
|
+
const fallbackAll = [];
|
|
227
|
+
for (const { outer, holes } of children) {
|
|
228
|
+
const result = computeGeohashes(outer, holes, minPrecision, minPrecision, 0) ?? [];
|
|
229
|
+
fallbackAll.push(...result);
|
|
230
|
+
}
|
|
231
|
+
const fallback = deduplicateGeohashes(fallbackAll);
|
|
232
|
+
if (fallback.length <= maxCells)
|
|
233
|
+
return fallback;
|
|
234
|
+
throw new RangeError(`MultiPolygon requires at least ${fallback.length} cells at precision ${minPrecision}, but maxCells is ${maxCells}. ` +
|
|
235
|
+
'Increase maxCells or reduce the polygon area.');
|
|
236
|
+
}
|
|
237
|
+
const { outer: polygon, holes } = normalisePolygonInput(input);
|
|
238
|
+
// Guard: degenerate polygons
|
|
239
|
+
if (polygon.length < 3) {
|
|
240
|
+
throw new Error('Polygon must have at least 3 vertices');
|
|
241
|
+
}
|
|
242
|
+
// Guard: antimeridian-crossing polygons are not supported
|
|
243
|
+
for (let i = 0; i < polygon.length; i++) {
|
|
244
|
+
const j = (i + 1) % polygon.length;
|
|
245
|
+
if (Math.abs(polygon[i][0] - polygon[j][0]) > 180) {
|
|
246
|
+
throw new Error('Polygons crossing the antimeridian (±180° longitude) are not supported');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Guard: all coordinates must be within valid geographic bounds
|
|
250
|
+
for (const [lon, lat] of polygon) {
|
|
251
|
+
if (!Number.isFinite(lat) || lat < -90 || lat > 90) {
|
|
252
|
+
throw new RangeError(`Invalid latitude in polygon: ${lat}`);
|
|
253
|
+
}
|
|
254
|
+
if (!Number.isFinite(lon) || lon < -180 || lon > 180) {
|
|
255
|
+
throw new RangeError(`Invalid longitude in polygon: ${lon}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
for (const hole of holes) {
|
|
259
|
+
for (const [lon, lat] of hole) {
|
|
260
|
+
if (!Number.isFinite(lat) || lat < -90 || lat > 90) {
|
|
261
|
+
throw new RangeError(`Invalid latitude in hole: ${lat}`);
|
|
262
|
+
}
|
|
263
|
+
if (!Number.isFinite(lon) || lon < -180 || lon > 180) {
|
|
264
|
+
throw new RangeError(`Invalid longitude in hole: ${lon}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Early bailout limit
|
|
269
|
+
const bailout = maxCells * 4;
|
|
270
|
+
// Try at requested maxPrecision, stepping down if too many cells
|
|
271
|
+
for (let mp = maxPrecision; mp >= minPrecision; mp--) {
|
|
272
|
+
const result = computeGeohashes(polygon, holes, minPrecision, mp, threshold, bailout);
|
|
273
|
+
if (result !== null && result.length <= maxCells)
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
// Fallback: minPrecision with threshold=0
|
|
277
|
+
const fallback = computeGeohashes(polygon, holes, minPrecision, minPrecision, 0) ?? [];
|
|
278
|
+
if (fallback.length <= maxCells)
|
|
279
|
+
return fallback;
|
|
280
|
+
throw new RangeError(`Polygon requires at least ${fallback.length} cells at precision ${minPrecision}, but maxCells is ${maxCells}. ` +
|
|
281
|
+
'Increase maxCells or reduce the polygon area.');
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Compute geohashes covering a polygon via greedy recursive subdivision.
|
|
285
|
+
*
|
|
286
|
+
* - Edges always subdivide to maxPrecision (tight boundary).
|
|
287
|
+
* - Interior cells emit at the coarsest precision allowed by coverageThreshold.
|
|
288
|
+
* threshold 1.0 → interior at maxPrecision (uniform cells, most cells).
|
|
289
|
+
* threshold 0.0 → interior at minPrecision (coarsest blocks, fewest cells).
|
|
290
|
+
* - Only fully-inside cells are emitted below maxPrecision, so no blocks
|
|
291
|
+
* extend outside the polygon boundary.
|
|
292
|
+
*/
|
|
293
|
+
function computeGeohashes(polygon, holes, minPrecision, maxPrecision, coverageThreshold, bailout) {
|
|
294
|
+
const result = [];
|
|
295
|
+
const limit = bailout ?? Infinity;
|
|
296
|
+
const hasHoles = holes.length > 0;
|
|
297
|
+
// Pre-compute polygon AABB for fast rejection.
|
|
298
|
+
let polyMinLon = Infinity, polyMaxLon = -Infinity;
|
|
299
|
+
let polyMinLat = Infinity, polyMaxLat = -Infinity;
|
|
300
|
+
for (const [lon, lat] of polygon) {
|
|
301
|
+
if (lon < polyMinLon)
|
|
302
|
+
polyMinLon = lon;
|
|
303
|
+
if (lon > polyMaxLon)
|
|
304
|
+
polyMaxLon = lon;
|
|
305
|
+
if (lat < polyMinLat)
|
|
306
|
+
polyMinLat = lat;
|
|
307
|
+
if (lat > polyMaxLat)
|
|
308
|
+
polyMaxLat = lat;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Check if bounds are fully inside the outer polygon and not fully inside any hole.
|
|
312
|
+
* A cell is "fully inside" the effective polygon when:
|
|
313
|
+
* - all corners are inside the outer ring, AND
|
|
314
|
+
* - the cell does not overlap any hole
|
|
315
|
+
*/
|
|
316
|
+
const isFullyInside = (b) => {
|
|
317
|
+
if (!boundsFullyInsidePolygon(b, polygon))
|
|
318
|
+
return false;
|
|
319
|
+
if (hasHoles) {
|
|
320
|
+
for (const hole of holes) {
|
|
321
|
+
if (boundsOverlapsPolygon(b, hole))
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return true;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Check if bounds overlap the effective polygon (outer minus holes).
|
|
329
|
+
* A cell overlaps when it overlaps the outer ring AND is not fully inside any hole.
|
|
330
|
+
*/
|
|
331
|
+
const doesOverlap = (b) => {
|
|
332
|
+
if (!boundsOverlapsPolygon(b, polygon))
|
|
333
|
+
return false;
|
|
334
|
+
if (hasHoles) {
|
|
335
|
+
for (const hole of holes) {
|
|
336
|
+
if (boundsFullyInsidePolygon(b, hole))
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return true;
|
|
341
|
+
};
|
|
342
|
+
// Interior cells must reach at least this precision before being emitted.
|
|
343
|
+
// At threshold 1.0 → all cells at maxPrecision (uniform).
|
|
344
|
+
// At threshold 0.0 → interior cells as coarse as minPrecision.
|
|
345
|
+
const interiorMinPrecision = Math.ceil(minPrecision + (maxPrecision - minPrecision) * coverageThreshold);
|
|
346
|
+
// Seed: precision-1 cells filtered by AABB then polygon overlap.
|
|
347
|
+
const queue = geohashChildren('').filter((hash) => {
|
|
348
|
+
const b = geohashBounds(hash);
|
|
349
|
+
if (b.maxLon < polyMinLon || b.minLon > polyMaxLon ||
|
|
350
|
+
b.maxLat < polyMinLat || b.minLat > polyMaxLat)
|
|
351
|
+
return false;
|
|
352
|
+
return doesOverlap(b);
|
|
353
|
+
});
|
|
354
|
+
while (queue.length > 0) {
|
|
355
|
+
const hash = queue.pop();
|
|
356
|
+
const b = geohashBounds(hash);
|
|
357
|
+
if (isFullyInside(b)) {
|
|
358
|
+
if (hash.length >= interiorMinPrecision) {
|
|
359
|
+
result.push(hash);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
for (const child of geohashChildren(hash)) {
|
|
363
|
+
queue.push(child);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else if (hash.length >= maxPrecision) {
|
|
368
|
+
// At max precision: only emit if it overlaps the effective polygon
|
|
369
|
+
if (doesOverlap(b)) {
|
|
370
|
+
result.push(hash);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
for (const child of geohashChildren(hash)) {
|
|
375
|
+
const cb = geohashBounds(child);
|
|
376
|
+
// Fast AABB rejection before expensive polygon checks
|
|
377
|
+
if (cb.maxLon < polyMinLon || cb.minLon > polyMaxLon ||
|
|
378
|
+
cb.maxLat < polyMinLat || cb.minLat > polyMaxLat)
|
|
379
|
+
continue;
|
|
380
|
+
if (isFullyInside(cb)) {
|
|
381
|
+
if (child.length >= interiorMinPrecision) {
|
|
382
|
+
result.push(child);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
queue.push(child);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (doesOverlap(cb)) {
|
|
389
|
+
queue.push(child);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (result.length > limit)
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
// Map coverageThreshold to merge aggressiveness:
|
|
397
|
+
// threshold 1.0 (tight) → require all 32 siblings (exact boundary)
|
|
398
|
+
// threshold 0.0 (loose) → require only 24 siblings (aggressive merge, fewer cells)
|
|
399
|
+
const minSiblings = Math.round(24 + coverageThreshold * 8);
|
|
400
|
+
return mergeCompleteSiblings(result, minPrecision, minSiblings).sort();
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Post-processing merge: bottom-up consolidation of sibling sets.
|
|
404
|
+
* When at least `minSiblings` of 32 children of a parent are present,
|
|
405
|
+
* replace them with the parent. With `minSiblings < 32` this trades a
|
|
406
|
+
* tiny boundary overshoot for a significantly smaller result array.
|
|
407
|
+
* Iterates from finest to coarsest so merges can cascade.
|
|
408
|
+
*/
|
|
409
|
+
function mergeCompleteSiblings(hashes, minPrecision, minSiblings = 30) {
|
|
410
|
+
const set = new Set(hashes);
|
|
411
|
+
let maxP = 0;
|
|
412
|
+
for (const h of set) {
|
|
413
|
+
if (h.length > maxP)
|
|
414
|
+
maxP = h.length;
|
|
415
|
+
}
|
|
416
|
+
for (let p = maxP; p > minPrecision; p--) {
|
|
417
|
+
const parentCounts = new Map();
|
|
418
|
+
for (const h of set) {
|
|
419
|
+
if (h.length === p) {
|
|
420
|
+
const parent = h.slice(0, -1);
|
|
421
|
+
parentCounts.set(parent, (parentCounts.get(parent) ?? 0) + 1);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
for (const [parent, count] of parentCounts) {
|
|
425
|
+
if (count >= minSiblings) {
|
|
426
|
+
// Near-complete or complete — replace children with parent
|
|
427
|
+
for (const ch of geohashChildren(parent)) {
|
|
428
|
+
set.delete(ch);
|
|
429
|
+
}
|
|
430
|
+
set.add(parent);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return Array.from(set);
|
|
435
|
+
}
|
|
436
|
+
// --- geohashesToConvexHull — reconstruct editable polygon ---
|
|
437
|
+
/** 2D cross product of vectors OA and OB where O is the origin. */
|
|
438
|
+
function cross2D(o, a, b) {
|
|
439
|
+
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Compute a convex hull polygon from an array of geohash strings.
|
|
443
|
+
* Collects all unique cell corners, then builds the hull using
|
|
444
|
+
* Andrew's monotone chain algorithm.
|
|
445
|
+
* Returns `[lon, lat][]`.
|
|
446
|
+
*
|
|
447
|
+
* **Antimeridian:** throws if the input hashes straddle ±180° longitude.
|
|
448
|
+
* Dateline-crossing hulls cannot be consumed by planar geometry functions
|
|
449
|
+
* (`pointInPolygon`, `polygonToGeohashes`). Split hash sets at the
|
|
450
|
+
* antimeridian and compute separate hulls for each side.
|
|
451
|
+
*/
|
|
452
|
+
export function geohashesToConvexHull(hashes) {
|
|
453
|
+
if (hashes.length === 0)
|
|
454
|
+
return [];
|
|
455
|
+
// Collect unique corners from all geohash bounding boxes
|
|
456
|
+
const seen = new Set();
|
|
457
|
+
const points = [];
|
|
458
|
+
for (const hash of hashes) {
|
|
459
|
+
const b = geohashBounds(hash);
|
|
460
|
+
const corners = [
|
|
461
|
+
[b.minLon, b.minLat],
|
|
462
|
+
[b.maxLon, b.minLat],
|
|
463
|
+
[b.maxLon, b.maxLat],
|
|
464
|
+
[b.minLon, b.maxLat],
|
|
465
|
+
];
|
|
466
|
+
for (const c of corners) {
|
|
467
|
+
const key = `${c[0]},${c[1]}`;
|
|
468
|
+
if (!seen.has(key)) {
|
|
469
|
+
seen.add(key);
|
|
470
|
+
points.push(c);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (points.length < 3)
|
|
475
|
+
return points;
|
|
476
|
+
// Guard: antimeridian-straddling hashes produce hulls that break planar geometry
|
|
477
|
+
const lons = points.map(p => p[0]);
|
|
478
|
+
if (Math.max(...lons) - Math.min(...lons) > 180) {
|
|
479
|
+
throw new Error('Geohashes straddle the antimeridian (±180° longitude). ' +
|
|
480
|
+
'Split into separate sets and compute hulls independently.');
|
|
481
|
+
}
|
|
482
|
+
// Sort by x then y
|
|
483
|
+
points.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
|
484
|
+
// Andrew's monotone chain — lower hull
|
|
485
|
+
const lower = [];
|
|
486
|
+
for (const p of points) {
|
|
487
|
+
while (lower.length >= 2 && cross2D(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
|
|
488
|
+
lower.pop();
|
|
489
|
+
}
|
|
490
|
+
lower.push(p);
|
|
491
|
+
}
|
|
492
|
+
// Upper hull
|
|
493
|
+
const upper = [];
|
|
494
|
+
for (let i = points.length - 1; i >= 0; i--) {
|
|
495
|
+
const p = points[i];
|
|
496
|
+
while (upper.length >= 2 && cross2D(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
|
|
497
|
+
upper.pop();
|
|
498
|
+
}
|
|
499
|
+
upper.push(p);
|
|
500
|
+
}
|
|
501
|
+
// Remove last point of each half because it's repeated
|
|
502
|
+
lower.pop();
|
|
503
|
+
upper.pop();
|
|
504
|
+
return [...lower, ...upper];
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Remove redundant geohashes and merge sibling groups.
|
|
508
|
+
* 1. Remove any geohash whose ancestor (shorter prefix) is already in the set.
|
|
509
|
+
* 2. Merge sibling sets bottom-up — exact (all 32) by default, or
|
|
510
|
+
* near-complete (≥30/32) when `lossy: true`.
|
|
511
|
+
*/
|
|
512
|
+
export function deduplicateGeohashes(hashes, options = {}) {
|
|
513
|
+
// Validate all input hashes
|
|
514
|
+
for (const h of hashes)
|
|
515
|
+
validateGeohash(h);
|
|
516
|
+
// Step 1: remove children when ancestor is present
|
|
517
|
+
const set = new Set(hashes);
|
|
518
|
+
const filtered = Array.from(set).filter((h) => {
|
|
519
|
+
for (let len = 1; len < h.length; len++) {
|
|
520
|
+
if (set.has(h.slice(0, len)))
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
return true;
|
|
524
|
+
});
|
|
525
|
+
// Step 2: merge sibling groups bottom-up
|
|
526
|
+
const minSiblings = options.lossy ? 30 : 32;
|
|
527
|
+
return mergeCompleteSiblings(filtered, 1, minSiblings).sort();
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Convert an array of geohash strings to a GeoJSON FeatureCollection
|
|
531
|
+
* of polygon rectangles, suitable for rendering on a MapLibre map.
|
|
532
|
+
*/
|
|
533
|
+
export function geohashesToGeoJSON(hashes) {
|
|
534
|
+
return {
|
|
535
|
+
type: 'FeatureCollection',
|
|
536
|
+
features: hashes.map((hash) => {
|
|
537
|
+
const b = geohashBounds(hash);
|
|
538
|
+
return {
|
|
539
|
+
type: 'Feature',
|
|
540
|
+
geometry: {
|
|
541
|
+
type: 'Polygon',
|
|
542
|
+
coordinates: [[
|
|
543
|
+
[b.minLon, b.minLat],
|
|
544
|
+
[b.maxLon, b.minLat],
|
|
545
|
+
[b.maxLon, b.maxLat],
|
|
546
|
+
[b.minLon, b.maxLat],
|
|
547
|
+
[b.minLon, b.minLat],
|
|
548
|
+
]],
|
|
549
|
+
},
|
|
550
|
+
properties: { geohash: hash, precision: hash.length },
|
|
551
|
+
};
|
|
552
|
+
}),
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** GeoJSON Polygon geometry. Coordinates are [lon, lat] rings; first ring is the outer boundary. */
|
|
2
|
+
export interface GeoJSONPolygon {
|
|
3
|
+
type: 'Polygon';
|
|
4
|
+
coordinates: number[][][];
|
|
5
|
+
}
|
|
6
|
+
/** GeoJSON MultiPolygon geometry. Each element of coordinates is a Polygon's coordinate array. */
|
|
7
|
+
export interface GeoJSONMultiPolygon {
|
|
8
|
+
type: 'MultiPolygon';
|
|
9
|
+
coordinates: number[][][][];
|
|
10
|
+
}
|
|
11
|
+
/** Input types accepted by polygonToGeohashes. */
|
|
12
|
+
export type PolygonInput = [number, number][] | GeoJSONPolygon | GeoJSONMultiPolygon;
|
|
13
|
+
//# sourceMappingURL=geojson.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geojson.d.ts","sourceRoot":"","sources":["../src/geojson.ts"],"names":[],"mappings":"AAEA,oGAAoG;AACpG,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAA;IACf,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;CAC1B;AAED,kGAAkG;AAClG,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAA;IACpB,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAA;CAC5B;AAED,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,cAAc,GAAG,mBAAmB,CAAA"}
|
package/dist/geojson.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geojson.js","sourceRoot":"","sources":["../src/geojson.ts"],"names":[],"mappings":"AAAA,kGAAkG"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { encode, decode, bounds, children, contains, matchesAny, neighbour, neighbours, distance, distanceFromCoords, radiusToPrecision, precisionToRadius, type GeohashBounds, type Direction, } from './core.js';
|
|
2
|
+
export { pointInPolygon, boundsOverlapsPolygon, boundsFullyInsidePolygon, polygonToGeohashes, geohashesToGeoJSON, geohashesToConvexHull, deduplicateGeohashes, type CoverageOptions, type DeduplicateOptions, type GeohashGeoJSON, type PolygonInput, type GeoJSONPolygon, type GeoJSONMultiPolygon, } from './coverage.js';
|
|
3
|
+
export { createGTagLadder, createGTagFilter, createGTagFilterFromGeohashes, expandRings, nearbyFilter, parseGTags, bestGeohash, } from './nostr.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EACtD,SAAS,EAAE,UAAU,EACrB,QAAQ,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAClE,KAAK,aAAa,EAAE,KAAK,SAAS,GACnC,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,cAAc,EAAE,qBAAqB,EAAE,wBAAwB,EAC/D,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAC7D,oBAAoB,EACpB,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAClE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,GACjE,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,gBAAgB,EAAE,gBAAgB,EAAE,6BAA6B,EACjE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,GACnD,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { encode, decode, bounds, children, contains, matchesAny, neighbour, neighbours, distance, distanceFromCoords, radiusToPrecision, precisionToRadius, } from './core.js';
|
|
2
|
+
export { pointInPolygon, boundsOverlapsPolygon, boundsFullyInsidePolygon, polygonToGeohashes, geohashesToGeoJSON, geohashesToConvexHull, deduplicateGeohashes, } from './coverage.js';
|
|
3
|
+
export { createGTagLadder, createGTagFilter, createGTagFilterFromGeohashes, expandRings, nearbyFilter, parseGTags, bestGeohash, } from './nostr.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EACtD,SAAS,EAAE,UAAU,EACrB,QAAQ,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,GAEnE,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,cAAc,EAAE,qBAAqB,EAAE,wBAAwB,EAC/D,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAC7D,oBAAoB,GAGrB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,gBAAgB,EAAE,gBAAgB,EAAE,6BAA6B,EACjE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,GACnD,MAAM,YAAY,CAAA"}
|