@india-boundary-corrector/tilefixer 0.1.0 → 0.2.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/dist/index.cjs CHANGED
@@ -22,11 +22,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
22
22
  // src/index.js
23
23
  var index_exports = {};
24
24
  __export(index_exports, {
25
- MIN_LINE_WIDTH: () => MIN_LINE_WIDTH,
26
25
  TileFetchError: () => TileFetchError,
27
26
  TileFixer: () => TileFixer,
28
- buildFetchOptions: () => buildFetchOptions,
29
- getLineWidth: () => getLineWidth
27
+ buildFetchOptions: () => buildFetchOptions
30
28
  });
31
29
  module.exports = __toCommonJS(index_exports);
32
30
 
@@ -2274,6 +2272,26 @@ var CorrectionsSource = class {
2274
2272
  var configs_default = [
2275
2273
  {
2276
2274
  id: "cartodb-dark",
2275
+ tileUrlTemplates: [
2276
+ "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
2277
+ "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
2278
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png",
2279
+ "https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
2280
+ "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
2281
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}.png"
2282
+ ],
2283
+ lineWidthStops: { "0": 1, "2": 1, "3": 1, "10": 2, "12": 2 },
2284
+ lineStyles: [
2285
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne", endZoom: 4 },
2286
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-disp", endZoom: 4 },
2287
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm", startZoom: 5 },
2288
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-disp", startZoom: 5 },
2289
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.3, dashArray: [2, 2], delWidthFactor: 2 },
2290
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.3, dashArray: [2, 2], delWidthFactor: 3 }
2291
+ ]
2292
+ },
2293
+ {
2294
+ id: "cartodb-dark-retina",
2277
2295
  tileUrlTemplates: [
2278
2296
  "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
2279
2297
  "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
@@ -2282,17 +2300,46 @@ var configs_default = [
2282
2300
  "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
2283
2301
  "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}{r}.png"
2284
2302
  ],
2285
- lineWidthStops: { "0": 1, "2": 1, "3": 1, "10": 2.5 },
2303
+ lineWidthStops: { "0": 1.5, "2": 1.5, "3": 1.5, "6": 2.5, "10": 3 },
2286
2304
  lineStyles: [
2287
2305
  { color: "rgb(40, 40, 40)", layerSuffix: "ne", endZoom: 4 },
2288
2306
  { color: "rgb(40, 40, 40)", layerSuffix: "ne-disp", endZoom: 4 },
2289
2307
  { color: "rgb(40, 40, 40)", layerSuffix: "osm", startZoom: 5 },
2290
2308
  { color: "rgb(40, 40, 40)", layerSuffix: "osm-disp", startZoom: 5 },
2291
- { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.3, dashArray: [2, 2] }
2309
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.3, dashArray: [4, 4], delWidthFactor: 2 },
2310
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.3, dashArray: [4, 4], delWidthFactor: 3 }
2292
2311
  ]
2293
2312
  },
2294
2313
  {
2295
2314
  id: "cartodb-light",
2315
+ tileUrlTemplates: [
2316
+ "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
2317
+ "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
2318
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",
2319
+ "https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
2320
+ "https://basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
2321
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png",
2322
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
2323
+ "https://basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
2324
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
2325
+ "https://basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
2326
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
2327
+ "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
2328
+ ],
2329
+ lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.5, "16": 2.5 },
2330
+ lineStyles: [
2331
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
2332
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
2333
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 6, endZoom: 11, widthFraction: 5, lineExtensionFactor: 0.1 },
2334
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
2335
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
2336
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
2337
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
2338
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2.5 }
2339
+ ]
2340
+ },
2341
+ {
2342
+ id: "cartodb-light-retina",
2296
2343
  tileUrlTemplates: [
2297
2344
  "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
2298
2345
  "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
@@ -2307,15 +2354,16 @@ var configs_default = [
2307
2354
  "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
2308
2355
  "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
2309
2356
  ],
2310
- lineWidthStops: { "1": 0.5, "2": 0.5, "3": 0.5, "4": 1, "5": 1.25, "7": 1.5, "16": 2.5 },
2357
+ lineWidthStops: { "1": 0.75, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.5, "11": 2 },
2311
2358
  lineStyles: [
2312
- { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2 },
2313
- { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, lineExtensionFactor: 0 },
2314
- { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 6, widthFraction: 3, lineExtensionFactor: 0.1 },
2359
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
2360
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
2361
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, endZoom: 11, widthFraction: 5, lineExtensionFactor: 0.1 },
2362
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
2315
2363
  { color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
2316
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", alpha: 0.2, startZoom: 6, widthFraction: 3, lineExtensionFactor: 0 },
2317
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, lineExtensionFactor: 0 },
2318
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.75, dashArray: [2, 2], delWidthFactor: 2 }
2364
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
2365
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
2366
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2.5 }
2319
2367
  ]
2320
2368
  },
2321
2369
  {
@@ -2342,10 +2390,10 @@ var configs_default = [
2342
2390
  lineWidthStops: { "1": 0.5, "2": 0.6, "3": 0.7, "4": 1, "10": 3.75 },
2343
2391
  lineStyles: [
2344
2392
  { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
2345
- { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4 },
2346
- { color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2] },
2393
+ { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
2394
+ { color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
2347
2395
  { color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
2348
- { color: "rgb(160, 120, 160)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.15, dashArray: [4, 2, 10] }
2396
+ { color: "rgb(160, 120, 160)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.15, dashArray: [10, 4, 2] }
2349
2397
  ]
2350
2398
  },
2351
2399
  {
@@ -2358,13 +2406,17 @@ var configs_default = [
2358
2406
  lineStyles: [
2359
2407
  { color: "rgb(149, 175, 180)", layerSuffix: "osm", lineExtensionFactor: 0.25, startZoom: 2 },
2360
2408
  { color: "rgb(89, 117, 123)", layerSuffix: "osm", widthFraction: 0.33, lineExtensionFactor: 0.25, startZoom: 2 },
2361
- { color: "rgb(172, 163, 163)", layerSuffix: "osm-internal", widthFraction: 0.33, startZoom: 4, dashArray: [7, 7, 7] }
2409
+ { color: "rgb(172, 163, 163)", layerSuffix: "osm-internal", widthFraction: 0.33, startZoom: 4, dashArray: [7, 7] }
2362
2410
  ]
2363
2411
  }
2364
2412
  ];
2365
2413
  var INFINITY = -1;
2414
+ var MIN_LINE_WIDTH = 0.1;
2415
+ var DEFAULT_LINE_WIDTH = 1;
2366
2416
  function templateToRegex(template) {
2367
2417
  const groups = [];
2418
+ const hasRetina = template.includes("{r}");
2419
+ const hasExtension = /\.(png|jpg|jpeg|webp|gif)$/i.test(template);
2368
2420
  let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
2369
2421
  if (char === "{" || char === "}") return char;
2370
2422
  return "\\" + char;
@@ -2378,13 +2430,22 @@ function templateToRegex(template) {
2378
2430
  return "([a-z0-9]+)";
2379
2431
  }
2380
2432
  if (lowerName === "r") {
2381
- return "(@\\d+x)?";
2433
+ return "(@\\d+x)";
2382
2434
  }
2383
2435
  return "(\\d+)";
2384
2436
  });
2437
+ if (!hasRetina) {
2438
+ if (hasExtension) {
2439
+ pattern = pattern.replace(/(\\\.(png|jpg|jpeg|webp|gif))/, "(?!@\\d+x)$1");
2440
+ } else {
2441
+ pattern = pattern + "(?!@\\d+x)";
2442
+ }
2443
+ }
2385
2444
  return { pattern: new RegExp("^" + pattern + "(\\?.*)?$", "i"), groups };
2386
2445
  }
2387
2446
  function templateToTemplateRegex(template) {
2447
+ const hasRetina = template.includes("{r}");
2448
+ const hasExtension = /\.(png|jpg|jpeg|webp|gif)$/i.test(template);
2388
2449
  let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
2389
2450
  if (char === "{" || char === "}") return char;
2390
2451
  return "\\" + char;
@@ -2394,10 +2455,17 @@ function templateToTemplateRegex(template) {
2394
2455
  return "(\\{s\\}|\\{[a-z0-9]-[a-z0-9]\\}|[a-z0-9]+)";
2395
2456
  }
2396
2457
  if (lowerName === "r") {
2397
- return "(\\{r\\}|@\\d+x)?";
2458
+ return "(\\{r\\}|@\\d+x)";
2398
2459
  }
2399
2460
  return `\\{${lowerName}\\}`;
2400
2461
  });
2462
+ if (!hasRetina) {
2463
+ if (hasExtension) {
2464
+ pattern = pattern.replace(/(\\\.(png|jpg|jpeg|webp|gif))/, "(?!@\\d+x|\\{r\\})$1");
2465
+ } else {
2466
+ pattern = pattern + "(?!@\\d+x|\\{r\\})";
2467
+ }
2468
+ }
2401
2469
  return new RegExp("^" + pattern + "(\\?.*)?$", "i");
2402
2470
  }
2403
2471
  function isValidColor(color) {
@@ -2466,7 +2534,7 @@ var LineStyle = class _LineStyle {
2466
2534
  * @param {number} [options.lineExtensionFactor=0.5] - Factor to extend lines by (multiplied by deletion line width)
2467
2535
  * @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
2468
2536
  */
2469
- constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0.5, delWidthFactor = 1.5 }) {
2537
+ constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
2470
2538
  this.color = color;
2471
2539
  this.layerSuffix = layerSuffix;
2472
2540
  this.widthFraction = widthFraction;
@@ -2596,6 +2664,45 @@ var LayerConfig = class _LayerConfig {
2596
2664
  const activeStyles = this.getLineStylesForZoom(z2);
2597
2665
  return [...new Set(activeStyles.map((s) => s.layerSuffix))];
2598
2666
  }
2667
+ /**
2668
+ * Interpolate or extrapolate line width for a given zoom level.
2669
+ * Uses the lineWidthStops map to calculate the appropriate width.
2670
+ * @param {number} zoom - Zoom level
2671
+ * @returns {number}
2672
+ */
2673
+ getLineWidth(zoom) {
2674
+ const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
2675
+ if (this.lineWidthStops[zoom] !== void 0) {
2676
+ return this.lineWidthStops[zoom];
2677
+ }
2678
+ if (zoom < zooms[0]) {
2679
+ const z1 = zooms[0];
2680
+ const z2 = zooms[1];
2681
+ const w1 = this.lineWidthStops[z1];
2682
+ const w2 = this.lineWidthStops[z2];
2683
+ const slope = (w2 - w1) / (z2 - z1);
2684
+ return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
2685
+ }
2686
+ if (zoom > zooms[zooms.length - 1]) {
2687
+ const z1 = zooms[zooms.length - 2];
2688
+ const z2 = zooms[zooms.length - 1];
2689
+ const w1 = this.lineWidthStops[z1];
2690
+ const w2 = this.lineWidthStops[z2];
2691
+ const slope = (w2 - w1) / (z2 - z1);
2692
+ return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
2693
+ }
2694
+ for (let i = 0; i < zooms.length - 1; i++) {
2695
+ if (zoom > zooms[i] && zoom < zooms[i + 1]) {
2696
+ const z1 = zooms[i];
2697
+ const z2 = zooms[i + 1];
2698
+ const w1 = this.lineWidthStops[z1];
2699
+ const w2 = this.lineWidthStops[z2];
2700
+ const t = (zoom - z1) / (z2 - z1);
2701
+ return w1 + t * (w2 - w1);
2702
+ }
2703
+ }
2704
+ return DEFAULT_LINE_WIDTH;
2705
+ }
2599
2706
  /**
2600
2707
  * Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
2601
2708
  * @param {string | string[]} templates - Single template URL or array of template URLs
@@ -2788,9 +2895,7 @@ var TileFetchError = class _TileFetchError extends Error {
2788
2895
  return new _TileFetchError(response.status, response.url, body);
2789
2896
  }
2790
2897
  };
2791
- var MIN_LINE_WIDTH = 0.1;
2792
2898
  var DEFAULT_TILE_EXTENT = 4096;
2793
- var DEFAULT_LINE_WIDTH = 1;
2794
2899
  function buildFetchOptions(crossOrigin, referrerPolicy) {
2795
2900
  const options = {};
2796
2901
  if (crossOrigin === "use-credentials") {
@@ -2808,39 +2913,6 @@ function buildFetchOptions(crossOrigin, referrerPolicy) {
2808
2913
  }
2809
2914
  return options;
2810
2915
  }
2811
- function getLineWidth(zoom, lineWidthStops) {
2812
- const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
2813
- if (lineWidthStops[zoom] !== void 0) {
2814
- return lineWidthStops[zoom];
2815
- }
2816
- if (zoom < zooms[0]) {
2817
- const z1 = zooms[0];
2818
- const z2 = zooms[1];
2819
- const w1 = lineWidthStops[z1];
2820
- const w2 = lineWidthStops[z2];
2821
- const slope = (w2 - w1) / (z2 - z1);
2822
- return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
2823
- }
2824
- if (zoom > zooms[zooms.length - 1]) {
2825
- const z1 = zooms[zooms.length - 2];
2826
- const z2 = zooms[zooms.length - 1];
2827
- const w1 = lineWidthStops[z1];
2828
- const w2 = lineWidthStops[z2];
2829
- const slope = (w2 - w1) / (z2 - z1);
2830
- return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
2831
- }
2832
- for (let i = 0; i < zooms.length - 1; i++) {
2833
- if (zoom > zooms[i] && zoom < zooms[i + 1]) {
2834
- const z1 = zooms[i];
2835
- const z2 = zooms[i + 1];
2836
- const w1 = lineWidthStops[z1];
2837
- const w2 = lineWidthStops[z2];
2838
- const t = (zoom - z1) / (z2 - z1);
2839
- return w1 + t * (w2 - w1);
2840
- }
2841
- }
2842
- return DEFAULT_LINE_WIDTH;
2843
- }
2844
2916
  function getFeaturesBoundingBox(features, tileSize, padding = 0) {
2845
2917
  let minX = Infinity, minY = Infinity;
2846
2918
  let maxX = -Infinity, maxY = -Infinity;
@@ -3101,7 +3173,6 @@ var _TileFixer = class _TileFixer {
3101
3173
  * @returns {Promise<ArrayBuffer>} The corrected tile as ArrayBuffer (PNG)
3102
3174
  */
3103
3175
  async fixTile(corrections, rasterTile, layerConfig, zoom) {
3104
- const { lineWidthStops } = layerConfig;
3105
3176
  let activeLineStyles;
3106
3177
  if (layerConfig.getLineStylesForZoom) {
3107
3178
  activeLineStyles = layerConfig.getLineStylesForZoom(zoom);
@@ -3126,7 +3197,7 @@ var _TileFixer = class _TileFixer {
3126
3197
  const canvas = this._canvas;
3127
3198
  const ctx = canvas.getContext("2d", { willReadFrequently: true });
3128
3199
  ctx.drawImage(imageBitmap, 0, 0, tileSize, tileSize);
3129
- const baseLineWidth = getLineWidth(zoom, lineWidthStops);
3200
+ const baseLineWidth = layerConfig.getLineWidth(zoom);
3130
3201
  const delLineWidthBySuffix = {};
3131
3202
  for (const suffix of layerSuffixes) {
3132
3203
  const stylesForSuffix = activeLineStyles.filter((s) => s.layerSuffix === suffix);