@india-boundary-corrector/maplibre-protocol 0.2.0 → 0.2.2
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/README.md +1 -1
- package/dist/index.global.js +191 -118
- package/dist/index.global.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
package/dist/index.global.js
CHANGED
|
@@ -30,7 +30,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
// ../data/version.js
|
|
33
|
-
var packageVersion = "0.2.
|
|
33
|
+
var packageVersion = "0.2.2";
|
|
34
34
|
|
|
35
35
|
// ../data/index.js
|
|
36
36
|
var import_meta = {};
|
|
@@ -128,12 +128,11 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
128
128
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
|
|
129
129
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
|
|
130
130
|
],
|
|
131
|
-
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.
|
|
131
|
+
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.75, "16": 2.5 },
|
|
132
132
|
lineStyles: [
|
|
133
133
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
134
134
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
135
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.
|
|
136
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
135
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 9, "10": 8, "14": 8 }, lineExtensionFactor: 0.1 },
|
|
137
136
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
138
137
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
139
138
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
|
|
@@ -156,12 +155,11 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
156
155
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
|
|
157
156
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
|
|
158
157
|
],
|
|
159
|
-
lineWidthStops: { "1":
|
|
158
|
+
lineWidthStops: { "1": 1, "3": 1, "4": 2, "5": 2, "6": 2.5, "7": 3, "8": 3, "10": 4, "11": 4, "12": 4 },
|
|
160
159
|
lineStyles: [
|
|
161
160
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
162
161
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
163
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6,
|
|
164
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
162
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 20, "8": 19, "10": 18, "12": 17 }, lineExtensionFactor: 0.1 },
|
|
165
163
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
166
164
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
167
165
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
|
|
@@ -172,15 +170,20 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
172
170
|
id: "open-topo",
|
|
173
171
|
tileUrlTemplates: [
|
|
174
172
|
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
175
|
-
"https://tile.opentopomap.org/{z}/{x}/{y}.png"
|
|
173
|
+
"https://tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
174
|
+
"https://{s}.tile.top-o-map.de/{z}/{x}/{y}.png",
|
|
175
|
+
"https://tile.top-o-map.de/{z}/{x}/{y}.png"
|
|
176
176
|
],
|
|
177
177
|
lineWidthStops: { "4": 0.75, "5": 1, "6": 1.25, "7": 1.5, "8": 1.75, "9": 1.25, "10": 1.25, "13": 1.5 },
|
|
178
178
|
lineStyles: [
|
|
179
179
|
{ color: "rgb(83, 83, 83)", layerSuffix: "ne", startZoom: 4, endZoom: 6 },
|
|
180
180
|
{ color: "rgb(173, 173, 173)", layerSuffix: "osm", startZoom: 7, endZoom: 8, alpha: 0.5, widthFraction: 4 },
|
|
181
181
|
{ color: "rgb(83, 83, 83)", layerSuffix: "osm", startZoom: 7, endZoom: 8 },
|
|
182
|
+
{ color: "rgb(83, 83, 83)", layerSuffix: "osm-internal", widthFraction: 0.75, startZoom: 7, endZoom: 8 },
|
|
182
183
|
{ color: "rgb(199, 158, 204)", layerSuffix: "osm", startZoom: 9, widthFraction: 7, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
183
|
-
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 }
|
|
184
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 },
|
|
185
|
+
{ color: "rgb(199, 158, 204)", layerSuffix: "osm-internal", startZoom: 9, widthFraction: 2.25, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
186
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm-internal", startZoom: 9, widthFactor: 0.75, lineExtensionFactor: 0.2 }
|
|
184
187
|
]
|
|
185
188
|
},
|
|
186
189
|
{
|
|
@@ -189,9 +192,8 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
189
192
|
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
190
193
|
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
191
194
|
],
|
|
192
|
-
lineWidthStops: { "
|
|
195
|
+
lineWidthStops: { "3": 0.7, "4": 1, "10": 3.75 },
|
|
193
196
|
lineStyles: [
|
|
194
|
-
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
|
|
195
197
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
|
|
196
198
|
{ color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
|
|
197
199
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
|
|
@@ -215,6 +217,39 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
215
217
|
var INFINITY = -1;
|
|
216
218
|
var MIN_LINE_WIDTH = 0.1;
|
|
217
219
|
var DEFAULT_LINE_WIDTH = 1;
|
|
220
|
+
function interpolateLineWidth(zoom, lineWidthStops) {
|
|
221
|
+
const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
222
|
+
if (lineWidthStops[zoom] !== void 0) {
|
|
223
|
+
return lineWidthStops[zoom];
|
|
224
|
+
}
|
|
225
|
+
if (zoom < zooms[0]) {
|
|
226
|
+
const z1 = zooms[0];
|
|
227
|
+
const z2 = zooms[1];
|
|
228
|
+
const w1 = lineWidthStops[z1];
|
|
229
|
+
const w2 = lineWidthStops[z2];
|
|
230
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
231
|
+
return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
|
|
232
|
+
}
|
|
233
|
+
if (zoom > zooms[zooms.length - 1]) {
|
|
234
|
+
const z1 = zooms[zooms.length - 2];
|
|
235
|
+
const z2 = zooms[zooms.length - 1];
|
|
236
|
+
const w1 = lineWidthStops[z1];
|
|
237
|
+
const w2 = lineWidthStops[z2];
|
|
238
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
239
|
+
return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
|
|
240
|
+
}
|
|
241
|
+
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
242
|
+
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
243
|
+
const z1 = zooms[i2];
|
|
244
|
+
const z2 = zooms[i2 + 1];
|
|
245
|
+
const w1 = lineWidthStops[z1];
|
|
246
|
+
const w2 = lineWidthStops[z2];
|
|
247
|
+
const t = (zoom - z1) / (z2 - z1);
|
|
248
|
+
return w1 + t * (w2 - w1);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return DEFAULT_LINE_WIDTH;
|
|
252
|
+
}
|
|
218
253
|
function templateToRegex(template) {
|
|
219
254
|
const groups = [];
|
|
220
255
|
const hasRetina = template.includes("{r}");
|
|
@@ -281,14 +316,33 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
281
316
|
if (/^[a-z]+$/.test(trimmed)) return true;
|
|
282
317
|
return false;
|
|
283
318
|
}
|
|
319
|
+
function validateLineWidthStops(lineWidthStops, prefix) {
|
|
320
|
+
if (!lineWidthStops || typeof lineWidthStops !== "object" || Array.isArray(lineWidthStops)) {
|
|
321
|
+
throw new Error(`${prefix}: lineWidthStops must be an object`);
|
|
322
|
+
}
|
|
323
|
+
const stopKeys = Object.keys(lineWidthStops);
|
|
324
|
+
if (stopKeys.length < 2) {
|
|
325
|
+
throw new Error(`${prefix}: lineWidthStops must have at least 2 entries`);
|
|
326
|
+
}
|
|
327
|
+
for (const key of stopKeys) {
|
|
328
|
+
const zoom = Number(key);
|
|
329
|
+
if (!Number.isInteger(zoom) || zoom < 0) {
|
|
330
|
+
throw new Error(`${prefix}: lineWidthStops keys must be non-negative integers, got "${key}"`);
|
|
331
|
+
}
|
|
332
|
+
if (typeof lineWidthStops[key] !== "number" || lineWidthStops[key] <= 0) {
|
|
333
|
+
throw new Error(`${prefix}: lineWidthStops values must be positive numbers`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
284
337
|
var LineStyle = class _LineStyle {
|
|
285
338
|
/**
|
|
286
339
|
* Validate a LineStyle configuration object.
|
|
287
340
|
* @param {Object} obj - The object to validate
|
|
288
341
|
* @param {number} [index] - Optional index for error messages (when validating in an array)
|
|
342
|
+
* @param {boolean} [requireLineWidthStops=false] - Whether lineWidthStops is required
|
|
289
343
|
* @throws {Error} If validation fails
|
|
290
344
|
*/
|
|
291
|
-
static validateJSON(obj, index) {
|
|
345
|
+
static validateJSON(obj, index, requireLineWidthStops = false) {
|
|
292
346
|
const prefix = index !== void 0 ? `lineStyles[${index}]` : "LineStyle";
|
|
293
347
|
if (!obj || typeof obj !== "object") {
|
|
294
348
|
throw new Error(`${prefix}: must be an object`);
|
|
@@ -323,22 +377,30 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
323
377
|
if (obj.delWidthFactor !== void 0 && (typeof obj.delWidthFactor !== "number" || obj.delWidthFactor < 0)) {
|
|
324
378
|
throw new Error(`${prefix}: delWidthFactor must be a non-negative number`);
|
|
325
379
|
}
|
|
380
|
+
if (requireLineWidthStops && obj.lineWidthStops === void 0) {
|
|
381
|
+
throw new Error(`${prefix}: lineWidthStops is required`);
|
|
382
|
+
}
|
|
383
|
+
if (obj.lineWidthStops !== void 0) {
|
|
384
|
+
validateLineWidthStops(obj.lineWidthStops, prefix);
|
|
385
|
+
}
|
|
326
386
|
}
|
|
327
387
|
/**
|
|
328
388
|
* @param {Object} options
|
|
329
389
|
* @param {string} options.color - CSS color string
|
|
330
390
|
* @param {string} options.layerSuffix - Layer suffix (e.g., 'osm', 'ne', 'osm-disp')
|
|
391
|
+
* @param {Object<number, number>} options.lineWidthStops - Line width stops for this style
|
|
331
392
|
* @param {number} [options.widthFraction=1.0] - Multiplier for base line width
|
|
332
393
|
* @param {number[]} [options.dashArray] - Dash pattern for dashed lines
|
|
333
394
|
* @param {number} [options.alpha=1.0] - Opacity (0-1)
|
|
334
395
|
* @param {number} [options.startZoom=0] - Minimum zoom level for this style
|
|
335
396
|
* @param {number} [options.endZoom=INFINITY] - Maximum zoom level for this style (INFINITY means no limit)
|
|
336
|
-
* @param {number} [options.lineExtensionFactor=0.
|
|
397
|
+
* @param {number} [options.lineExtensionFactor=0.0] - Factor to extend lines by (multiplied by deletion line width)
|
|
337
398
|
* @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
|
|
338
399
|
*/
|
|
339
|
-
constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
400
|
+
constructor({ color, layerSuffix, lineWidthStops, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
340
401
|
this.color = color;
|
|
341
402
|
this.layerSuffix = layerSuffix;
|
|
403
|
+
this.lineWidthStops = lineWidthStops;
|
|
342
404
|
this.widthFraction = widthFraction;
|
|
343
405
|
this.dashArray = dashArray;
|
|
344
406
|
this.alpha = alpha;
|
|
@@ -347,6 +409,14 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
347
409
|
this.lineExtensionFactor = lineExtensionFactor;
|
|
348
410
|
this.delWidthFactor = delWidthFactor;
|
|
349
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Get base line width for this style at a given zoom level.
|
|
414
|
+
* @param {number} zoom - Zoom level
|
|
415
|
+
* @returns {number}
|
|
416
|
+
*/
|
|
417
|
+
getLineWidth(zoom) {
|
|
418
|
+
return interpolateLineWidth(zoom, this.lineWidthStops);
|
|
419
|
+
}
|
|
350
420
|
/**
|
|
351
421
|
* Check if this style is active at the given zoom level.
|
|
352
422
|
* @param {number} z - Zoom level
|
|
@@ -363,6 +433,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
363
433
|
return {
|
|
364
434
|
color: this.color,
|
|
365
435
|
layerSuffix: this.layerSuffix,
|
|
436
|
+
lineWidthStops: this.lineWidthStops,
|
|
366
437
|
widthFraction: this.widthFraction,
|
|
367
438
|
dashArray: this.dashArray,
|
|
368
439
|
alpha: this.alpha,
|
|
@@ -379,7 +450,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
379
450
|
* @returns {LineStyle}
|
|
380
451
|
*/
|
|
381
452
|
static fromJSON(obj, index) {
|
|
382
|
-
_LineStyle.validateJSON(obj, index);
|
|
453
|
+
_LineStyle.validateJSON(obj, index, true);
|
|
383
454
|
return new _LineStyle(obj);
|
|
384
455
|
}
|
|
385
456
|
};
|
|
@@ -445,9 +516,13 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
445
516
|
this._compiledPatterns = templates.map((t) => templateToRegex(t));
|
|
446
517
|
this._templatePatterns = templates.map((t) => templateToTemplateRegex(t));
|
|
447
518
|
this.lineWidthStops = lineWidthStops;
|
|
448
|
-
this.lineStyles = lineStyles.map(
|
|
449
|
-
(style
|
|
450
|
-
|
|
519
|
+
this.lineStyles = lineStyles.map((style) => {
|
|
520
|
+
if (style instanceof LineStyle) {
|
|
521
|
+
return style;
|
|
522
|
+
}
|
|
523
|
+
const styleWithStops = style.lineWidthStops ? style : { ...style, lineWidthStops };
|
|
524
|
+
return new LineStyle(styleWithStops);
|
|
525
|
+
});
|
|
451
526
|
}
|
|
452
527
|
/**
|
|
453
528
|
* Get line styles active at a given zoom level
|
|
@@ -466,45 +541,6 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
466
541
|
const activeStyles = this.getLineStylesForZoom(z2);
|
|
467
542
|
return [...new Set(activeStyles.map((s) => s.layerSuffix))];
|
|
468
543
|
}
|
|
469
|
-
/**
|
|
470
|
-
* Interpolate or extrapolate line width for a given zoom level.
|
|
471
|
-
* Uses the lineWidthStops map to calculate the appropriate width.
|
|
472
|
-
* @param {number} zoom - Zoom level
|
|
473
|
-
* @returns {number}
|
|
474
|
-
*/
|
|
475
|
-
getLineWidth(zoom) {
|
|
476
|
-
const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
477
|
-
if (this.lineWidthStops[zoom] !== void 0) {
|
|
478
|
-
return this.lineWidthStops[zoom];
|
|
479
|
-
}
|
|
480
|
-
if (zoom < zooms[0]) {
|
|
481
|
-
const z1 = zooms[0];
|
|
482
|
-
const z2 = zooms[1];
|
|
483
|
-
const w1 = this.lineWidthStops[z1];
|
|
484
|
-
const w2 = this.lineWidthStops[z2];
|
|
485
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
486
|
-
return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
|
|
487
|
-
}
|
|
488
|
-
if (zoom > zooms[zooms.length - 1]) {
|
|
489
|
-
const z1 = zooms[zooms.length - 2];
|
|
490
|
-
const z2 = zooms[zooms.length - 1];
|
|
491
|
-
const w1 = this.lineWidthStops[z1];
|
|
492
|
-
const w2 = this.lineWidthStops[z2];
|
|
493
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
494
|
-
return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
|
|
495
|
-
}
|
|
496
|
-
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
497
|
-
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
498
|
-
const z1 = zooms[i2];
|
|
499
|
-
const z2 = zooms[i2 + 1];
|
|
500
|
-
const w1 = this.lineWidthStops[z1];
|
|
501
|
-
const w2 = this.lineWidthStops[z2];
|
|
502
|
-
const t = (zoom - z1) / (z2 - z1);
|
|
503
|
-
return w1 + t * (w2 - w1);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return DEFAULT_LINE_WIDTH;
|
|
507
|
-
}
|
|
508
544
|
/**
|
|
509
545
|
* Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
|
|
510
546
|
* @param {string | string[]} templates - Single template URL or array of template URLs
|
|
@@ -2958,12 +2994,11 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
2958
2994
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
|
|
2959
2995
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
|
|
2960
2996
|
],
|
|
2961
|
-
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.
|
|
2997
|
+
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.75, "16": 2.5 },
|
|
2962
2998
|
lineStyles: [
|
|
2963
2999
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
2964
3000
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
2965
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.
|
|
2966
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
3001
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 9, "10": 8, "14": 8 }, lineExtensionFactor: 0.1 },
|
|
2967
3002
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
2968
3003
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
2969
3004
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
|
|
@@ -2986,12 +3021,11 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
2986
3021
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
|
|
2987
3022
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
|
|
2988
3023
|
],
|
|
2989
|
-
lineWidthStops: { "1":
|
|
3024
|
+
lineWidthStops: { "1": 1, "3": 1, "4": 2, "5": 2, "6": 2.5, "7": 3, "8": 3, "10": 4, "11": 4, "12": 4 },
|
|
2990
3025
|
lineStyles: [
|
|
2991
3026
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
2992
3027
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
2993
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6,
|
|
2994
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
3028
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 20, "8": 19, "10": 18, "12": 17 }, lineExtensionFactor: 0.1 },
|
|
2995
3029
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
2996
3030
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
2997
3031
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
|
|
@@ -3002,15 +3036,20 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3002
3036
|
id: "open-topo",
|
|
3003
3037
|
tileUrlTemplates: [
|
|
3004
3038
|
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
3005
|
-
"https://tile.opentopomap.org/{z}/{x}/{y}.png"
|
|
3039
|
+
"https://tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
3040
|
+
"https://{s}.tile.top-o-map.de/{z}/{x}/{y}.png",
|
|
3041
|
+
"https://tile.top-o-map.de/{z}/{x}/{y}.png"
|
|
3006
3042
|
],
|
|
3007
3043
|
lineWidthStops: { "4": 0.75, "5": 1, "6": 1.25, "7": 1.5, "8": 1.75, "9": 1.25, "10": 1.25, "13": 1.5 },
|
|
3008
3044
|
lineStyles: [
|
|
3009
3045
|
{ color: "rgb(83, 83, 83)", layerSuffix: "ne", startZoom: 4, endZoom: 6 },
|
|
3010
3046
|
{ color: "rgb(173, 173, 173)", layerSuffix: "osm", startZoom: 7, endZoom: 8, alpha: 0.5, widthFraction: 4 },
|
|
3011
3047
|
{ color: "rgb(83, 83, 83)", layerSuffix: "osm", startZoom: 7, endZoom: 8 },
|
|
3048
|
+
{ color: "rgb(83, 83, 83)", layerSuffix: "osm-internal", widthFraction: 0.75, startZoom: 7, endZoom: 8 },
|
|
3012
3049
|
{ color: "rgb(199, 158, 204)", layerSuffix: "osm", startZoom: 9, widthFraction: 7, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
3013
|
-
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 }
|
|
3050
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 },
|
|
3051
|
+
{ color: "rgb(199, 158, 204)", layerSuffix: "osm-internal", startZoom: 9, widthFraction: 2.25, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
3052
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm-internal", startZoom: 9, widthFactor: 0.75, lineExtensionFactor: 0.2 }
|
|
3014
3053
|
]
|
|
3015
3054
|
},
|
|
3016
3055
|
{
|
|
@@ -3019,9 +3058,8 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3019
3058
|
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
3020
3059
|
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
3021
3060
|
],
|
|
3022
|
-
lineWidthStops: { "
|
|
3061
|
+
lineWidthStops: { "3": 0.7, "4": 1, "10": 3.75 },
|
|
3023
3062
|
lineStyles: [
|
|
3024
|
-
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
|
|
3025
3063
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
|
|
3026
3064
|
{ color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
|
|
3027
3065
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
|
|
@@ -3045,6 +3083,39 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3045
3083
|
var INFINITY2 = -1;
|
|
3046
3084
|
var MIN_LINE_WIDTH2 = 0.1;
|
|
3047
3085
|
var DEFAULT_LINE_WIDTH2 = 1;
|
|
3086
|
+
function interpolateLineWidth2(zoom, lineWidthStops) {
|
|
3087
|
+
const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
3088
|
+
if (lineWidthStops[zoom] !== void 0) {
|
|
3089
|
+
return lineWidthStops[zoom];
|
|
3090
|
+
}
|
|
3091
|
+
if (zoom < zooms[0]) {
|
|
3092
|
+
const z1 = zooms[0];
|
|
3093
|
+
const z2 = zooms[1];
|
|
3094
|
+
const w1 = lineWidthStops[z1];
|
|
3095
|
+
const w2 = lineWidthStops[z2];
|
|
3096
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
3097
|
+
return Math.max(MIN_LINE_WIDTH2, w1 + slope * (zoom - z1));
|
|
3098
|
+
}
|
|
3099
|
+
if (zoom > zooms[zooms.length - 1]) {
|
|
3100
|
+
const z1 = zooms[zooms.length - 2];
|
|
3101
|
+
const z2 = zooms[zooms.length - 1];
|
|
3102
|
+
const w1 = lineWidthStops[z1];
|
|
3103
|
+
const w2 = lineWidthStops[z2];
|
|
3104
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
3105
|
+
return Math.max(MIN_LINE_WIDTH2, w2 + slope * (zoom - z2));
|
|
3106
|
+
}
|
|
3107
|
+
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
3108
|
+
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
3109
|
+
const z1 = zooms[i2];
|
|
3110
|
+
const z2 = zooms[i2 + 1];
|
|
3111
|
+
const w1 = lineWidthStops[z1];
|
|
3112
|
+
const w2 = lineWidthStops[z2];
|
|
3113
|
+
const t = (zoom - z1) / (z2 - z1);
|
|
3114
|
+
return w1 + t * (w2 - w1);
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
return DEFAULT_LINE_WIDTH2;
|
|
3118
|
+
}
|
|
3048
3119
|
function templateToRegex2(template) {
|
|
3049
3120
|
const groups = [];
|
|
3050
3121
|
const hasRetina = template.includes("{r}");
|
|
@@ -3111,14 +3182,33 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3111
3182
|
if (/^[a-z]+$/.test(trimmed)) return true;
|
|
3112
3183
|
return false;
|
|
3113
3184
|
}
|
|
3185
|
+
function validateLineWidthStops2(lineWidthStops, prefix) {
|
|
3186
|
+
if (!lineWidthStops || typeof lineWidthStops !== "object" || Array.isArray(lineWidthStops)) {
|
|
3187
|
+
throw new Error(`${prefix}: lineWidthStops must be an object`);
|
|
3188
|
+
}
|
|
3189
|
+
const stopKeys = Object.keys(lineWidthStops);
|
|
3190
|
+
if (stopKeys.length < 2) {
|
|
3191
|
+
throw new Error(`${prefix}: lineWidthStops must have at least 2 entries`);
|
|
3192
|
+
}
|
|
3193
|
+
for (const key of stopKeys) {
|
|
3194
|
+
const zoom = Number(key);
|
|
3195
|
+
if (!Number.isInteger(zoom) || zoom < 0) {
|
|
3196
|
+
throw new Error(`${prefix}: lineWidthStops keys must be non-negative integers, got "${key}"`);
|
|
3197
|
+
}
|
|
3198
|
+
if (typeof lineWidthStops[key] !== "number" || lineWidthStops[key] <= 0) {
|
|
3199
|
+
throw new Error(`${prefix}: lineWidthStops values must be positive numbers`);
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3114
3203
|
var LineStyle2 = class _LineStyle2 {
|
|
3115
3204
|
/**
|
|
3116
3205
|
* Validate a LineStyle configuration object.
|
|
3117
3206
|
* @param {Object} obj - The object to validate
|
|
3118
3207
|
* @param {number} [index] - Optional index for error messages (when validating in an array)
|
|
3208
|
+
* @param {boolean} [requireLineWidthStops=false] - Whether lineWidthStops is required
|
|
3119
3209
|
* @throws {Error} If validation fails
|
|
3120
3210
|
*/
|
|
3121
|
-
static validateJSON(obj, index) {
|
|
3211
|
+
static validateJSON(obj, index, requireLineWidthStops = false) {
|
|
3122
3212
|
const prefix = index !== void 0 ? `lineStyles[${index}]` : "LineStyle";
|
|
3123
3213
|
if (!obj || typeof obj !== "object") {
|
|
3124
3214
|
throw new Error(`${prefix}: must be an object`);
|
|
@@ -3153,22 +3243,30 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3153
3243
|
if (obj.delWidthFactor !== void 0 && (typeof obj.delWidthFactor !== "number" || obj.delWidthFactor < 0)) {
|
|
3154
3244
|
throw new Error(`${prefix}: delWidthFactor must be a non-negative number`);
|
|
3155
3245
|
}
|
|
3246
|
+
if (requireLineWidthStops && obj.lineWidthStops === void 0) {
|
|
3247
|
+
throw new Error(`${prefix}: lineWidthStops is required`);
|
|
3248
|
+
}
|
|
3249
|
+
if (obj.lineWidthStops !== void 0) {
|
|
3250
|
+
validateLineWidthStops2(obj.lineWidthStops, prefix);
|
|
3251
|
+
}
|
|
3156
3252
|
}
|
|
3157
3253
|
/**
|
|
3158
3254
|
* @param {Object} options
|
|
3159
3255
|
* @param {string} options.color - CSS color string
|
|
3160
3256
|
* @param {string} options.layerSuffix - Layer suffix (e.g., 'osm', 'ne', 'osm-disp')
|
|
3257
|
+
* @param {Object<number, number>} options.lineWidthStops - Line width stops for this style
|
|
3161
3258
|
* @param {number} [options.widthFraction=1.0] - Multiplier for base line width
|
|
3162
3259
|
* @param {number[]} [options.dashArray] - Dash pattern for dashed lines
|
|
3163
3260
|
* @param {number} [options.alpha=1.0] - Opacity (0-1)
|
|
3164
3261
|
* @param {number} [options.startZoom=0] - Minimum zoom level for this style
|
|
3165
3262
|
* @param {number} [options.endZoom=INFINITY] - Maximum zoom level for this style (INFINITY means no limit)
|
|
3166
|
-
* @param {number} [options.lineExtensionFactor=0.
|
|
3263
|
+
* @param {number} [options.lineExtensionFactor=0.0] - Factor to extend lines by (multiplied by deletion line width)
|
|
3167
3264
|
* @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
|
|
3168
3265
|
*/
|
|
3169
|
-
constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY2, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
3266
|
+
constructor({ color, layerSuffix, lineWidthStops, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY2, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
3170
3267
|
this.color = color;
|
|
3171
3268
|
this.layerSuffix = layerSuffix;
|
|
3269
|
+
this.lineWidthStops = lineWidthStops;
|
|
3172
3270
|
this.widthFraction = widthFraction;
|
|
3173
3271
|
this.dashArray = dashArray;
|
|
3174
3272
|
this.alpha = alpha;
|
|
@@ -3177,6 +3275,14 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3177
3275
|
this.lineExtensionFactor = lineExtensionFactor;
|
|
3178
3276
|
this.delWidthFactor = delWidthFactor;
|
|
3179
3277
|
}
|
|
3278
|
+
/**
|
|
3279
|
+
* Get base line width for this style at a given zoom level.
|
|
3280
|
+
* @param {number} zoom - Zoom level
|
|
3281
|
+
* @returns {number}
|
|
3282
|
+
*/
|
|
3283
|
+
getLineWidth(zoom) {
|
|
3284
|
+
return interpolateLineWidth2(zoom, this.lineWidthStops);
|
|
3285
|
+
}
|
|
3180
3286
|
/**
|
|
3181
3287
|
* Check if this style is active at the given zoom level.
|
|
3182
3288
|
* @param {number} z - Zoom level
|
|
@@ -3193,6 +3299,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3193
3299
|
return {
|
|
3194
3300
|
color: this.color,
|
|
3195
3301
|
layerSuffix: this.layerSuffix,
|
|
3302
|
+
lineWidthStops: this.lineWidthStops,
|
|
3196
3303
|
widthFraction: this.widthFraction,
|
|
3197
3304
|
dashArray: this.dashArray,
|
|
3198
3305
|
alpha: this.alpha,
|
|
@@ -3209,7 +3316,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3209
3316
|
* @returns {LineStyle}
|
|
3210
3317
|
*/
|
|
3211
3318
|
static fromJSON(obj, index) {
|
|
3212
|
-
_LineStyle2.validateJSON(obj, index);
|
|
3319
|
+
_LineStyle2.validateJSON(obj, index, true);
|
|
3213
3320
|
return new _LineStyle2(obj);
|
|
3214
3321
|
}
|
|
3215
3322
|
};
|
|
@@ -3275,9 +3382,13 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3275
3382
|
this._compiledPatterns = templates.map((t) => templateToRegex2(t));
|
|
3276
3383
|
this._templatePatterns = templates.map((t) => templateToTemplateRegex2(t));
|
|
3277
3384
|
this.lineWidthStops = lineWidthStops;
|
|
3278
|
-
this.lineStyles = lineStyles.map(
|
|
3279
|
-
(style
|
|
3280
|
-
|
|
3385
|
+
this.lineStyles = lineStyles.map((style) => {
|
|
3386
|
+
if (style instanceof LineStyle2) {
|
|
3387
|
+
return style;
|
|
3388
|
+
}
|
|
3389
|
+
const styleWithStops = style.lineWidthStops ? style : { ...style, lineWidthStops };
|
|
3390
|
+
return new LineStyle2(styleWithStops);
|
|
3391
|
+
});
|
|
3281
3392
|
}
|
|
3282
3393
|
/**
|
|
3283
3394
|
* Get line styles active at a given zoom level
|
|
@@ -3296,45 +3407,6 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3296
3407
|
const activeStyles = this.getLineStylesForZoom(z2);
|
|
3297
3408
|
return [...new Set(activeStyles.map((s) => s.layerSuffix))];
|
|
3298
3409
|
}
|
|
3299
|
-
/**
|
|
3300
|
-
* Interpolate or extrapolate line width for a given zoom level.
|
|
3301
|
-
* Uses the lineWidthStops map to calculate the appropriate width.
|
|
3302
|
-
* @param {number} zoom - Zoom level
|
|
3303
|
-
* @returns {number}
|
|
3304
|
-
*/
|
|
3305
|
-
getLineWidth(zoom) {
|
|
3306
|
-
const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
3307
|
-
if (this.lineWidthStops[zoom] !== void 0) {
|
|
3308
|
-
return this.lineWidthStops[zoom];
|
|
3309
|
-
}
|
|
3310
|
-
if (zoom < zooms[0]) {
|
|
3311
|
-
const z1 = zooms[0];
|
|
3312
|
-
const z2 = zooms[1];
|
|
3313
|
-
const w1 = this.lineWidthStops[z1];
|
|
3314
|
-
const w2 = this.lineWidthStops[z2];
|
|
3315
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
3316
|
-
return Math.max(MIN_LINE_WIDTH2, w1 + slope * (zoom - z1));
|
|
3317
|
-
}
|
|
3318
|
-
if (zoom > zooms[zooms.length - 1]) {
|
|
3319
|
-
const z1 = zooms[zooms.length - 2];
|
|
3320
|
-
const z2 = zooms[zooms.length - 1];
|
|
3321
|
-
const w1 = this.lineWidthStops[z1];
|
|
3322
|
-
const w2 = this.lineWidthStops[z2];
|
|
3323
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
3324
|
-
return Math.max(MIN_LINE_WIDTH2, w2 + slope * (zoom - z2));
|
|
3325
|
-
}
|
|
3326
|
-
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
3327
|
-
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
3328
|
-
const z1 = zooms[i2];
|
|
3329
|
-
const z2 = zooms[i2 + 1];
|
|
3330
|
-
const w1 = this.lineWidthStops[z1];
|
|
3331
|
-
const w2 = this.lineWidthStops[z2];
|
|
3332
|
-
const t = (zoom - z1) / (z2 - z1);
|
|
3333
|
-
return w1 + t * (w2 - w1);
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
return DEFAULT_LINE_WIDTH2;
|
|
3337
|
-
}
|
|
3338
3410
|
/**
|
|
3339
3411
|
* Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
|
|
3340
3412
|
* @param {string | string[]} templates - Single template URL or array of template URLs
|
|
@@ -3810,12 +3882,13 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3810
3882
|
const canvas = this._canvas;
|
|
3811
3883
|
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
3812
3884
|
ctx.drawImage(imageBitmap, 0, 0, tileSize, tileSize);
|
|
3813
|
-
const baseLineWidth = layerConfig.getLineWidth(zoom);
|
|
3814
3885
|
const delLineWidthBySuffix = {};
|
|
3815
3886
|
for (const suffix of layerSuffixes) {
|
|
3816
3887
|
const stylesForSuffix = activeLineStyles.filter((s) => s.layerSuffix === suffix);
|
|
3817
|
-
const
|
|
3818
|
-
|
|
3888
|
+
const maxDelWidth = Math.max(...stylesForSuffix.map(
|
|
3889
|
+
(s) => s.getLineWidth(zoom) * s.widthFraction * s.delWidthFactor
|
|
3890
|
+
));
|
|
3891
|
+
delLineWidthBySuffix[suffix] = maxDelWidth;
|
|
3819
3892
|
}
|
|
3820
3893
|
for (const suffix of layerSuffixes) {
|
|
3821
3894
|
const delLineWidth = delLineWidthBySuffix[suffix];
|
|
@@ -3830,7 +3903,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3830
3903
|
}
|
|
3831
3904
|
}
|
|
3832
3905
|
for (const style of activeLineStyles) {
|
|
3833
|
-
const { color,
|
|
3906
|
+
const { color, widthFraction, dashArray, alpha, lineExtensionFactor, layerSuffix } = style;
|
|
3834
3907
|
const addLayerName = `to-add-${layerSuffix}`;
|
|
3835
3908
|
let addFeatures = corrections[addLayerName] || [];
|
|
3836
3909
|
if (addFeatures.length > 0) {
|
|
@@ -3838,7 +3911,7 @@ var IndiaBoundaryCorrector = (() => {
|
|
|
3838
3911
|
if (lineExtensionFactor > 0) {
|
|
3839
3912
|
addFeatures = extendFeaturesByFactor(addFeatures, lineExtensionFactor, delLineWidth, tileSize);
|
|
3840
3913
|
}
|
|
3841
|
-
const lineWidth =
|
|
3914
|
+
const lineWidth = style.getLineWidth(zoom) * widthFraction;
|
|
3842
3915
|
drawFeatures(ctx, addFeatures, color, lineWidth, tileSize, dashArray, alpha);
|
|
3843
3916
|
}
|
|
3844
3917
|
}
|