@india-boundary-corrector/openlayers-layer 0.0.3 → 0.0.5
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 +23 -6
- package/dist/index.cjs +36 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +1926 -815
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +37 -72
- package/dist/index.js.map +1 -1
- package/dist/india_boundary_corrections.pmtiles +0 -0
- package/dist/india_boundary_corrections.pmtiles.gz +0 -0
- package/package.json +4 -4
- package/src/index.d.ts +4 -2
- package/src/index.js +52 -104
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ No bundler required! Just include the script and use the global `IndiaBoundaryCo
|
|
|
21
21
|
```html
|
|
22
22
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@10.3.1/ol.css">
|
|
23
23
|
<script src="https://cdn.jsdelivr.net/npm/ol@10.3.1/dist/ol.js"></script>
|
|
24
|
-
<script src="https://
|
|
24
|
+
<script src="https://cdn.jsdelivr.net/npm/@india-boundary-corrector/openlayers-layer/dist/index.global.js"></script>
|
|
25
25
|
|
|
26
26
|
<div id="map" style="height: 400px;"></div>
|
|
27
27
|
|
|
@@ -77,7 +77,10 @@ import { IndiaBoundaryCorrectedTileLayer } from '@india-boundary-corrector/openl
|
|
|
77
77
|
|
|
78
78
|
const layer = new IndiaBoundaryCorrectedTileLayer({
|
|
79
79
|
url: 'https://{a-c}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
|
|
80
|
-
layerConfig: 'cartodb-dark'
|
|
80
|
+
layerConfig: 'cartodb-dark',
|
|
81
|
+
sourceOptions: {
|
|
82
|
+
attributions: '© CARTO © OpenStreetMap contributors'
|
|
83
|
+
}
|
|
81
84
|
});
|
|
82
85
|
```
|
|
83
86
|
|
|
@@ -98,13 +101,19 @@ const osmDeConfig = new LayerConfig({
|
|
|
98
101
|
|
|
99
102
|
const layer = new IndiaBoundaryCorrectedTileLayer({
|
|
100
103
|
url: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png',
|
|
101
|
-
layerConfig: osmDeConfig
|
|
104
|
+
layerConfig: osmDeConfig,
|
|
105
|
+
sourceOptions: {
|
|
106
|
+
attributions: '© OpenStreetMap contributors'
|
|
107
|
+
}
|
|
102
108
|
});
|
|
103
109
|
|
|
104
110
|
// Or use extraLayerConfigs for auto-detection
|
|
105
111
|
const layer2 = new IndiaBoundaryCorrectedTileLayer({
|
|
106
112
|
url: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png',
|
|
107
|
-
extraLayerConfigs: [osmDeConfig]
|
|
113
|
+
extraLayerConfigs: [osmDeConfig],
|
|
114
|
+
sourceOptions: {
|
|
115
|
+
attributions: '© OpenStreetMap contributors'
|
|
116
|
+
}
|
|
108
117
|
});
|
|
109
118
|
```
|
|
110
119
|
|
|
@@ -114,7 +123,10 @@ const layer2 = new IndiaBoundaryCorrectedTileLayer({
|
|
|
114
123
|
import { indiaBoundaryCorrectedTileLayer } from '@india-boundary-corrector/openlayers-layer';
|
|
115
124
|
|
|
116
125
|
const layer = indiaBoundaryCorrectedTileLayer({
|
|
117
|
-
url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
|
126
|
+
url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
127
|
+
sourceOptions: {
|
|
128
|
+
attributions: '© OpenStreetMap contributors'
|
|
129
|
+
}
|
|
118
130
|
});
|
|
119
131
|
```
|
|
120
132
|
|
|
@@ -126,7 +138,8 @@ const layer = indiaBoundaryCorrectedTileLayer({
|
|
|
126
138
|
| `pmtilesUrl` | string | URL to PMTiles file (auto-detected if not provided) |
|
|
127
139
|
| `layerConfig` | LayerConfig \| string | Layer config object or config ID |
|
|
128
140
|
| `extraLayerConfigs` | LayerConfig[] | Additional configs for auto-detection |
|
|
129
|
-
| `tileSize` | number | Tile size in pixels (default: 256) |
|
|
141
|
+
| `tileSize` | number | Tile size in pixels for OpenLayers source (default: 256) |
|
|
142
|
+
| `fallbackOnCorrectionFailure` | boolean | Return original tile if corrections fail (default: true) |
|
|
130
143
|
| `sourceOptions` | Object | Additional options passed to XYZ source |
|
|
131
144
|
| `...layerOptions` | Object | Additional options passed to TileLayer |
|
|
132
145
|
|
|
@@ -158,6 +171,10 @@ layer.on('correctionerror', (e) => {
|
|
|
158
171
|
| `coords` | object | Tile coordinates `{ z, x, y }` |
|
|
159
172
|
| `tileUrl` | string | URL of the tile being loaded |
|
|
160
173
|
|
|
174
|
+
## Bundling
|
|
175
|
+
|
|
176
|
+
If you're bundling your application (Rollup, Webpack, Vite, etc.), you may need to copy the PMTiles data file to your output directory. See **[Bundling the PMTiles Asset](../data/bundling-pmtiles.md)** for instructions.
|
|
177
|
+
|
|
161
178
|
## License
|
|
162
179
|
|
|
163
180
|
Unlicense
|
package/dist/index.cjs
CHANGED
|
@@ -32,70 +32,42 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
IndiaBoundaryCorrectedTileLayer: () => IndiaBoundaryCorrectedTileLayer,
|
|
34
34
|
LayerConfig: () => import_layer_configs2.LayerConfig,
|
|
35
|
-
fetchAndFixTile: () => fetchAndFixTile,
|
|
36
35
|
getPmtilesUrl: () => import_data2.getPmtilesUrl,
|
|
37
36
|
indiaBoundaryCorrectedTileLayer: () => indiaBoundaryCorrectedTileLayer,
|
|
38
37
|
layerConfigs: () => import_layer_configs2.layerConfigs
|
|
39
38
|
});
|
|
40
39
|
module.exports = __toCommonJS(index_exports);
|
|
41
40
|
var import_Tile = __toESM(require("ol/layer/Tile.js"), 1);
|
|
42
|
-
var
|
|
41
|
+
var import_ImageTile = __toESM(require("ol/source/ImageTile.js"), 1);
|
|
43
42
|
var import_data = require("@india-boundary-corrector/data");
|
|
44
43
|
var import_layer_configs = require("@india-boundary-corrector/layer-configs");
|
|
45
44
|
var import_tilefixer = require("@india-boundary-corrector/tilefixer");
|
|
46
45
|
var import_layer_configs2 = require("@india-boundary-corrector/layer-configs");
|
|
47
46
|
var import_data2 = require("@india-boundary-corrector/data");
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
src,
|
|
51
|
-
z,
|
|
52
|
-
x,
|
|
53
|
-
y,
|
|
54
|
-
layerConfig,
|
|
55
|
-
{ tileSize, mode: "cors" }
|
|
56
|
-
);
|
|
57
|
-
const blob = new Blob([data], { type: wasFixed ? "image/png" : void 0 });
|
|
58
|
-
return { blob, wasFixed, correctionsFailed, correctionsError };
|
|
59
|
-
}
|
|
60
|
-
function createCorrectedTileLoadFunction(tileFixer, layerConfig, tileSize, layer) {
|
|
61
|
-
return async function(imageTile, src) {
|
|
62
|
-
const tileCoord = imageTile.getTileCoord();
|
|
63
|
-
const z = tileCoord[0];
|
|
64
|
-
const x = tileCoord[1];
|
|
65
|
-
const y = tileCoord[2];
|
|
47
|
+
function createCorrectedTileLoader(urlTemplate, tileFixer, layerConfig, layerRef, fetchOptions, fallbackOnCorrectionFailure) {
|
|
48
|
+
return async function(z, x, y, { signal }) {
|
|
49
|
+
const src = urlTemplate.replace("{z}", z).replace("{x}", x).replace("{y}", y);
|
|
66
50
|
try {
|
|
67
|
-
const {
|
|
68
|
-
|
|
51
|
+
const { data, correctionsFailed, correctionsError } = await tileFixer.fetchAndFixTile(
|
|
52
|
+
src,
|
|
53
|
+
z,
|
|
54
|
+
x,
|
|
55
|
+
y,
|
|
56
|
+
layerConfig,
|
|
57
|
+
{ signal, ...fetchOptions },
|
|
58
|
+
fallbackOnCorrectionFailure
|
|
59
|
+
);
|
|
60
|
+
if (correctionsFailed && layerRef.current) {
|
|
69
61
|
console.warn("[IndiaBoundaryCorrectedTileLayer] Corrections fetch failed:", correctionsError);
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
const image = imageTile.getImage();
|
|
73
|
-
if (typeof image.getContext === "function") {
|
|
74
|
-
const imageBitmap = await createImageBitmap(blob);
|
|
75
|
-
image.width = imageBitmap.width;
|
|
76
|
-
image.height = imageBitmap.height;
|
|
77
|
-
const ctx = image.getContext("2d");
|
|
78
|
-
ctx.drawImage(imageBitmap, 0, 0);
|
|
79
|
-
imageBitmap.close?.();
|
|
80
|
-
image.dispatchEvent(new Event("load"));
|
|
81
|
-
} else {
|
|
82
|
-
const blobUrl = URL.createObjectURL(blob);
|
|
83
|
-
image.onload = () => {
|
|
84
|
-
URL.revokeObjectURL(blobUrl);
|
|
85
|
-
};
|
|
86
|
-
image.onerror = () => {
|
|
87
|
-
URL.revokeObjectURL(blobUrl);
|
|
88
|
-
};
|
|
89
|
-
image.src = blobUrl;
|
|
62
|
+
layerRef.current.dispatchEvent({ type: "correctionerror", error: correctionsError, coords: { z, x, y }, tileUrl: src });
|
|
90
63
|
}
|
|
64
|
+
const blob = new Blob([data]);
|
|
65
|
+
return createImageBitmap(blob);
|
|
91
66
|
} catch (err) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (typeof image.src !== "undefined") {
|
|
95
|
-
image.src = src;
|
|
96
|
-
} else if (typeof image.dispatchEvent === "function") {
|
|
97
|
-
image.dispatchEvent(new Event("error"));
|
|
67
|
+
if (err.name !== "AbortError") {
|
|
68
|
+
console.warn("[IndiaBoundaryCorrectedTileLayer] Tile fetch failed:", err);
|
|
98
69
|
}
|
|
70
|
+
throw err;
|
|
99
71
|
}
|
|
100
72
|
};
|
|
101
73
|
}
|
|
@@ -106,8 +78,11 @@ var IndiaBoundaryCorrectedTileLayer = class extends import_Tile.default {
|
|
|
106
78
|
* @param {string} [options.pmtilesUrl] - URL to PMTiles file (defaults to CDN)
|
|
107
79
|
* @param {Object|string} [options.layerConfig] - LayerConfig or config ID (auto-detected if not provided)
|
|
108
80
|
* @param {Object[]} [options.extraLayerConfigs] - Additional LayerConfigs for matching
|
|
109
|
-
* @param {number} [options.tileSize=256] - Tile size in pixels
|
|
110
|
-
* @param {
|
|
81
|
+
* @param {number} [options.tileSize=256] - Tile size in pixels (for OpenLayers source)
|
|
82
|
+
* @param {boolean} [options.fallbackOnCorrectionFailure=true] - Return original tile if corrections fail
|
|
83
|
+
* @param {Object} [options.sourceOptions] - Additional options for ImageTile source
|
|
84
|
+
* @param {string} [options.sourceOptions.crossOrigin] - Cross-origin attribute ('anonymous' or 'use-credentials')
|
|
85
|
+
* @param {string} [options.sourceOptions.referrerPolicy] - Referrer policy for fetch requests
|
|
111
86
|
* @param {Object} [options.layerOptions] - Additional options for TileLayer
|
|
112
87
|
*/
|
|
113
88
|
constructor(options) {
|
|
@@ -117,6 +92,7 @@ var IndiaBoundaryCorrectedTileLayer = class extends import_Tile.default {
|
|
|
117
92
|
layerConfig,
|
|
118
93
|
extraLayerConfigs,
|
|
119
94
|
tileSize = 256,
|
|
95
|
+
fallbackOnCorrectionFailure = true,
|
|
120
96
|
sourceOptions = {},
|
|
121
97
|
...layerOptions
|
|
122
98
|
} = options;
|
|
@@ -129,23 +105,25 @@ var IndiaBoundaryCorrectedTileLayer = class extends import_Tile.default {
|
|
|
129
105
|
} else {
|
|
130
106
|
resolvedConfig = registry.detectFromTemplates([url]);
|
|
131
107
|
}
|
|
132
|
-
const tileFixer =
|
|
133
|
-
const
|
|
134
|
-
|
|
108
|
+
const tileFixer = import_tilefixer.TileFixer.getOrCreate(pmtilesUrl ?? (0, import_data.getPmtilesUrl)());
|
|
109
|
+
const crossOrigin = sourceOptions.crossOrigin ?? "anonymous";
|
|
110
|
+
const fetchOptions = (0, import_tilefixer.buildFetchOptions)(crossOrigin, sourceOptions.referrerPolicy);
|
|
111
|
+
const layerRef = { current: null };
|
|
112
|
+
const source = new import_ImageTile.default({
|
|
135
113
|
tileSize,
|
|
136
|
-
crossOrigin
|
|
137
|
-
...sourceOptions
|
|
114
|
+
crossOrigin,
|
|
115
|
+
...sourceOptions,
|
|
116
|
+
loader: resolvedConfig ? createCorrectedTileLoader(url, tileFixer, resolvedConfig, layerRef, fetchOptions, fallbackOnCorrectionFailure) : void 0,
|
|
117
|
+
url: resolvedConfig ? void 0 : url
|
|
138
118
|
});
|
|
139
119
|
super({
|
|
140
120
|
source,
|
|
141
121
|
...layerOptions
|
|
142
122
|
});
|
|
123
|
+
layerRef.current = this;
|
|
143
124
|
this._tileFixer = tileFixer;
|
|
144
125
|
this._layerConfig = resolvedConfig;
|
|
145
126
|
this._registry = registry;
|
|
146
|
-
if (resolvedConfig) {
|
|
147
|
-
source.setTileLoadFunction(createCorrectedTileLoadFunction(tileFixer, resolvedConfig, tileSize, this));
|
|
148
|
-
}
|
|
149
127
|
if (!resolvedConfig) {
|
|
150
128
|
console.warn("[IndiaBoundaryCorrectedTileLayer] Could not detect layer config from URL. Corrections will not be applied.");
|
|
151
129
|
}
|
|
@@ -171,19 +149,6 @@ var IndiaBoundaryCorrectedTileLayer = class extends import_Tile.default {
|
|
|
171
149
|
getRegistry() {
|
|
172
150
|
return this._registry;
|
|
173
151
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Fetch and fix a tile (exposed for testing).
|
|
176
|
-
* @param {string} src - Tile URL
|
|
177
|
-
* @param {number} z - Zoom level
|
|
178
|
-
* @param {number} x - Tile X coordinate
|
|
179
|
-
* @param {number} y - Tile Y coordinate
|
|
180
|
-
* @returns {Promise<{blob: Blob, wasFixed: boolean}>}
|
|
181
|
-
* @private
|
|
182
|
-
*/
|
|
183
|
-
async _fetchAndFixTile(src, z, x, y) {
|
|
184
|
-
const tileSize = this.getSource().getTileGrid()?.getTileSize(z) || 256;
|
|
185
|
-
return fetchAndFixTile(src, z, x, y, this._tileFixer, this._layerConfig, tileSize);
|
|
186
|
-
}
|
|
187
152
|
};
|
|
188
153
|
function indiaBoundaryCorrectedTileLayer(options) {
|
|
189
154
|
return new IndiaBoundaryCorrectedTileLayer(options);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"sourcesContent":["import TileLayer from 'ol/layer/Tile.js';\nimport XYZ from 'ol/source/XYZ.js';\nimport { getPmtilesUrl } from '@india-boundary-corrector/data';\nimport { layerConfigs } from '@india-boundary-corrector/layer-configs';\nimport { BoundaryCorrector as TileFixer } from '@india-boundary-corrector/tilefixer';\n\n// Re-export for convenience\nexport { layerConfigs, LayerConfig } from '@india-boundary-corrector/layer-configs';\nexport { getPmtilesUrl } from '@india-boundary-corrector/data';\n\n/**\n * Handle tile fetching and correction application logic.\n * This method is extracted for testability.\n * @param {string} src - URL of the raster tile\n * @param {number} z - Zoom level\n * @param {number} x - Tile X coordinate\n * @param {number} y - Tile Y coordinate\n * @param {TileFixer} tileFixer - TileFixer instance\n * @param {Object} layerConfig - Layer configuration\n * @param {number} tileSize - Tile size in pixels\n * @returns {Promise<{blob: Blob, wasFixed: boolean, correctionsFailed: boolean, correctionsError: Error|null}>}\n */\nasync function fetchAndFixTile(src, z, x, y, tileFixer, layerConfig, tileSize) {\n const { data, wasFixed, correctionsFailed, correctionsError } = await tileFixer.fetchAndFixTile(\n src, z, x, y, layerConfig, { tileSize, mode: 'cors' }\n );\n const blob = new Blob([data], { type: wasFixed ? 'image/png' : undefined });\n return { blob, wasFixed, correctionsFailed, correctionsError };\n}\n\n/**\n * Create a custom tileLoadFunction that applies boundary corrections.\n * @param {TileFixer} tileFixer - The TileFixer instance\n * @param {Object} layerConfig - The layer configuration\n * @param {number} tileSize - Tile size in pixels\n * @param {IndiaBoundaryCorrectedTileLayer} layer - The layer instance for event dispatching\n * @returns {Function} Custom tile load function\n */\nfunction createCorrectedTileLoadFunction(tileFixer, layerConfig, tileSize, layer) {\n return async function(imageTile, src) {\n const tileCoord = imageTile.getTileCoord();\n const z = tileCoord[0];\n const x = tileCoord[1];\n const y = tileCoord[2];\n\n // TODO: Pass AbortSignal to fetchAndFixTile to cancel in-flight requests when tiles\n // go off-screen. OpenLayers' tileLoadFunction doesn't provide an AbortController,\n // so this would require custom tracking. Deferred due to complexity - will revisit\n // if performance becomes an issue during rapid panning.\n try {\n const { blob, correctionsFailed, correctionsError } = await fetchAndFixTile(src, z, x, y, tileFixer, layerConfig, tileSize);\n\n if (correctionsFailed) {\n // TODO: If abort is implemented, check for AbortError here and skip emitting correctionerror\n console.warn('[IndiaBoundaryCorrectedTileLayer] Corrections fetch failed:', correctionsError);\n layer.dispatchEvent({ type: 'correctionerror', error: correctionsError, coords: { z, x, y }, tileUrl: src });\n }\n\n const image = imageTile.getImage();\n \n // Check if image is a canvas (OffscreenCanvas) or HTMLImageElement\n if (typeof image.getContext === 'function') {\n // OffscreenCanvas path\n const imageBitmap = await createImageBitmap(blob);\n image.width = imageBitmap.width;\n image.height = imageBitmap.height;\n const ctx = image.getContext('2d');\n ctx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close?.();\n image.dispatchEvent(new Event('load'));\n } else {\n // HTMLImageElement path - use blob URL\n const blobUrl = URL.createObjectURL(blob);\n image.onload = () => {\n URL.revokeObjectURL(blobUrl);\n };\n image.onerror = () => {\n URL.revokeObjectURL(blobUrl);\n };\n image.src = blobUrl;\n }\n } catch (err) {\n // Don't emit correctionerror for tile fetch/processing errors - only for PMTiles failures (handled above)\n console.warn('[IndiaBoundaryCorrectedTileLayer] Tile fetch failed:', err);\n // Fall back to original tile\n const image = imageTile.getImage();\n if (typeof image.src !== 'undefined') {\n // HTMLImageElement - load original tile\n image.src = src;\n } else if (typeof image.dispatchEvent === 'function') {\n // OffscreenCanvas - can't fall back, signal error\n image.dispatchEvent(new Event('error'));\n }\n }\n };\n}\n\n/**\n * Extended OpenLayers TileLayer with India boundary corrections.\n * Extends ol/layer/Tile with a custom XYZ source that applies corrections.\n */\nexport class IndiaBoundaryCorrectedTileLayer extends TileLayer {\n /**\n * @param {Object} options - Layer options\n * @param {string} options.url - Tile URL template with {x}, {y}, {z} placeholders\n * @param {string} [options.pmtilesUrl] - URL to PMTiles file (defaults to CDN)\n * @param {Object|string} [options.layerConfig] - LayerConfig or config ID (auto-detected if not provided)\n * @param {Object[]} [options.extraLayerConfigs] - Additional LayerConfigs for matching\n * @param {number} [options.tileSize=256] - Tile size in pixels\n * @param {Object} [options.sourceOptions] - Additional options for XYZ source\n * @param {Object} [options.layerOptions] - Additional options for TileLayer\n */\n constructor(options) {\n const {\n url,\n pmtilesUrl,\n layerConfig,\n extraLayerConfigs,\n tileSize = 256,\n sourceOptions = {},\n ...layerOptions\n } = options;\n\n // Initialize registry and resolve layer config\n const registry = layerConfigs.createMergedRegistry(extraLayerConfigs);\n let resolvedConfig;\n \n if (typeof layerConfig === 'string') {\n resolvedConfig = registry.get(layerConfig);\n } else if (layerConfig) {\n resolvedConfig = layerConfig;\n } else {\n // Auto-detect from URL\n resolvedConfig = registry.detectFromTemplates([url]);\n }\n\n // Create TileFixer\n const tileFixer = new TileFixer(pmtilesUrl ?? getPmtilesUrl());\n\n // Create XYZ source (tileLoadFunction set after super() to access 'this')\n const source = new XYZ({\n url,\n tileSize,\n crossOrigin: 'anonymous',\n ...sourceOptions,\n });\n\n super({\n source,\n ...layerOptions\n });\n\n this._tileFixer = tileFixer;\n this._layerConfig = resolvedConfig;\n this._registry = registry;\n\n // Set tileLoadFunction after super() so we can pass 'this' for event dispatching\n if (resolvedConfig) {\n source.setTileLoadFunction(createCorrectedTileLoadFunction(tileFixer, resolvedConfig, tileSize, this));\n }\n\n if (!resolvedConfig) {\n console.warn('[IndiaBoundaryCorrectedTileLayer] Could not detect layer config from URL. Corrections will not be applied.');\n }\n }\n\n /**\n * Get the TileFixer instance.\n * @returns {TileFixer}\n */\n getTileFixer() {\n return this._tileFixer;\n }\n\n /**\n * Get the resolved LayerConfig.\n * @returns {Object|null}\n */\n getLayerConfig() {\n return this._layerConfig;\n }\n\n /**\n * Get the registry.\n * @returns {LayerConfigRegistry}\n */\n getRegistry() {\n return this._registry;\n }\n\n /**\n * Fetch and fix a tile (exposed for testing).\n * @param {string} src - Tile URL\n * @param {number} z - Zoom level\n * @param {number} x - Tile X coordinate\n * @param {number} y - Tile Y coordinate\n * @returns {Promise<{blob: Blob, wasFixed: boolean}>}\n * @private\n */\n async _fetchAndFixTile(src, z, x, y) {\n const tileSize = this.getSource().getTileGrid()?.getTileSize(z) || 256;\n return fetchAndFixTile(src, z, x, y, this._tileFixer, this._layerConfig, tileSize);\n }\n}\n\n// Export for testing\nexport { fetchAndFixTile };\n\n/**\n * Factory function to create an IndiaBoundaryCorrectedTileLayer.\n * @param {Object} options - Layer options (see IndiaBoundaryCorrectedTileLayer constructor)\n * @returns {IndiaBoundaryCorrectedTileLayer}\n */\nexport function indiaBoundaryCorrectedTileLayer(options) {\n return new IndiaBoundaryCorrectedTileLayer(options);\n}\n"],"mappings":"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","names":["import_layer_configs","import_data","TileLayer","TileFixer","XYZ"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"sourcesContent":["import TileLayer from 'ol/layer/Tile.js';\nimport ImageTile from 'ol/source/ImageTile.js';\nimport { getPmtilesUrl } from '@india-boundary-corrector/data';\nimport { layerConfigs } from '@india-boundary-corrector/layer-configs';\nimport { TileFixer, buildFetchOptions } from '@india-boundary-corrector/tilefixer';\n\n// Re-export for convenience\nexport { layerConfigs, LayerConfig } from '@india-boundary-corrector/layer-configs';\nexport { getPmtilesUrl } from '@india-boundary-corrector/data';\n\n/**\n * Create a tile loader function that applies boundary corrections.\n * Uses the modern OpenLayers loader API with abort signal support.\n * @param {string} urlTemplate - URL template with {x}, {y}, {z} placeholders\n * @param {TileFixer} tileFixer - The TileFixer instance\n * @param {Object} layerConfig - The layer configuration\n * @param {{current: IndiaBoundaryCorrectedTileLayer}} layerRef - Reference to layer instance for event dispatching\n * @param {Object} fetchOptions - Fetch options (mode, credentials)\n * @param {boolean} fallbackOnCorrectionFailure - Whether to return original tile if corrections fail\n * @returns {Function} Tile loader function\n */\nfunction createCorrectedTileLoader(urlTemplate, tileFixer, layerConfig, layerRef, fetchOptions, fallbackOnCorrectionFailure) {\n return async function(z, x, y, { signal }) {\n const src = urlTemplate\n .replace('{z}', z)\n .replace('{x}', x)\n .replace('{y}', y);\n\n try {\n const { data, correctionsFailed, correctionsError } = await tileFixer.fetchAndFixTile(\n src, z, x, y, layerConfig, { signal, ...fetchOptions }, fallbackOnCorrectionFailure\n );\n\n if (correctionsFailed && layerRef.current) {\n console.warn('[IndiaBoundaryCorrectedTileLayer] Corrections fetch failed:', correctionsError);\n layerRef.current.dispatchEvent({ type: 'correctionerror', error: correctionsError, coords: { z, x, y }, tileUrl: src });\n }\n\n const blob = new Blob([data]);\n return createImageBitmap(blob);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.warn('[IndiaBoundaryCorrectedTileLayer] Tile fetch failed:', err);\n }\n throw err;\n }\n };\n}\n\n/**\n * Extended OpenLayers TileLayer with India boundary corrections.\n * Uses ol/source/ImageTile with a custom loader that applies corrections.\n */\nexport class IndiaBoundaryCorrectedTileLayer extends TileLayer {\n /**\n * @param {Object} options - Layer options\n * @param {string} options.url - Tile URL template with {x}, {y}, {z} placeholders\n * @param {string} [options.pmtilesUrl] - URL to PMTiles file (defaults to CDN)\n * @param {Object|string} [options.layerConfig] - LayerConfig or config ID (auto-detected if not provided)\n * @param {Object[]} [options.extraLayerConfigs] - Additional LayerConfigs for matching\n * @param {number} [options.tileSize=256] - Tile size in pixels (for OpenLayers source)\n * @param {boolean} [options.fallbackOnCorrectionFailure=true] - Return original tile if corrections fail\n * @param {Object} [options.sourceOptions] - Additional options for ImageTile source\n * @param {string} [options.sourceOptions.crossOrigin] - Cross-origin attribute ('anonymous' or 'use-credentials')\n * @param {string} [options.sourceOptions.referrerPolicy] - Referrer policy for fetch requests\n * @param {Object} [options.layerOptions] - Additional options for TileLayer\n */\n constructor(options) {\n const {\n url,\n pmtilesUrl,\n layerConfig,\n extraLayerConfigs,\n tileSize = 256,\n fallbackOnCorrectionFailure = true,\n sourceOptions = {},\n ...layerOptions\n } = options;\n\n // Initialize registry and resolve layer config\n const registry = layerConfigs.createMergedRegistry(extraLayerConfigs);\n let resolvedConfig;\n \n if (typeof layerConfig === 'string') {\n resolvedConfig = registry.get(layerConfig);\n } else if (layerConfig) {\n resolvedConfig = layerConfig;\n } else {\n // Auto-detect from URL\n resolvedConfig = registry.detectFromTemplates([url]);\n }\n\n // Create TileFixer\n const tileFixer = TileFixer.getOrCreate(pmtilesUrl ?? getPmtilesUrl());\n\n // Derive fetch options from crossOrigin (matches OpenLayers behavior)\n // Default to 'anonymous' if not specified in sourceOptions\n const crossOrigin = sourceOptions.crossOrigin ?? 'anonymous';\n const fetchOptions = buildFetchOptions(crossOrigin, sourceOptions.referrerPolicy);\n\n // Create a placeholder for the layer instance (needed for event dispatching in loader)\n const layerRef = { current: null };\n\n // Create ImageTile source with loader (supports abort signals)\n const source = new ImageTile({\n tileSize,\n crossOrigin,\n ...sourceOptions,\n loader: resolvedConfig\n ? createCorrectedTileLoader(url, tileFixer, resolvedConfig, layerRef, fetchOptions, fallbackOnCorrectionFailure)\n : undefined,\n url: resolvedConfig ? undefined : url,\n });\n\n super({\n source,\n ...layerOptions\n });\n\n // Set the layer reference for event dispatching\n layerRef.current = this;\n\n this._tileFixer = tileFixer;\n this._layerConfig = resolvedConfig;\n this._registry = registry;\n\n if (!resolvedConfig) {\n console.warn('[IndiaBoundaryCorrectedTileLayer] Could not detect layer config from URL. Corrections will not be applied.');\n }\n }\n\n /**\n * Get the TileFixer instance.\n * @returns {TileFixer}\n */\n getTileFixer() {\n return this._tileFixer;\n }\n\n /**\n * Get the resolved LayerConfig.\n * @returns {Object|null}\n */\n getLayerConfig() {\n return this._layerConfig;\n }\n\n /**\n * Get the registry.\n * @returns {LayerConfigRegistry}\n */\n getRegistry() {\n return this._registry;\n }\n}\n\n/**\n * Factory function to create an IndiaBoundaryCorrectedTileLayer.\n * @param {Object} options - Layer options (see IndiaBoundaryCorrectedTileLayer constructor)\n * @returns {IndiaBoundaryCorrectedTileLayer}\n */\nexport function indiaBoundaryCorrectedTileLayer(options) {\n return new IndiaBoundaryCorrectedTileLayer(options);\n}\n"],"mappings":"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","names":["import_layer_configs","import_data","TileLayer","ImageTile"]}
|