@india-boundary-corrector/leaflet-layer 0.0.1

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/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@india-boundary-corrector/leaflet-layer",
3
+ "version": "0.0.1",
4
+ "description": "Leaflet TileLayer plugin with India boundary corrections",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "src/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./src/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./src/index.d.ts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "src",
23
+ "dist"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsup"
27
+ },
28
+ "peerDependencies": {
29
+ "leaflet": ">=1.9.0"
30
+ },
31
+ "dependencies": {
32
+ "@india-boundary-corrector/data": "^0.0.1",
33
+ "@india-boundary-corrector/layer-configs": "^0.0.1",
34
+ "@india-boundary-corrector/tilefixer": "^0.0.1"
35
+ },
36
+ "keywords": [
37
+ "india",
38
+ "boundary",
39
+ "map",
40
+ "leaflet",
41
+ "tilelayer"
42
+ ],
43
+ "author": "ramSeraph",
44
+ "license": "Unlicense",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/ramSeraph/india_boundary_corrector.git",
48
+ "directory": "packages/leaflet-layer"
49
+ },
50
+ "bugs": {
51
+ "url": "https://github.com/ramSeraph/india_boundary_corrector/issues"
52
+ },
53
+ "homepage": "https://github.com/ramSeraph/india_boundary_corrector#readme"
54
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ import * as L from 'leaflet';
2
+ import { LayerConfig } from '@india-boundary-corrector/layer-configs';
3
+ import { BoundaryCorrector as TileFixer } from '@india-boundary-corrector/tilefixer';
4
+
5
+ export { layerConfigs, LayerConfig } from '@india-boundary-corrector/layer-configs';
6
+ export { getPmtilesUrl } from '@india-boundary-corrector/data';
7
+
8
+ /**
9
+ * Options for L.TileLayer.IndiaBoundaryCorrected
10
+ */
11
+ export interface IndiaBoundaryCorrectedTileLayerOptions extends L.TileLayerOptions {
12
+ /** URL to PMTiles file (defaults to CDN) */
13
+ pmtilesUrl?: string;
14
+ /** LayerConfig object or config ID string (auto-detected from URL if not provided) */
15
+ layerConfig?: LayerConfig | string;
16
+ /** Additional layer configs for matching */
17
+ extraLayerConfigs?: LayerConfig[];
18
+ }
19
+
20
+ /**
21
+ * Extended TileLayer with boundary corrections
22
+ */
23
+ export interface IndiaBoundaryCorrectedTileLayer extends L.TileLayer {
24
+ /** Get the TileFixer instance */
25
+ getTileFixer(): TileFixer;
26
+ /** Get the resolved LayerConfig */
27
+ getLayerConfig(): LayerConfig | null;
28
+ }
29
+
30
+ declare module 'leaflet' {
31
+ namespace TileLayer {
32
+ class IndiaBoundaryCorrected extends L.TileLayer implements IndiaBoundaryCorrectedTileLayer {
33
+ constructor(url: string, options?: IndiaBoundaryCorrectedTileLayerOptions);
34
+ getTileFixer(): TileFixer;
35
+ getLayerConfig(): LayerConfig | null;
36
+ }
37
+ }
38
+
39
+ namespace tileLayer {
40
+ function indiaBoundaryCorrected(url: string, options?: IndiaBoundaryCorrectedTileLayerOptions): TileLayer.IndiaBoundaryCorrected;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Extend Leaflet with L.TileLayer.IndiaBoundaryCorrected and L.tileLayer.indiaBoundaryCorrected.
46
+ * Called automatically when Leaflet is available globally.
47
+ * Use this for ES module imports where L is not global.
48
+ * @param L - Leaflet namespace
49
+ */
50
+ export declare function extendLeaflet(L: typeof import('leaflet')): void;
package/src/index.js ADDED
@@ -0,0 +1,134 @@
1
+ import { getPmtilesUrl } from '@india-boundary-corrector/data';
2
+ import { layerConfigs } from '@india-boundary-corrector/layer-configs';
3
+ import { BoundaryCorrector as TileFixer } from '@india-boundary-corrector/tilefixer';
4
+
5
+ // Re-export for convenience
6
+ export { layerConfigs, LayerConfig } from '@india-boundary-corrector/layer-configs';
7
+ export { getPmtilesUrl } from '@india-boundary-corrector/data';
8
+
9
+ /**
10
+ * Extend Leaflet with IndiaBoundaryCorrectedTileLayer.
11
+ * @param {L} L - Leaflet namespace
12
+ */
13
+ function extendLeaflet(L) {
14
+ // Avoid re-extending
15
+ if (L.TileLayer.IndiaBoundaryCorrected) {
16
+ return;
17
+ }
18
+
19
+ L.TileLayer.IndiaBoundaryCorrected = L.TileLayer.extend({
20
+ options: {
21
+ pmtilesUrl: null,
22
+ layerConfig: null,
23
+ extraLayerConfigs: null,
24
+ },
25
+
26
+ initialize: function (url, options) {
27
+ L.TileLayer.prototype.initialize.call(this, url, options);
28
+
29
+ this._pmtilesUrl = this.options.pmtilesUrl ?? getPmtilesUrl();
30
+ this._tileFixer = new TileFixer(this._pmtilesUrl);
31
+ this._registry = layerConfigs.createMergedRegistry(this.options.extraLayerConfigs);
32
+
33
+ if (typeof this.options.layerConfig === 'string') {
34
+ this._layerConfig = this._registry.get(this.options.layerConfig);
35
+ } else if (this.options.layerConfig) {
36
+ this._layerConfig = this.options.layerConfig;
37
+ } else {
38
+ this._layerConfig = this._registry.detectFromTemplates([url]);
39
+ }
40
+
41
+ if (!this._layerConfig) {
42
+ console.warn('[L.TileLayer.IndiaBoundaryCorrected] Could not detect layer config from URL. Corrections will not be applied.');
43
+ }
44
+ },
45
+
46
+ /**
47
+ * Handle tile fetching and correction application logic.
48
+ * This method is extracted for testability.
49
+ * @param {string} tileUrl - URL of the raster tile
50
+ * @param {number} z - Zoom level
51
+ * @param {number} x - Tile X coordinate
52
+ * @param {number} y - Tile Y coordinate
53
+ * @param {number} tileSize - Tile size in pixels
54
+ * @returns {Promise<{blob: Blob, wasFixed: boolean, correctionsFailed: boolean, correctionsError: Error|null}>}
55
+ * @private
56
+ */
57
+ _fetchAndFixTile: async function (tileUrl, z, x, y, tileSize) {
58
+ const { data, wasFixed, correctionsFailed, correctionsError } = await this._tileFixer.fetchAndFixTile(
59
+ tileUrl, z, x, y, this._layerConfig, { tileSize }
60
+ );
61
+ const blob = new Blob([data], { type: wasFixed ? 'image/png' : undefined });
62
+ return { blob, wasFixed, correctionsFailed, correctionsError };
63
+ },
64
+
65
+ createTile: function (coords, done) {
66
+ const tile = document.createElement('img');
67
+
68
+ tile.alt = '';
69
+
70
+ if (this.options.crossOrigin || this.options.crossOrigin === '') {
71
+ tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
72
+ }
73
+
74
+ if (typeof this.options.referrerPolicy === 'string') {
75
+ tile.referrerPolicy = this.options.referrerPolicy;
76
+ }
77
+
78
+ if (!this._layerConfig) {
79
+ tile.onload = () => done(null, tile);
80
+ tile.onerror = (e) => done(e, tile);
81
+ tile.src = this.getTileUrl(coords);
82
+ return tile;
83
+ }
84
+
85
+ const tileUrl = this.getTileUrl(coords);
86
+ const z = coords.z;
87
+ const x = coords.x;
88
+ const y = coords.y;
89
+ const tileSize = this.options.tileSize || 256;
90
+
91
+ // TODO: Pass AbortSignal to _fetchAndFixTile to cancel in-flight requests when tiles
92
+ // go off-screen. This would require creating an AbortController per tile and hooking
93
+ // into Leaflet's _removeTile/_abortLoading. Deferred due to complexity - will revisit
94
+ // if performance becomes an issue during rapid panning.
95
+ this._fetchAndFixTile(tileUrl, z, x, y, tileSize)
96
+ .then(({ blob, wasFixed, correctionsFailed, correctionsError }) => {
97
+ if (correctionsFailed) {
98
+ console.warn('[L.TileLayer.IndiaBoundaryCorrected] Corrections fetch failed:', correctionsError);
99
+ this.fire('correctionerror', { error: correctionsError, coords: { z, x, y }, tileUrl });
100
+ }
101
+ tile.src = URL.createObjectURL(blob);
102
+ tile.onload = () => {
103
+ URL.revokeObjectURL(tile.src);
104
+ done(null, tile);
105
+ };
106
+ tile.onerror = (e) => {
107
+ URL.revokeObjectURL(tile.src);
108
+ done(e, tile);
109
+ };
110
+ })
111
+ .catch((err) => {
112
+ console.warn('[L.TileLayer.IndiaBoundaryCorrected] Tile fetch failed:', err);
113
+ done(err, tile);
114
+ });
115
+
116
+ return tile;
117
+ },
118
+
119
+ getTileFixer: function () {
120
+ return this._tileFixer;
121
+ },
122
+
123
+ getLayerConfig: function () {
124
+ return this._layerConfig;
125
+ },
126
+ });
127
+
128
+ L.tileLayer.indiaBoundaryCorrected = function (url, options) {
129
+ return new L.TileLayer.IndiaBoundaryCorrected(url, options);
130
+ };
131
+ }
132
+
133
+ // Export for manual extension if needed (e.g., ES modules with imported L)
134
+ export { extendLeaflet };