@india-boundary-corrector/leaflet-layer 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.cjs +190 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +191 -118
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +190 -117
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -86,12 +86,11 @@ var configs_default = [
|
|
|
86
86
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
|
|
87
87
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
|
|
88
88
|
],
|
|
89
|
-
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.
|
|
89
|
+
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.75, "16": 2.5 },
|
|
90
90
|
lineStyles: [
|
|
91
91
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
92
92
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
93
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.
|
|
94
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
93
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 9, "10": 8, "14": 8 }, lineExtensionFactor: 0.1 },
|
|
95
94
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
96
95
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
97
96
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
|
|
@@ -114,12 +113,11 @@ var configs_default = [
|
|
|
114
113
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
|
|
115
114
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
|
|
116
115
|
],
|
|
117
|
-
lineWidthStops: { "1":
|
|
116
|
+
lineWidthStops: { "1": 1, "3": 1, "4": 2, "5": 2, "6": 2.5, "7": 3, "8": 3, "10": 4, "11": 4, "12": 4 },
|
|
118
117
|
lineStyles: [
|
|
119
118
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
120
119
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
121
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6,
|
|
122
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
120
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 20, "8": 19, "10": 18, "12": 17 }, lineExtensionFactor: 0.1 },
|
|
123
121
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
124
122
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
125
123
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
|
|
@@ -130,15 +128,20 @@ var configs_default = [
|
|
|
130
128
|
id: "open-topo",
|
|
131
129
|
tileUrlTemplates: [
|
|
132
130
|
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
133
|
-
"https://tile.opentopomap.org/{z}/{x}/{y}.png"
|
|
131
|
+
"https://tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
132
|
+
"https://{s}.tile.top-o-map.de/{z}/{x}/{y}.png",
|
|
133
|
+
"https://tile.top-o-map.de/{z}/{x}/{y}.png"
|
|
134
134
|
],
|
|
135
135
|
lineWidthStops: { "4": 0.75, "5": 1, "6": 1.25, "7": 1.5, "8": 1.75, "9": 1.25, "10": 1.25, "13": 1.5 },
|
|
136
136
|
lineStyles: [
|
|
137
137
|
{ color: "rgb(83, 83, 83)", layerSuffix: "ne", startZoom: 4, endZoom: 6 },
|
|
138
138
|
{ color: "rgb(173, 173, 173)", layerSuffix: "osm", startZoom: 7, endZoom: 8, alpha: 0.5, widthFraction: 4 },
|
|
139
139
|
{ color: "rgb(83, 83, 83)", layerSuffix: "osm", startZoom: 7, endZoom: 8 },
|
|
140
|
+
{ color: "rgb(83, 83, 83)", layerSuffix: "osm-internal", widthFraction: 0.75, startZoom: 7, endZoom: 8 },
|
|
140
141
|
{ color: "rgb(199, 158, 204)", layerSuffix: "osm", startZoom: 9, widthFraction: 7, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
141
|
-
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 }
|
|
142
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 },
|
|
143
|
+
{ color: "rgb(199, 158, 204)", layerSuffix: "osm-internal", startZoom: 9, widthFraction: 2.25, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
144
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm-internal", startZoom: 9, widthFactor: 0.75, lineExtensionFactor: 0.2 }
|
|
142
145
|
]
|
|
143
146
|
},
|
|
144
147
|
{
|
|
@@ -147,9 +150,8 @@ var configs_default = [
|
|
|
147
150
|
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
148
151
|
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
149
152
|
],
|
|
150
|
-
lineWidthStops: { "
|
|
153
|
+
lineWidthStops: { "3": 0.7, "4": 1, "10": 3.75 },
|
|
151
154
|
lineStyles: [
|
|
152
|
-
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
|
|
153
155
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
|
|
154
156
|
{ color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
|
|
155
157
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
|
|
@@ -173,6 +175,39 @@ var configs_default = [
|
|
|
173
175
|
var INFINITY = -1;
|
|
174
176
|
var MIN_LINE_WIDTH = 0.1;
|
|
175
177
|
var DEFAULT_LINE_WIDTH = 1;
|
|
178
|
+
function interpolateLineWidth(zoom, lineWidthStops) {
|
|
179
|
+
const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
180
|
+
if (lineWidthStops[zoom] !== void 0) {
|
|
181
|
+
return lineWidthStops[zoom];
|
|
182
|
+
}
|
|
183
|
+
if (zoom < zooms[0]) {
|
|
184
|
+
const z1 = zooms[0];
|
|
185
|
+
const z2 = zooms[1];
|
|
186
|
+
const w1 = lineWidthStops[z1];
|
|
187
|
+
const w2 = lineWidthStops[z2];
|
|
188
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
189
|
+
return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
|
|
190
|
+
}
|
|
191
|
+
if (zoom > zooms[zooms.length - 1]) {
|
|
192
|
+
const z1 = zooms[zooms.length - 2];
|
|
193
|
+
const z2 = zooms[zooms.length - 1];
|
|
194
|
+
const w1 = lineWidthStops[z1];
|
|
195
|
+
const w2 = lineWidthStops[z2];
|
|
196
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
197
|
+
return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
|
|
198
|
+
}
|
|
199
|
+
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
200
|
+
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
201
|
+
const z1 = zooms[i2];
|
|
202
|
+
const z2 = zooms[i2 + 1];
|
|
203
|
+
const w1 = lineWidthStops[z1];
|
|
204
|
+
const w2 = lineWidthStops[z2];
|
|
205
|
+
const t = (zoom - z1) / (z2 - z1);
|
|
206
|
+
return w1 + t * (w2 - w1);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return DEFAULT_LINE_WIDTH;
|
|
210
|
+
}
|
|
176
211
|
function templateToRegex(template) {
|
|
177
212
|
const groups = [];
|
|
178
213
|
const hasRetina = template.includes("{r}");
|
|
@@ -239,14 +274,33 @@ function isValidColor(color) {
|
|
|
239
274
|
if (/^[a-z]+$/.test(trimmed)) return true;
|
|
240
275
|
return false;
|
|
241
276
|
}
|
|
277
|
+
function validateLineWidthStops(lineWidthStops, prefix) {
|
|
278
|
+
if (!lineWidthStops || typeof lineWidthStops !== "object" || Array.isArray(lineWidthStops)) {
|
|
279
|
+
throw new Error(`${prefix}: lineWidthStops must be an object`);
|
|
280
|
+
}
|
|
281
|
+
const stopKeys = Object.keys(lineWidthStops);
|
|
282
|
+
if (stopKeys.length < 2) {
|
|
283
|
+
throw new Error(`${prefix}: lineWidthStops must have at least 2 entries`);
|
|
284
|
+
}
|
|
285
|
+
for (const key of stopKeys) {
|
|
286
|
+
const zoom = Number(key);
|
|
287
|
+
if (!Number.isInteger(zoom) || zoom < 0) {
|
|
288
|
+
throw new Error(`${prefix}: lineWidthStops keys must be non-negative integers, got "${key}"`);
|
|
289
|
+
}
|
|
290
|
+
if (typeof lineWidthStops[key] !== "number" || lineWidthStops[key] <= 0) {
|
|
291
|
+
throw new Error(`${prefix}: lineWidthStops values must be positive numbers`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
242
295
|
var LineStyle = class _LineStyle {
|
|
243
296
|
/**
|
|
244
297
|
* Validate a LineStyle configuration object.
|
|
245
298
|
* @param {Object} obj - The object to validate
|
|
246
299
|
* @param {number} [index] - Optional index for error messages (when validating in an array)
|
|
300
|
+
* @param {boolean} [requireLineWidthStops=false] - Whether lineWidthStops is required
|
|
247
301
|
* @throws {Error} If validation fails
|
|
248
302
|
*/
|
|
249
|
-
static validateJSON(obj, index) {
|
|
303
|
+
static validateJSON(obj, index, requireLineWidthStops = false) {
|
|
250
304
|
const prefix = index !== void 0 ? `lineStyles[${index}]` : "LineStyle";
|
|
251
305
|
if (!obj || typeof obj !== "object") {
|
|
252
306
|
throw new Error(`${prefix}: must be an object`);
|
|
@@ -281,22 +335,30 @@ var LineStyle = class _LineStyle {
|
|
|
281
335
|
if (obj.delWidthFactor !== void 0 && (typeof obj.delWidthFactor !== "number" || obj.delWidthFactor < 0)) {
|
|
282
336
|
throw new Error(`${prefix}: delWidthFactor must be a non-negative number`);
|
|
283
337
|
}
|
|
338
|
+
if (requireLineWidthStops && obj.lineWidthStops === void 0) {
|
|
339
|
+
throw new Error(`${prefix}: lineWidthStops is required`);
|
|
340
|
+
}
|
|
341
|
+
if (obj.lineWidthStops !== void 0) {
|
|
342
|
+
validateLineWidthStops(obj.lineWidthStops, prefix);
|
|
343
|
+
}
|
|
284
344
|
}
|
|
285
345
|
/**
|
|
286
346
|
* @param {Object} options
|
|
287
347
|
* @param {string} options.color - CSS color string
|
|
288
348
|
* @param {string} options.layerSuffix - Layer suffix (e.g., 'osm', 'ne', 'osm-disp')
|
|
349
|
+
* @param {Object<number, number>} options.lineWidthStops - Line width stops for this style
|
|
289
350
|
* @param {number} [options.widthFraction=1.0] - Multiplier for base line width
|
|
290
351
|
* @param {number[]} [options.dashArray] - Dash pattern for dashed lines
|
|
291
352
|
* @param {number} [options.alpha=1.0] - Opacity (0-1)
|
|
292
353
|
* @param {number} [options.startZoom=0] - Minimum zoom level for this style
|
|
293
354
|
* @param {number} [options.endZoom=INFINITY] - Maximum zoom level for this style (INFINITY means no limit)
|
|
294
|
-
* @param {number} [options.lineExtensionFactor=0.
|
|
355
|
+
* @param {number} [options.lineExtensionFactor=0.0] - Factor to extend lines by (multiplied by deletion line width)
|
|
295
356
|
* @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
|
|
296
357
|
*/
|
|
297
|
-
constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
358
|
+
constructor({ color, layerSuffix, lineWidthStops, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
298
359
|
this.color = color;
|
|
299
360
|
this.layerSuffix = layerSuffix;
|
|
361
|
+
this.lineWidthStops = lineWidthStops;
|
|
300
362
|
this.widthFraction = widthFraction;
|
|
301
363
|
this.dashArray = dashArray;
|
|
302
364
|
this.alpha = alpha;
|
|
@@ -305,6 +367,14 @@ var LineStyle = class _LineStyle {
|
|
|
305
367
|
this.lineExtensionFactor = lineExtensionFactor;
|
|
306
368
|
this.delWidthFactor = delWidthFactor;
|
|
307
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Get base line width for this style at a given zoom level.
|
|
372
|
+
* @param {number} zoom - Zoom level
|
|
373
|
+
* @returns {number}
|
|
374
|
+
*/
|
|
375
|
+
getLineWidth(zoom) {
|
|
376
|
+
return interpolateLineWidth(zoom, this.lineWidthStops);
|
|
377
|
+
}
|
|
308
378
|
/**
|
|
309
379
|
* Check if this style is active at the given zoom level.
|
|
310
380
|
* @param {number} z - Zoom level
|
|
@@ -321,6 +391,7 @@ var LineStyle = class _LineStyle {
|
|
|
321
391
|
return {
|
|
322
392
|
color: this.color,
|
|
323
393
|
layerSuffix: this.layerSuffix,
|
|
394
|
+
lineWidthStops: this.lineWidthStops,
|
|
324
395
|
widthFraction: this.widthFraction,
|
|
325
396
|
dashArray: this.dashArray,
|
|
326
397
|
alpha: this.alpha,
|
|
@@ -337,7 +408,7 @@ var LineStyle = class _LineStyle {
|
|
|
337
408
|
* @returns {LineStyle}
|
|
338
409
|
*/
|
|
339
410
|
static fromJSON(obj, index) {
|
|
340
|
-
_LineStyle.validateJSON(obj, index);
|
|
411
|
+
_LineStyle.validateJSON(obj, index, true);
|
|
341
412
|
return new _LineStyle(obj);
|
|
342
413
|
}
|
|
343
414
|
};
|
|
@@ -403,9 +474,13 @@ var LayerConfig = class _LayerConfig {
|
|
|
403
474
|
this._compiledPatterns = templates.map((t) => templateToRegex(t));
|
|
404
475
|
this._templatePatterns = templates.map((t) => templateToTemplateRegex(t));
|
|
405
476
|
this.lineWidthStops = lineWidthStops;
|
|
406
|
-
this.lineStyles = lineStyles.map(
|
|
407
|
-
(style
|
|
408
|
-
|
|
477
|
+
this.lineStyles = lineStyles.map((style) => {
|
|
478
|
+
if (style instanceof LineStyle) {
|
|
479
|
+
return style;
|
|
480
|
+
}
|
|
481
|
+
const styleWithStops = style.lineWidthStops ? style : { ...style, lineWidthStops };
|
|
482
|
+
return new LineStyle(styleWithStops);
|
|
483
|
+
});
|
|
409
484
|
}
|
|
410
485
|
/**
|
|
411
486
|
* Get line styles active at a given zoom level
|
|
@@ -424,45 +499,6 @@ var LayerConfig = class _LayerConfig {
|
|
|
424
499
|
const activeStyles = this.getLineStylesForZoom(z2);
|
|
425
500
|
return [...new Set(activeStyles.map((s) => s.layerSuffix))];
|
|
426
501
|
}
|
|
427
|
-
/**
|
|
428
|
-
* Interpolate or extrapolate line width for a given zoom level.
|
|
429
|
-
* Uses the lineWidthStops map to calculate the appropriate width.
|
|
430
|
-
* @param {number} zoom - Zoom level
|
|
431
|
-
* @returns {number}
|
|
432
|
-
*/
|
|
433
|
-
getLineWidth(zoom) {
|
|
434
|
-
const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
435
|
-
if (this.lineWidthStops[zoom] !== void 0) {
|
|
436
|
-
return this.lineWidthStops[zoom];
|
|
437
|
-
}
|
|
438
|
-
if (zoom < zooms[0]) {
|
|
439
|
-
const z1 = zooms[0];
|
|
440
|
-
const z2 = zooms[1];
|
|
441
|
-
const w1 = this.lineWidthStops[z1];
|
|
442
|
-
const w2 = this.lineWidthStops[z2];
|
|
443
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
444
|
-
return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
|
|
445
|
-
}
|
|
446
|
-
if (zoom > zooms[zooms.length - 1]) {
|
|
447
|
-
const z1 = zooms[zooms.length - 2];
|
|
448
|
-
const z2 = zooms[zooms.length - 1];
|
|
449
|
-
const w1 = this.lineWidthStops[z1];
|
|
450
|
-
const w2 = this.lineWidthStops[z2];
|
|
451
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
452
|
-
return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
|
|
453
|
-
}
|
|
454
|
-
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
455
|
-
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
456
|
-
const z1 = zooms[i2];
|
|
457
|
-
const z2 = zooms[i2 + 1];
|
|
458
|
-
const w1 = this.lineWidthStops[z1];
|
|
459
|
-
const w2 = this.lineWidthStops[z2];
|
|
460
|
-
const t = (zoom - z1) / (z2 - z1);
|
|
461
|
-
return w1 + t * (w2 - w1);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return DEFAULT_LINE_WIDTH;
|
|
465
|
-
}
|
|
466
502
|
/**
|
|
467
503
|
* Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
|
|
468
504
|
* @param {string | string[]} templates - Single template URL or array of template URLs
|
|
@@ -2916,12 +2952,11 @@ var configs_default2 = [
|
|
|
2916
2952
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
|
|
2917
2953
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
|
|
2918
2954
|
],
|
|
2919
|
-
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.
|
|
2955
|
+
lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.75, "16": 2.5 },
|
|
2920
2956
|
lineStyles: [
|
|
2921
2957
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
2922
2958
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
2923
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.
|
|
2924
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
2959
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 9, "10": 8, "14": 8 }, lineExtensionFactor: 0.1 },
|
|
2925
2960
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
2926
2961
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
2927
2962
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
|
|
@@ -2944,12 +2979,11 @@ var configs_default2 = [
|
|
|
2944
2979
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
|
|
2945
2980
|
"https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
|
|
2946
2981
|
],
|
|
2947
|
-
lineWidthStops: { "1":
|
|
2982
|
+
lineWidthStops: { "1": 1, "3": 1, "4": 2, "5": 2, "6": 2.5, "7": 3, "8": 3, "10": 4, "11": 4, "12": 4 },
|
|
2948
2983
|
lineStyles: [
|
|
2949
2984
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
|
|
2950
2985
|
{ color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
|
|
2951
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6,
|
|
2952
|
-
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
|
|
2986
|
+
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, lineWidthStops: { "6": 20, "8": 19, "10": 18, "12": 17 }, lineExtensionFactor: 0.1 },
|
|
2953
2987
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
|
|
2954
2988
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
|
|
2955
2989
|
{ color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
|
|
@@ -2960,15 +2994,20 @@ var configs_default2 = [
|
|
|
2960
2994
|
id: "open-topo",
|
|
2961
2995
|
tileUrlTemplates: [
|
|
2962
2996
|
"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
2963
|
-
"https://tile.opentopomap.org/{z}/{x}/{y}.png"
|
|
2997
|
+
"https://tile.opentopomap.org/{z}/{x}/{y}.png",
|
|
2998
|
+
"https://{s}.tile.top-o-map.de/{z}/{x}/{y}.png",
|
|
2999
|
+
"https://tile.top-o-map.de/{z}/{x}/{y}.png"
|
|
2964
3000
|
],
|
|
2965
3001
|
lineWidthStops: { "4": 0.75, "5": 1, "6": 1.25, "7": 1.5, "8": 1.75, "9": 1.25, "10": 1.25, "13": 1.5 },
|
|
2966
3002
|
lineStyles: [
|
|
2967
3003
|
{ color: "rgb(83, 83, 83)", layerSuffix: "ne", startZoom: 4, endZoom: 6 },
|
|
2968
3004
|
{ color: "rgb(173, 173, 173)", layerSuffix: "osm", startZoom: 7, endZoom: 8, alpha: 0.5, widthFraction: 4 },
|
|
2969
3005
|
{ color: "rgb(83, 83, 83)", layerSuffix: "osm", startZoom: 7, endZoom: 8 },
|
|
3006
|
+
{ color: "rgb(83, 83, 83)", layerSuffix: "osm-internal", widthFraction: 0.75, startZoom: 7, endZoom: 8 },
|
|
2970
3007
|
{ color: "rgb(199, 158, 204)", layerSuffix: "osm", startZoom: 9, widthFraction: 7, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
2971
|
-
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 }
|
|
3008
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm", startZoom: 9, lineExtensionFactor: 0.2 },
|
|
3009
|
+
{ color: "rgb(199, 158, 204)", layerSuffix: "osm-internal", startZoom: 9, widthFraction: 2.25, alpha: 0.6, lineExtensionFactor: 0.2 },
|
|
3010
|
+
{ color: "rgb(175, 41, 203)", layerSuffix: "osm-internal", startZoom: 9, widthFactor: 0.75, lineExtensionFactor: 0.2 }
|
|
2972
3011
|
]
|
|
2973
3012
|
},
|
|
2974
3013
|
{
|
|
@@ -2977,9 +3016,8 @@ var configs_default2 = [
|
|
|
2977
3016
|
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
2978
3017
|
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
2979
3018
|
],
|
|
2980
|
-
lineWidthStops: { "
|
|
3019
|
+
lineWidthStops: { "3": 0.7, "4": 1, "10": 3.75 },
|
|
2981
3020
|
lineStyles: [
|
|
2982
|
-
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
|
|
2983
3021
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
|
|
2984
3022
|
{ color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
|
|
2985
3023
|
{ color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
|
|
@@ -3003,6 +3041,39 @@ var configs_default2 = [
|
|
|
3003
3041
|
var INFINITY2 = -1;
|
|
3004
3042
|
var MIN_LINE_WIDTH2 = 0.1;
|
|
3005
3043
|
var DEFAULT_LINE_WIDTH2 = 1;
|
|
3044
|
+
function interpolateLineWidth2(zoom, lineWidthStops) {
|
|
3045
|
+
const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
3046
|
+
if (lineWidthStops[zoom] !== void 0) {
|
|
3047
|
+
return lineWidthStops[zoom];
|
|
3048
|
+
}
|
|
3049
|
+
if (zoom < zooms[0]) {
|
|
3050
|
+
const z1 = zooms[0];
|
|
3051
|
+
const z2 = zooms[1];
|
|
3052
|
+
const w1 = lineWidthStops[z1];
|
|
3053
|
+
const w2 = lineWidthStops[z2];
|
|
3054
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
3055
|
+
return Math.max(MIN_LINE_WIDTH2, w1 + slope * (zoom - z1));
|
|
3056
|
+
}
|
|
3057
|
+
if (zoom > zooms[zooms.length - 1]) {
|
|
3058
|
+
const z1 = zooms[zooms.length - 2];
|
|
3059
|
+
const z2 = zooms[zooms.length - 1];
|
|
3060
|
+
const w1 = lineWidthStops[z1];
|
|
3061
|
+
const w2 = lineWidthStops[z2];
|
|
3062
|
+
const slope = (w2 - w1) / (z2 - z1);
|
|
3063
|
+
return Math.max(MIN_LINE_WIDTH2, w2 + slope * (zoom - z2));
|
|
3064
|
+
}
|
|
3065
|
+
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
3066
|
+
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
3067
|
+
const z1 = zooms[i2];
|
|
3068
|
+
const z2 = zooms[i2 + 1];
|
|
3069
|
+
const w1 = lineWidthStops[z1];
|
|
3070
|
+
const w2 = lineWidthStops[z2];
|
|
3071
|
+
const t = (zoom - z1) / (z2 - z1);
|
|
3072
|
+
return w1 + t * (w2 - w1);
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
return DEFAULT_LINE_WIDTH2;
|
|
3076
|
+
}
|
|
3006
3077
|
function templateToRegex2(template) {
|
|
3007
3078
|
const groups = [];
|
|
3008
3079
|
const hasRetina = template.includes("{r}");
|
|
@@ -3069,14 +3140,33 @@ function isValidColor2(color) {
|
|
|
3069
3140
|
if (/^[a-z]+$/.test(trimmed)) return true;
|
|
3070
3141
|
return false;
|
|
3071
3142
|
}
|
|
3143
|
+
function validateLineWidthStops2(lineWidthStops, prefix) {
|
|
3144
|
+
if (!lineWidthStops || typeof lineWidthStops !== "object" || Array.isArray(lineWidthStops)) {
|
|
3145
|
+
throw new Error(`${prefix}: lineWidthStops must be an object`);
|
|
3146
|
+
}
|
|
3147
|
+
const stopKeys = Object.keys(lineWidthStops);
|
|
3148
|
+
if (stopKeys.length < 2) {
|
|
3149
|
+
throw new Error(`${prefix}: lineWidthStops must have at least 2 entries`);
|
|
3150
|
+
}
|
|
3151
|
+
for (const key of stopKeys) {
|
|
3152
|
+
const zoom = Number(key);
|
|
3153
|
+
if (!Number.isInteger(zoom) || zoom < 0) {
|
|
3154
|
+
throw new Error(`${prefix}: lineWidthStops keys must be non-negative integers, got "${key}"`);
|
|
3155
|
+
}
|
|
3156
|
+
if (typeof lineWidthStops[key] !== "number" || lineWidthStops[key] <= 0) {
|
|
3157
|
+
throw new Error(`${prefix}: lineWidthStops values must be positive numbers`);
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3072
3161
|
var LineStyle2 = class _LineStyle2 {
|
|
3073
3162
|
/**
|
|
3074
3163
|
* Validate a LineStyle configuration object.
|
|
3075
3164
|
* @param {Object} obj - The object to validate
|
|
3076
3165
|
* @param {number} [index] - Optional index for error messages (when validating in an array)
|
|
3166
|
+
* @param {boolean} [requireLineWidthStops=false] - Whether lineWidthStops is required
|
|
3077
3167
|
* @throws {Error} If validation fails
|
|
3078
3168
|
*/
|
|
3079
|
-
static validateJSON(obj, index) {
|
|
3169
|
+
static validateJSON(obj, index, requireLineWidthStops = false) {
|
|
3080
3170
|
const prefix = index !== void 0 ? `lineStyles[${index}]` : "LineStyle";
|
|
3081
3171
|
if (!obj || typeof obj !== "object") {
|
|
3082
3172
|
throw new Error(`${prefix}: must be an object`);
|
|
@@ -3111,22 +3201,30 @@ var LineStyle2 = class _LineStyle2 {
|
|
|
3111
3201
|
if (obj.delWidthFactor !== void 0 && (typeof obj.delWidthFactor !== "number" || obj.delWidthFactor < 0)) {
|
|
3112
3202
|
throw new Error(`${prefix}: delWidthFactor must be a non-negative number`);
|
|
3113
3203
|
}
|
|
3204
|
+
if (requireLineWidthStops && obj.lineWidthStops === void 0) {
|
|
3205
|
+
throw new Error(`${prefix}: lineWidthStops is required`);
|
|
3206
|
+
}
|
|
3207
|
+
if (obj.lineWidthStops !== void 0) {
|
|
3208
|
+
validateLineWidthStops2(obj.lineWidthStops, prefix);
|
|
3209
|
+
}
|
|
3114
3210
|
}
|
|
3115
3211
|
/**
|
|
3116
3212
|
* @param {Object} options
|
|
3117
3213
|
* @param {string} options.color - CSS color string
|
|
3118
3214
|
* @param {string} options.layerSuffix - Layer suffix (e.g., 'osm', 'ne', 'osm-disp')
|
|
3215
|
+
* @param {Object<number, number>} options.lineWidthStops - Line width stops for this style
|
|
3119
3216
|
* @param {number} [options.widthFraction=1.0] - Multiplier for base line width
|
|
3120
3217
|
* @param {number[]} [options.dashArray] - Dash pattern for dashed lines
|
|
3121
3218
|
* @param {number} [options.alpha=1.0] - Opacity (0-1)
|
|
3122
3219
|
* @param {number} [options.startZoom=0] - Minimum zoom level for this style
|
|
3123
3220
|
* @param {number} [options.endZoom=INFINITY] - Maximum zoom level for this style (INFINITY means no limit)
|
|
3124
|
-
* @param {number} [options.lineExtensionFactor=0.
|
|
3221
|
+
* @param {number} [options.lineExtensionFactor=0.0] - Factor to extend lines by (multiplied by deletion line width)
|
|
3125
3222
|
* @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
|
|
3126
3223
|
*/
|
|
3127
|
-
constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY2, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
3224
|
+
constructor({ color, layerSuffix, lineWidthStops, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY2, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
|
|
3128
3225
|
this.color = color;
|
|
3129
3226
|
this.layerSuffix = layerSuffix;
|
|
3227
|
+
this.lineWidthStops = lineWidthStops;
|
|
3130
3228
|
this.widthFraction = widthFraction;
|
|
3131
3229
|
this.dashArray = dashArray;
|
|
3132
3230
|
this.alpha = alpha;
|
|
@@ -3135,6 +3233,14 @@ var LineStyle2 = class _LineStyle2 {
|
|
|
3135
3233
|
this.lineExtensionFactor = lineExtensionFactor;
|
|
3136
3234
|
this.delWidthFactor = delWidthFactor;
|
|
3137
3235
|
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Get base line width for this style at a given zoom level.
|
|
3238
|
+
* @param {number} zoom - Zoom level
|
|
3239
|
+
* @returns {number}
|
|
3240
|
+
*/
|
|
3241
|
+
getLineWidth(zoom) {
|
|
3242
|
+
return interpolateLineWidth2(zoom, this.lineWidthStops);
|
|
3243
|
+
}
|
|
3138
3244
|
/**
|
|
3139
3245
|
* Check if this style is active at the given zoom level.
|
|
3140
3246
|
* @param {number} z - Zoom level
|
|
@@ -3151,6 +3257,7 @@ var LineStyle2 = class _LineStyle2 {
|
|
|
3151
3257
|
return {
|
|
3152
3258
|
color: this.color,
|
|
3153
3259
|
layerSuffix: this.layerSuffix,
|
|
3260
|
+
lineWidthStops: this.lineWidthStops,
|
|
3154
3261
|
widthFraction: this.widthFraction,
|
|
3155
3262
|
dashArray: this.dashArray,
|
|
3156
3263
|
alpha: this.alpha,
|
|
@@ -3167,7 +3274,7 @@ var LineStyle2 = class _LineStyle2 {
|
|
|
3167
3274
|
* @returns {LineStyle}
|
|
3168
3275
|
*/
|
|
3169
3276
|
static fromJSON(obj, index) {
|
|
3170
|
-
_LineStyle2.validateJSON(obj, index);
|
|
3277
|
+
_LineStyle2.validateJSON(obj, index, true);
|
|
3171
3278
|
return new _LineStyle2(obj);
|
|
3172
3279
|
}
|
|
3173
3280
|
};
|
|
@@ -3233,9 +3340,13 @@ var LayerConfig2 = class _LayerConfig2 {
|
|
|
3233
3340
|
this._compiledPatterns = templates.map((t) => templateToRegex2(t));
|
|
3234
3341
|
this._templatePatterns = templates.map((t) => templateToTemplateRegex2(t));
|
|
3235
3342
|
this.lineWidthStops = lineWidthStops;
|
|
3236
|
-
this.lineStyles = lineStyles.map(
|
|
3237
|
-
(style
|
|
3238
|
-
|
|
3343
|
+
this.lineStyles = lineStyles.map((style) => {
|
|
3344
|
+
if (style instanceof LineStyle2) {
|
|
3345
|
+
return style;
|
|
3346
|
+
}
|
|
3347
|
+
const styleWithStops = style.lineWidthStops ? style : { ...style, lineWidthStops };
|
|
3348
|
+
return new LineStyle2(styleWithStops);
|
|
3349
|
+
});
|
|
3239
3350
|
}
|
|
3240
3351
|
/**
|
|
3241
3352
|
* Get line styles active at a given zoom level
|
|
@@ -3254,45 +3365,6 @@ var LayerConfig2 = class _LayerConfig2 {
|
|
|
3254
3365
|
const activeStyles = this.getLineStylesForZoom(z2);
|
|
3255
3366
|
return [...new Set(activeStyles.map((s) => s.layerSuffix))];
|
|
3256
3367
|
}
|
|
3257
|
-
/**
|
|
3258
|
-
* Interpolate or extrapolate line width for a given zoom level.
|
|
3259
|
-
* Uses the lineWidthStops map to calculate the appropriate width.
|
|
3260
|
-
* @param {number} zoom - Zoom level
|
|
3261
|
-
* @returns {number}
|
|
3262
|
-
*/
|
|
3263
|
-
getLineWidth(zoom) {
|
|
3264
|
-
const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
|
|
3265
|
-
if (this.lineWidthStops[zoom] !== void 0) {
|
|
3266
|
-
return this.lineWidthStops[zoom];
|
|
3267
|
-
}
|
|
3268
|
-
if (zoom < zooms[0]) {
|
|
3269
|
-
const z1 = zooms[0];
|
|
3270
|
-
const z2 = zooms[1];
|
|
3271
|
-
const w1 = this.lineWidthStops[z1];
|
|
3272
|
-
const w2 = this.lineWidthStops[z2];
|
|
3273
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
3274
|
-
return Math.max(MIN_LINE_WIDTH2, w1 + slope * (zoom - z1));
|
|
3275
|
-
}
|
|
3276
|
-
if (zoom > zooms[zooms.length - 1]) {
|
|
3277
|
-
const z1 = zooms[zooms.length - 2];
|
|
3278
|
-
const z2 = zooms[zooms.length - 1];
|
|
3279
|
-
const w1 = this.lineWidthStops[z1];
|
|
3280
|
-
const w2 = this.lineWidthStops[z2];
|
|
3281
|
-
const slope = (w2 - w1) / (z2 - z1);
|
|
3282
|
-
return Math.max(MIN_LINE_WIDTH2, w2 + slope * (zoom - z2));
|
|
3283
|
-
}
|
|
3284
|
-
for (let i2 = 0; i2 < zooms.length - 1; i2++) {
|
|
3285
|
-
if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
|
|
3286
|
-
const z1 = zooms[i2];
|
|
3287
|
-
const z2 = zooms[i2 + 1];
|
|
3288
|
-
const w1 = this.lineWidthStops[z1];
|
|
3289
|
-
const w2 = this.lineWidthStops[z2];
|
|
3290
|
-
const t = (zoom - z1) / (z2 - z1);
|
|
3291
|
-
return w1 + t * (w2 - w1);
|
|
3292
|
-
}
|
|
3293
|
-
}
|
|
3294
|
-
return DEFAULT_LINE_WIDTH2;
|
|
3295
|
-
}
|
|
3296
3368
|
/**
|
|
3297
3369
|
* Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
|
|
3298
3370
|
* @param {string | string[]} templates - Single template URL or array of template URLs
|
|
@@ -3785,12 +3857,13 @@ var _TileFixer = class _TileFixer2 {
|
|
|
3785
3857
|
const canvas = this._canvas;
|
|
3786
3858
|
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
3787
3859
|
ctx.drawImage(imageBitmap, 0, 0, tileSize, tileSize);
|
|
3788
|
-
const baseLineWidth = layerConfig.getLineWidth(zoom);
|
|
3789
3860
|
const delLineWidthBySuffix = {};
|
|
3790
3861
|
for (const suffix of layerSuffixes) {
|
|
3791
3862
|
const stylesForSuffix = activeLineStyles.filter((s) => s.layerSuffix === suffix);
|
|
3792
|
-
const
|
|
3793
|
-
|
|
3863
|
+
const maxDelWidth = Math.max(...stylesForSuffix.map(
|
|
3864
|
+
(s) => s.getLineWidth(zoom) * s.widthFraction * s.delWidthFactor
|
|
3865
|
+
));
|
|
3866
|
+
delLineWidthBySuffix[suffix] = maxDelWidth;
|
|
3794
3867
|
}
|
|
3795
3868
|
for (const suffix of layerSuffixes) {
|
|
3796
3869
|
const delLineWidth = delLineWidthBySuffix[suffix];
|
|
@@ -3805,7 +3878,7 @@ var _TileFixer = class _TileFixer2 {
|
|
|
3805
3878
|
}
|
|
3806
3879
|
}
|
|
3807
3880
|
for (const style of activeLineStyles) {
|
|
3808
|
-
const { color,
|
|
3881
|
+
const { color, widthFraction, dashArray, alpha, lineExtensionFactor, layerSuffix } = style;
|
|
3809
3882
|
const addLayerName = `to-add-${layerSuffix}`;
|
|
3810
3883
|
let addFeatures = corrections[addLayerName] || [];
|
|
3811
3884
|
if (addFeatures.length > 0) {
|
|
@@ -3813,7 +3886,7 @@ var _TileFixer = class _TileFixer2 {
|
|
|
3813
3886
|
if (lineExtensionFactor > 0) {
|
|
3814
3887
|
addFeatures = extendFeaturesByFactor(addFeatures, lineExtensionFactor, delLineWidth, tileSize);
|
|
3815
3888
|
}
|
|
3816
|
-
const lineWidth =
|
|
3889
|
+
const lineWidth = style.getLineWidth(zoom) * widthFraction;
|
|
3817
3890
|
drawFeatures(ctx, addFeatures, color, lineWidth, tileSize, dashArray, alpha);
|
|
3818
3891
|
}
|
|
3819
3892
|
}
|