leaflet-india-boundary 0.1.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/LICENSE +25 -0
- package/LICENSE-DATA +101 -0
- package/README.md +391 -0
- package/data/india-boundary.geojson +1 -0
- package/dist/cjs/attribution.js +24 -0
- package/dist/cjs/attribution.js.map +1 -0
- package/dist/cjs/data.js +78 -0
- package/dist/cjs/data.js.map +1 -0
- package/dist/cjs/index.js +39 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/leaflet.js +152 -0
- package/dist/cjs/leaflet.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/react.js +77 -0
- package/dist/cjs/react.js.map +1 -0
- package/dist/cjs/style.js +129 -0
- package/dist/cjs/style.js.map +1 -0
- package/dist/cjs/suppress.js +462 -0
- package/dist/cjs/suppress.js.map +1 -0
- package/dist/cjs/suppressionData.js +205 -0
- package/dist/cjs/suppressionData.js.map +1 -0
- package/dist/esm/attribution.d.ts +21 -0
- package/dist/esm/attribution.d.ts.map +1 -0
- package/dist/esm/attribution.js +21 -0
- package/dist/esm/attribution.js.map +1 -0
- package/dist/esm/data.d.ts +78 -0
- package/dist/esm/data.d.ts.map +1 -0
- package/dist/esm/data.js +75 -0
- package/dist/esm/data.js.map +1 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +19 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/leaflet.d.ts +103 -0
- package/dist/esm/leaflet.d.ts.map +1 -0
- package/dist/esm/leaflet.js +147 -0
- package/dist/esm/leaflet.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/react.d.ts +31 -0
- package/dist/esm/react.d.ts.map +1 -0
- package/dist/esm/react.js +69 -0
- package/dist/esm/react.js.map +1 -0
- package/dist/esm/style.d.ts +106 -0
- package/dist/esm/style.d.ts.map +1 -0
- package/dist/esm/style.js +121 -0
- package/dist/esm/style.js.map +1 -0
- package/dist/esm/suppress.d.ts +64 -0
- package/dist/esm/suppress.d.ts.map +1 -0
- package/dist/esm/suppress.js +456 -0
- package/dist/esm/suppress.js.map +1 -0
- package/dist/esm/suppressionData.d.ts +34 -0
- package/dist/esm/suppressionData.d.ts.map +1 -0
- package/dist/esm/suppressionData.js +202 -0
- package/dist/esm/suppressionData.js.map +1 -0
- package/dist/style.css +66 -0
- package/package.json +113 -0
- package/src/attribution.ts +23 -0
- package/src/data.ts +153 -0
- package/src/index.ts +45 -0
- package/src/leaflet.ts +252 -0
- package/src/react.ts +92 -0
- package/src/style.css +66 -0
- package/src/style.ts +168 -0
- package/src/suppress.ts +599 -0
- package/src/suppressionData.ts +238 -0
- package/tools/build-india-boundary.mjs +836 -0
- package/tools/postbuild.mjs +61 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { geoJSON, } from "leaflet";
|
|
2
|
+
import { INDIA_BOUNDARY_ATTRIBUTION } from "./attribution.js";
|
|
3
|
+
import { INDIA_BOUNDARY } from "./data.js";
|
|
4
|
+
import { isOsmAdminBoundaryVisible, OSM_ADMIN_BOUNDARY_MIN_ZOOM, OSM_ADMIN_BOUNDARY_OPACITY, osmAdminBoundaryColor, osmAdminBoundaryWidth, OSM_ADMIN_BOUNDARY_WIDE_ZOOM, } from "./style.js";
|
|
5
|
+
/** Base class Leaflet writes onto the SVG paths, for CSS overrides. */
|
|
6
|
+
export const INDIA_BOUNDARY_CLASS = "leaflet-india-boundary";
|
|
7
|
+
/** Added alongside the base class from `wideZoom` up, mirroring carto's colour swap. */
|
|
8
|
+
export const INDIA_BOUNDARY_WIDE_CLASS = "leaflet-india-boundary--wide";
|
|
9
|
+
/** Pane the layer creates and filters when `tileFilter` is set. */
|
|
10
|
+
export const INDIA_BOUNDARY_PANE = "indiaBoundary";
|
|
11
|
+
function resolve(options) {
|
|
12
|
+
return {
|
|
13
|
+
style: options,
|
|
14
|
+
// The one line in this package that encodes the filter interaction.
|
|
15
|
+
opacity: options.opacity ?? (options.tileFilter ? 1 : OSM_ADMIN_BOUNDARY_OPACITY),
|
|
16
|
+
wideZoom: options.wideZoom ?? OSM_ADMIN_BOUNDARY_WIDE_ZOOM,
|
|
17
|
+
className: options.className,
|
|
18
|
+
tileFilter: options.tileFilter,
|
|
19
|
+
pane: options.pane ?? (options.tileFilter ? INDIA_BOUNDARY_PANE : undefined),
|
|
20
|
+
interactive: options.interactive ?? false,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function pathStyle(zoom, r) {
|
|
24
|
+
const wide = zoom >= r.wideZoom;
|
|
25
|
+
const classes = [INDIA_BOUNDARY_CLASS];
|
|
26
|
+
if (wide)
|
|
27
|
+
classes.push(INDIA_BOUNDARY_WIDE_CLASS);
|
|
28
|
+
if (r.className)
|
|
29
|
+
classes.push(r.className);
|
|
30
|
+
return {
|
|
31
|
+
className: classes.join(" "),
|
|
32
|
+
color: osmAdminBoundaryColor(zoom, r.style),
|
|
33
|
+
weight: osmAdminBoundaryWidth(zoom),
|
|
34
|
+
opacity: r.opacity,
|
|
35
|
+
// Below carto's z4 the basemap draws no national borders, so this draws
|
|
36
|
+
// nothing either. `stroke: false` rather than removing the layer from the
|
|
37
|
+
// map: same result on screen, but `map.hasLayer()` keeps telling the truth
|
|
38
|
+
// and layer-control checkboxes do not flicker.
|
|
39
|
+
stroke: isOsmAdminBoundaryVisible(zoom, r.style),
|
|
40
|
+
fill: false,
|
|
41
|
+
interactive: r.interactive,
|
|
42
|
+
// carto joins its border segments with a bevel. Note that nothing in CSS may
|
|
43
|
+
// set `stroke-linejoin` — a CSS property would beat the SVG attribute
|
|
44
|
+
// Leaflet writes here.
|
|
45
|
+
lineJoin: "bevel",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* India's boundary through Jammu & Kashmir, Ladakh and Aksai Chin — as depicted
|
|
50
|
+
* by the Survey of India — drawn over your basemap in the basemap's own border
|
|
51
|
+
* style.
|
|
52
|
+
*
|
|
53
|
+
* ```js
|
|
54
|
+
* import { indiaBoundaryLayer } from "leaflet-india-boundary/leaflet";
|
|
55
|
+
*
|
|
56
|
+
* indiaBoundaryLayer().addTo(map);
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* The returned layer restyles itself on zoom, so carto's per-zoom widths and its
|
|
60
|
+
* colour swap at z10 keep matching the tiles underneath, and it draws nothing
|
|
61
|
+
* below z4 where the basemap has no national borders to match.
|
|
62
|
+
*
|
|
63
|
+
* ## The ceiling, stated plainly
|
|
64
|
+
*
|
|
65
|
+
* This *adds* India's claimed border. It cannot *remove* the Line of Control /
|
|
66
|
+
* Line of Actual Control that raster tiles have already drawn, because by the time
|
|
67
|
+
* a tile reaches the browser it is a picture. Where the two run apart, both are
|
|
68
|
+
* visible. Suppressing the basemap's own line needs either vector tiles, where the
|
|
69
|
+
* boundary layer can be filtered out, or a provider political view — HERE's
|
|
70
|
+
* `pview=IN`, MapTiler's worldview setting.
|
|
71
|
+
*/
|
|
72
|
+
export function indiaBoundaryLayer(options = {}) {
|
|
73
|
+
const r = resolve(options);
|
|
74
|
+
const attribution = options.attribution ?? INDIA_BOUNDARY_ATTRIBUTION;
|
|
75
|
+
// Declared before `geoJSON()` on purpose. Leaflet builds the child paths
|
|
76
|
+
// synchronously inside the constructor, which calls `style` right there — so a
|
|
77
|
+
// `style` closure reading a `let` declared afterwards would hit it in its
|
|
78
|
+
// temporal dead zone and throw on construction.
|
|
79
|
+
let map = null;
|
|
80
|
+
const zoomNow = () => map?.getZoom() ?? r.style.minZoom ?? OSM_ADMIN_BOUNDARY_MIN_ZOOM;
|
|
81
|
+
const layer = geoJSON(INDIA_BOUNDARY, {
|
|
82
|
+
style: () => pathStyle(zoomNow(), r),
|
|
83
|
+
pane: r.pane,
|
|
84
|
+
interactive: r.interactive,
|
|
85
|
+
...(attribution === false ? {} : { attribution }),
|
|
86
|
+
});
|
|
87
|
+
const restyle = () => {
|
|
88
|
+
const zoom = zoomNow();
|
|
89
|
+
layer.setStyle(() => pathStyle(zoom, r));
|
|
90
|
+
// `setStyle` does not reapply `className`. Leaflet writes the class once, when
|
|
91
|
+
// it creates the path element, and its `_updateStyle` only touches the paint
|
|
92
|
+
// attributes — so the wide-zoom modifier has to be toggled by hand or it stays
|
|
93
|
+
// frozen at whatever it was when the layer was built. Harmless for the default
|
|
94
|
+
// rendering, where the colour arrives as the `stroke` attribute; not harmless
|
|
95
|
+
// for anyone driving the colours from style.css, where the class *is* the
|
|
96
|
+
// mechanism.
|
|
97
|
+
const wide = zoom >= r.wideZoom;
|
|
98
|
+
for (const el of indiaBoundaryElements(layer)) {
|
|
99
|
+
el.classList.toggle(INDIA_BOUNDARY_WIDE_CLASS, wide);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
// Instance-level overrides of two documented `Layer` methods. Leaflet's own
|
|
103
|
+
// class system (`L.GeoJSON.extend`) would work too, but it types poorly and
|
|
104
|
+
// subclassing it from an ES class fights its `initialize` convention for no
|
|
105
|
+
// gain — there is no second implementation to share.
|
|
106
|
+
const baseOnAdd = layer.onAdd.bind(layer);
|
|
107
|
+
const baseOnRemove = layer.onRemove.bind(layer);
|
|
108
|
+
layer.onAdd = (m) => {
|
|
109
|
+
map = m;
|
|
110
|
+
// Must happen before the base `onAdd`, which is when each path resolves the
|
|
111
|
+
// renderer that will live in this pane.
|
|
112
|
+
if (r.tileFilter && r.pane) {
|
|
113
|
+
const pane = m.getPane(r.pane) ?? m.createPane(r.pane);
|
|
114
|
+
if (!pane.style.zIndex)
|
|
115
|
+
pane.style.zIndex = "400"; // beside overlayPane, under markers
|
|
116
|
+
pane.style.filter = r.tileFilter;
|
|
117
|
+
if (!r.interactive)
|
|
118
|
+
pane.style.pointerEvents = "none";
|
|
119
|
+
}
|
|
120
|
+
const result = baseOnAdd(m);
|
|
121
|
+
m.on("zoomend", restyle);
|
|
122
|
+
restyle();
|
|
123
|
+
return result;
|
|
124
|
+
};
|
|
125
|
+
layer.onRemove = (m) => {
|
|
126
|
+
m.off("zoomend", restyle);
|
|
127
|
+
map = null;
|
|
128
|
+
return baseOnRemove(m);
|
|
129
|
+
};
|
|
130
|
+
return layer;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Escape hatch for anyone doing something this factory does not cover — reading
|
|
134
|
+
* the live SVG elements, say, to hand them to an animation library.
|
|
135
|
+
*
|
|
136
|
+
* Returns undefined for canvas-rendered paths, which have no element of their own.
|
|
137
|
+
*/
|
|
138
|
+
export function indiaBoundaryElements(layer) {
|
|
139
|
+
const out = [];
|
|
140
|
+
layer.eachLayer((child) => {
|
|
141
|
+
const el = child.getElement?.();
|
|
142
|
+
if (el)
|
|
143
|
+
out.push(el);
|
|
144
|
+
});
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=leaflet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leaflet.js","sourceRoot":"","sources":["../../src/leaflet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type IndiaBoundaryLayerOptions } from "./leaflet.js";
|
|
2
|
+
export type IndiaBoundaryProps = IndiaBoundaryLayerOptions;
|
|
3
|
+
/**
|
|
4
|
+
* react-leaflet wrapper. Drop it inside a `<MapContainer>`, anywhere below the
|
|
5
|
+
* `<TileLayer>`:
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { IndiaBoundary } from "leaflet-india-boundary/react";
|
|
9
|
+
*
|
|
10
|
+
* <MapContainer center={[22, 79]} zoom={5}>
|
|
11
|
+
* <TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
|
12
|
+
* <IndiaBoundary />
|
|
13
|
+
* </MapContainer>
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* If your app filters its tile pane to build a dark basemap, pass the same filter
|
|
17
|
+
* so the overlay is transformed with it — see `tileFilter` on
|
|
18
|
+
* {@link IndiaBoundaryLayerOptions}, which is the one option worth reading about
|
|
19
|
+
* before you need it:
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <IndiaBoundary tileFilter="invert(1) hue-rotate(192deg) saturate(0.45)" />
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Renders no DOM of its own — the layer is Leaflet's, so React only owns its
|
|
26
|
+
* lifetime. Note this file is deliberately `.ts`, not `.tsx`: the component
|
|
27
|
+
* returns `null`, so the package needs no JSX transform to build.
|
|
28
|
+
*/
|
|
29
|
+
export declare function IndiaBoundary(props?: IndiaBoundaryProps): null;
|
|
30
|
+
export { INDIA_BOUNDARY_CLASS, INDIA_BOUNDARY_PANE, INDIA_BOUNDARY_WIDE_CLASS, indiaBoundaryLayer, type IndiaBoundaryLayerOptions, } from "./leaflet.js";
|
|
31
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/react.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAElF,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,aAAa,CAAC,KAAK,GAAE,kBAAuB,GAAG,IAAI,CAmDlE;AAED,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useMap } from "react-leaflet";
|
|
3
|
+
import { indiaBoundaryLayer } from "./leaflet.js";
|
|
4
|
+
/**
|
|
5
|
+
* react-leaflet wrapper. Drop it inside a `<MapContainer>`, anywhere below the
|
|
6
|
+
* `<TileLayer>`:
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { IndiaBoundary } from "leaflet-india-boundary/react";
|
|
10
|
+
*
|
|
11
|
+
* <MapContainer center={[22, 79]} zoom={5}>
|
|
12
|
+
* <TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
|
13
|
+
* <IndiaBoundary />
|
|
14
|
+
* </MapContainer>
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* If your app filters its tile pane to build a dark basemap, pass the same filter
|
|
18
|
+
* so the overlay is transformed with it — see `tileFilter` on
|
|
19
|
+
* {@link IndiaBoundaryLayerOptions}, which is the one option worth reading about
|
|
20
|
+
* before you need it:
|
|
21
|
+
*
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <IndiaBoundary tileFilter="invert(1) hue-rotate(192deg) saturate(0.45)" />
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* Renders no DOM of its own — the layer is Leaflet's, so React only owns its
|
|
27
|
+
* lifetime. Note this file is deliberately `.ts`, not `.tsx`: the component
|
|
28
|
+
* returns `null`, so the package needs no JSX transform to build.
|
|
29
|
+
*/
|
|
30
|
+
export function IndiaBoundary(props = {}) {
|
|
31
|
+
const map = useMap();
|
|
32
|
+
// Every option is a primitive, so they can be listed individually instead of
|
|
33
|
+
// reaching for a deep-equality hook or re-creating the layer whenever the
|
|
34
|
+
// caller passes a fresh object literal (which, in JSX, is every render).
|
|
35
|
+
const { attribution, className, color, colorWide, interactive, minZoom, opacity, pane, tileFilter, wideZoom, } = props;
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const layer = indiaBoundaryLayer({
|
|
38
|
+
attribution,
|
|
39
|
+
className,
|
|
40
|
+
color,
|
|
41
|
+
colorWide,
|
|
42
|
+
interactive,
|
|
43
|
+
minZoom,
|
|
44
|
+
opacity,
|
|
45
|
+
pane,
|
|
46
|
+
tileFilter,
|
|
47
|
+
wideZoom,
|
|
48
|
+
});
|
|
49
|
+
layer.addTo(map);
|
|
50
|
+
return () => {
|
|
51
|
+
layer.remove();
|
|
52
|
+
};
|
|
53
|
+
}, [
|
|
54
|
+
map,
|
|
55
|
+
attribution,
|
|
56
|
+
className,
|
|
57
|
+
color,
|
|
58
|
+
colorWide,
|
|
59
|
+
interactive,
|
|
60
|
+
minZoom,
|
|
61
|
+
opacity,
|
|
62
|
+
pane,
|
|
63
|
+
tileFilter,
|
|
64
|
+
wideZoom,
|
|
65
|
+
]);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
export { INDIA_BOUNDARY_CLASS, INDIA_BOUNDARY_PANE, INDIA_BOUNDARY_WIDE_CLASS, indiaBoundaryLayer, } from "./leaflet.js";
|
|
69
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAkC,MAAM,cAAc,CAAC;AAIlF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,aAAa,CAAC,QAA4B,EAAE;IAC1D,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IAErB,6EAA6E;IAC7E,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,EACJ,WAAW,EACX,SAAS,EACT,KAAK,EACL,SAAS,EACT,WAAW,EACX,OAAO,EACP,OAAO,EACP,IAAI,EACJ,UAAU,EACV,QAAQ,GACT,GAAG,KAAK,CAAC;IAEV,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,kBAAkB,CAAC;YAC/B,WAAW;YACX,SAAS;YACT,KAAK;YACL,SAAS;YACT,WAAW;YACX,OAAO;YACP,OAAO;YACP,IAAI;YACJ,UAAU;YACV,QAAQ;SACT,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,GAAG,EAAE;YACV,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,GAAG;QACH,WAAW;QACX,SAAS;QACT,KAAK;QACL,SAAS;QACT,WAAW;QACX,OAAO;QACP,OAAO;QACP,IAAI;QACJ,UAAU;QACV,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,GAEnB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openstreetmap-carto's own `admin_level=2` border style, transcribed from its
|
|
3
|
+
* `style/admin.mss` (the `::wideline` attachment) rather than picked by eye.
|
|
4
|
+
*
|
|
5
|
+
* Matching these exactly is most of what stops the overlay reading as something
|
|
6
|
+
* drawn *on top of* the basemap instead of part of it. A border that is a
|
|
7
|
+
* slightly different purple, or a pixel too heavy, looks like an annotation. The
|
|
8
|
+
* same border in the basemap's own colour and weight looks like the map.
|
|
9
|
+
*
|
|
10
|
+
* Nothing in this module imports Leaflet, or anything else. It is here so that a
|
|
11
|
+
* MapLibre, OpenLayers or deck.gl user gets the same values without taking a
|
|
12
|
+
* mapping dependency they do not use.
|
|
13
|
+
*/
|
|
14
|
+
/** carto's `@admin-boundaries`. Applies below {@link OSM_ADMIN_BOUNDARY_WIDE_ZOOM}. */
|
|
15
|
+
export declare const OSM_ADMIN_BOUNDARY_COLOR = "#8d618b";
|
|
16
|
+
/** carto's `@admin-boundaries-wide`, which it swaps in from zoom 10. */
|
|
17
|
+
export declare const OSM_ADMIN_BOUNDARY_COLOR_WIDE = "#a37da1";
|
|
18
|
+
/** The zoom at which carto swaps `@admin-boundaries` for the lighter wide colour. */
|
|
19
|
+
export declare const OSM_ADMIN_BOUNDARY_WIDE_ZOOM = 10;
|
|
20
|
+
/**
|
|
21
|
+
* carto's country-border rule starts at `[zoom >= 4]`, so below that the basemap
|
|
22
|
+
* draws no national boundaries at all — and neither should this overlay. On a
|
|
23
|
+
* borderless world map it is a lone squiggle floating over central Asia, attached
|
|
24
|
+
* to nothing. See `isOsmAdminBoundaryVisible`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const OSM_ADMIN_BOUNDARY_MIN_ZOOM = 4;
|
|
27
|
+
/**
|
|
28
|
+
* carto's width table ends here. Above it the z14 width carries on, which is what
|
|
29
|
+
* carto does too.
|
|
30
|
+
*/
|
|
31
|
+
export declare const OSM_ADMIN_BOUNDARY_MAX_TABLE_ZOOM = 14;
|
|
32
|
+
/**
|
|
33
|
+
* carto's own stroke opacity for national borders.
|
|
34
|
+
*
|
|
35
|
+
* Read the note on `tileFilter` in the README before overriding this. Short
|
|
36
|
+
* version: carto composites this 0.5 against its light land fill (`#f2efe9`)
|
|
37
|
+
* *inside the tile*. If your app puts a CSS filter over its tile pane, an overlay
|
|
38
|
+
* drawn at 0.5 on the unfiltered side of that filter lands roughly three times
|
|
39
|
+
* too dark and disappears.
|
|
40
|
+
*/
|
|
41
|
+
export declare const OSM_ADMIN_BOUNDARY_OPACITY = 0.5;
|
|
42
|
+
/**
|
|
43
|
+
* Stroke width by zoom, from carto's `::wideline` attachment.
|
|
44
|
+
*
|
|
45
|
+
* carto pairs this with a white "background" line, which is *not* a visible
|
|
46
|
+
* casing — it is a `comp-op: darken` trick for hiding the seams where two
|
|
47
|
+
* countries' borders overlap. Do not draw one. On a single overlay there is
|
|
48
|
+
* nothing to hide, and a white line under a purple one just looks like a mistake.
|
|
49
|
+
*/
|
|
50
|
+
export declare const OSM_ADMIN_BOUNDARY_WIDTH: Readonly<Record<number, number>>;
|
|
51
|
+
/** Every carto-derived value in one object, for destructuring or spreading. */
|
|
52
|
+
export declare const OSM_ADMIN_STYLE: Readonly<{
|
|
53
|
+
color: "#8d618b";
|
|
54
|
+
colorWide: "#a37da1";
|
|
55
|
+
wideZoom: 10;
|
|
56
|
+
minZoom: 4;
|
|
57
|
+
maxTableZoom: 14;
|
|
58
|
+
opacity: 0.5;
|
|
59
|
+
width: Readonly<Record<number, number>>;
|
|
60
|
+
}>;
|
|
61
|
+
/** Overrides accepted by the resolvers below and by every layer factory. */
|
|
62
|
+
export interface OsmAdminBoundaryStyleOptions {
|
|
63
|
+
/** Stroke colour below `wideZoom`. Defaults to carto's `@admin-boundaries`. */
|
|
64
|
+
color?: string;
|
|
65
|
+
/** Stroke colour from `wideZoom` up. Defaults to carto's `@admin-boundaries-wide`. */
|
|
66
|
+
colorWide?: string;
|
|
67
|
+
/** Zoom at which `colorWide` takes over. Defaults to 10, as carto does. */
|
|
68
|
+
wideZoom?: number;
|
|
69
|
+
/** Below this zoom the boundary is not drawn. Defaults to 4, as carto does. */
|
|
70
|
+
minZoom?: number;
|
|
71
|
+
/** Stroke opacity. Defaults to carto's 0.5 — but see `tileFilter`. */
|
|
72
|
+
opacity?: number;
|
|
73
|
+
}
|
|
74
|
+
/** carto's width for a zoom, clamped to the ends of its table. */
|
|
75
|
+
export declare function osmAdminBoundaryWidth(zoom: number): number;
|
|
76
|
+
/** carto's border colour for a zoom. */
|
|
77
|
+
export declare function osmAdminBoundaryColor(zoom: number, options?: OsmAdminBoundaryStyleOptions): string;
|
|
78
|
+
/** Whether the basemap draws national borders at this zoom, and so whether we should. */
|
|
79
|
+
export declare function isOsmAdminBoundaryVisible(zoom: number, options?: OsmAdminBoundaryStyleOptions): boolean;
|
|
80
|
+
/** A resolved stroke, ready to hand to whatever renderer you are using. */
|
|
81
|
+
export interface ResolvedBoundaryStyle {
|
|
82
|
+
color: string;
|
|
83
|
+
width: number;
|
|
84
|
+
opacity: number;
|
|
85
|
+
visible: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The whole style for one zoom level, in renderer-neutral terms.
|
|
89
|
+
*
|
|
90
|
+
* ```js
|
|
91
|
+
* const { color, width, visible } = osmAdminBoundaryStyle(map.getZoom());
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function osmAdminBoundaryStyle(zoom: number, options?: OsmAdminBoundaryStyleOptions): ResolvedBoundaryStyle;
|
|
95
|
+
/**
|
|
96
|
+
* carto's width table as a MapLibre / Mapbox style expression, for
|
|
97
|
+
* `paint: { "line-width": … }`.
|
|
98
|
+
*
|
|
99
|
+
* `interpolate` rather than `step` on purpose: carto's table is per-integer-zoom
|
|
100
|
+
* because raster tiles only exist at integer zooms, but a vector map renders the
|
|
101
|
+
* fractional zooms in between, and stepping through them makes the line visibly
|
|
102
|
+
* jump. Interpolating hits carto's exact widths at every integer zoom and behaves
|
|
103
|
+
* sanely between them.
|
|
104
|
+
*/
|
|
105
|
+
export declare function osmAdminBoundaryWidthExpression(): unknown[];
|
|
106
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/style.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD,wEAAwE;AACxE,eAAO,MAAM,6BAA6B,YAAY,CAAC;AAEvD,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAalE,CAAC;AAEL,+EAA+E;AAC/E,eAAO,MAAM,eAAe;;;;;;;;EAQ1B,CAAC;AAEH,4EAA4E;AAC5E,MAAM,WAAW,4BAA4B;IAC3C,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wCAAwC;AACxC,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,4BAAiC,GACzC,MAAM,CAKR;AAED,yFAAyF;AACzF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAET;AAED,2EAA2E;AAC3E,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,4BAAiC,GACzC,qBAAqB,CAOvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,EAAE,CAM3D"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openstreetmap-carto's own `admin_level=2` border style, transcribed from its
|
|
3
|
+
* `style/admin.mss` (the `::wideline` attachment) rather than picked by eye.
|
|
4
|
+
*
|
|
5
|
+
* Matching these exactly is most of what stops the overlay reading as something
|
|
6
|
+
* drawn *on top of* the basemap instead of part of it. A border that is a
|
|
7
|
+
* slightly different purple, or a pixel too heavy, looks like an annotation. The
|
|
8
|
+
* same border in the basemap's own colour and weight looks like the map.
|
|
9
|
+
*
|
|
10
|
+
* Nothing in this module imports Leaflet, or anything else. It is here so that a
|
|
11
|
+
* MapLibre, OpenLayers or deck.gl user gets the same values without taking a
|
|
12
|
+
* mapping dependency they do not use.
|
|
13
|
+
*/
|
|
14
|
+
/** carto's `@admin-boundaries`. Applies below {@link OSM_ADMIN_BOUNDARY_WIDE_ZOOM}. */
|
|
15
|
+
export const OSM_ADMIN_BOUNDARY_COLOR = "#8d618b";
|
|
16
|
+
/** carto's `@admin-boundaries-wide`, which it swaps in from zoom 10. */
|
|
17
|
+
export const OSM_ADMIN_BOUNDARY_COLOR_WIDE = "#a37da1";
|
|
18
|
+
/** The zoom at which carto swaps `@admin-boundaries` for the lighter wide colour. */
|
|
19
|
+
export const OSM_ADMIN_BOUNDARY_WIDE_ZOOM = 10;
|
|
20
|
+
/**
|
|
21
|
+
* carto's country-border rule starts at `[zoom >= 4]`, so below that the basemap
|
|
22
|
+
* draws no national boundaries at all — and neither should this overlay. On a
|
|
23
|
+
* borderless world map it is a lone squiggle floating over central Asia, attached
|
|
24
|
+
* to nothing. See `isOsmAdminBoundaryVisible`.
|
|
25
|
+
*/
|
|
26
|
+
export const OSM_ADMIN_BOUNDARY_MIN_ZOOM = 4;
|
|
27
|
+
/**
|
|
28
|
+
* carto's width table ends here. Above it the z14 width carries on, which is what
|
|
29
|
+
* carto does too.
|
|
30
|
+
*/
|
|
31
|
+
export const OSM_ADMIN_BOUNDARY_MAX_TABLE_ZOOM = 14;
|
|
32
|
+
/**
|
|
33
|
+
* carto's own stroke opacity for national borders.
|
|
34
|
+
*
|
|
35
|
+
* Read the note on `tileFilter` in the README before overriding this. Short
|
|
36
|
+
* version: carto composites this 0.5 against its light land fill (`#f2efe9`)
|
|
37
|
+
* *inside the tile*. If your app puts a CSS filter over its tile pane, an overlay
|
|
38
|
+
* drawn at 0.5 on the unfiltered side of that filter lands roughly three times
|
|
39
|
+
* too dark and disappears.
|
|
40
|
+
*/
|
|
41
|
+
export const OSM_ADMIN_BOUNDARY_OPACITY = 0.5;
|
|
42
|
+
/**
|
|
43
|
+
* Stroke width by zoom, from carto's `::wideline` attachment.
|
|
44
|
+
*
|
|
45
|
+
* carto pairs this with a white "background" line, which is *not* a visible
|
|
46
|
+
* casing — it is a `comp-op: darken` trick for hiding the seams where two
|
|
47
|
+
* countries' borders overlap. Do not draw one. On a single overlay there is
|
|
48
|
+
* nothing to hide, and a white line under a purple one just looks like a mistake.
|
|
49
|
+
*/
|
|
50
|
+
export const OSM_ADMIN_BOUNDARY_WIDTH = Object.freeze({
|
|
51
|
+
4: 1.2,
|
|
52
|
+
5: 1.5,
|
|
53
|
+
6: 1.8,
|
|
54
|
+
7: 2.2,
|
|
55
|
+
8: 3,
|
|
56
|
+
9: 3.5,
|
|
57
|
+
10: 4.5,
|
|
58
|
+
11: 5,
|
|
59
|
+
12: 6,
|
|
60
|
+
13: 7,
|
|
61
|
+
14: 8,
|
|
62
|
+
});
|
|
63
|
+
/** Every carto-derived value in one object, for destructuring or spreading. */
|
|
64
|
+
export const OSM_ADMIN_STYLE = Object.freeze({
|
|
65
|
+
color: OSM_ADMIN_BOUNDARY_COLOR,
|
|
66
|
+
colorWide: OSM_ADMIN_BOUNDARY_COLOR_WIDE,
|
|
67
|
+
wideZoom: OSM_ADMIN_BOUNDARY_WIDE_ZOOM,
|
|
68
|
+
minZoom: OSM_ADMIN_BOUNDARY_MIN_ZOOM,
|
|
69
|
+
maxTableZoom: OSM_ADMIN_BOUNDARY_MAX_TABLE_ZOOM,
|
|
70
|
+
opacity: OSM_ADMIN_BOUNDARY_OPACITY,
|
|
71
|
+
width: OSM_ADMIN_BOUNDARY_WIDTH,
|
|
72
|
+
});
|
|
73
|
+
/** carto's width for a zoom, clamped to the ends of its table. */
|
|
74
|
+
export function osmAdminBoundaryWidth(zoom) {
|
|
75
|
+
const z = Math.min(OSM_ADMIN_BOUNDARY_MAX_TABLE_ZOOM, Math.max(OSM_ADMIN_BOUNDARY_MIN_ZOOM, Math.round(zoom)));
|
|
76
|
+
return OSM_ADMIN_BOUNDARY_WIDTH[z] ?? OSM_ADMIN_BOUNDARY_WIDTH[OSM_ADMIN_BOUNDARY_MIN_ZOOM];
|
|
77
|
+
}
|
|
78
|
+
/** carto's border colour for a zoom. */
|
|
79
|
+
export function osmAdminBoundaryColor(zoom, options = {}) {
|
|
80
|
+
const wideZoom = options.wideZoom ?? OSM_ADMIN_BOUNDARY_WIDE_ZOOM;
|
|
81
|
+
return zoom >= wideZoom
|
|
82
|
+
? (options.colorWide ?? OSM_ADMIN_BOUNDARY_COLOR_WIDE)
|
|
83
|
+
: (options.color ?? OSM_ADMIN_BOUNDARY_COLOR);
|
|
84
|
+
}
|
|
85
|
+
/** Whether the basemap draws national borders at this zoom, and so whether we should. */
|
|
86
|
+
export function isOsmAdminBoundaryVisible(zoom, options = {}) {
|
|
87
|
+
return zoom >= (options.minZoom ?? OSM_ADMIN_BOUNDARY_MIN_ZOOM);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The whole style for one zoom level, in renderer-neutral terms.
|
|
91
|
+
*
|
|
92
|
+
* ```js
|
|
93
|
+
* const { color, width, visible } = osmAdminBoundaryStyle(map.getZoom());
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export function osmAdminBoundaryStyle(zoom, options = {}) {
|
|
97
|
+
return {
|
|
98
|
+
color: osmAdminBoundaryColor(zoom, options),
|
|
99
|
+
width: osmAdminBoundaryWidth(zoom),
|
|
100
|
+
opacity: options.opacity ?? OSM_ADMIN_BOUNDARY_OPACITY,
|
|
101
|
+
visible: isOsmAdminBoundaryVisible(zoom, options),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* carto's width table as a MapLibre / Mapbox style expression, for
|
|
106
|
+
* `paint: { "line-width": … }`.
|
|
107
|
+
*
|
|
108
|
+
* `interpolate` rather than `step` on purpose: carto's table is per-integer-zoom
|
|
109
|
+
* because raster tiles only exist at integer zooms, but a vector map renders the
|
|
110
|
+
* fractional zooms in between, and stepping through them makes the line visibly
|
|
111
|
+
* jump. Interpolating hits carto's exact widths at every integer zoom and behaves
|
|
112
|
+
* sanely between them.
|
|
113
|
+
*/
|
|
114
|
+
export function osmAdminBoundaryWidthExpression() {
|
|
115
|
+
const stops = Object.keys(OSM_ADMIN_BOUNDARY_WIDTH)
|
|
116
|
+
.map(Number)
|
|
117
|
+
.sort((a, b) => a - b)
|
|
118
|
+
.flatMap((z) => [z, OSM_ADMIN_BOUNDARY_WIDTH[z]]);
|
|
119
|
+
return ["interpolate", ["linear"], ["zoom"], ...stops];
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/style.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type TileLayer, type TileLayerOptions } from "leaflet";
|
|
2
|
+
export interface SuppressedTileLayerOptions extends TileLayerOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Mask width in pixels, or a function of zoom. Defaults to
|
|
5
|
+
* {@link defaultRibbonWidth} — carto's stroke width for the zoom plus padding.
|
|
6
|
+
*
|
|
7
|
+
* Widen it if a sliver of the old line survives; narrow it if labels crossing the
|
|
8
|
+
* border are being chewed. Those are the only two failure modes, and they pull in
|
|
9
|
+
* opposite directions.
|
|
10
|
+
*/
|
|
11
|
+
ribbonWidth?: number | ((zoom: number) => number);
|
|
12
|
+
/**
|
|
13
|
+
* On a CORS failure (a tainted canvas, so `getImageData` throws), show the tile
|
|
14
|
+
* unmodified instead of failing. Default `true`: a map with a redundant border
|
|
15
|
+
* beats a map with holes in it.
|
|
16
|
+
*/
|
|
17
|
+
fallbackOnError?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Paint the mask in magenta instead of inpainting under it. For checking that the
|
|
20
|
+
* ribbon actually lands on the line before trusting what it removes.
|
|
21
|
+
*/
|
|
22
|
+
debugMask?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Reconstruct across tile boundaries by seeding the inpaint with the neighbouring
|
|
25
|
+
* tiles. Default `true`.
|
|
26
|
+
*
|
|
27
|
+
* Without it, each tile is inpainted in isolation, so a pixel on the tile's edge is
|
|
28
|
+
* rebuilt only from the data on its own side and the two tiles disagree along the
|
|
29
|
+
* join — a faint but visible stitch across the erased line. With it, the work
|
|
30
|
+
* happens on a padded canvas seeded from the neighbours the ribbon actually runs
|
|
31
|
+
* into, so both sides see the same ground truth.
|
|
32
|
+
*
|
|
33
|
+
* The cost is bounded and small: only the neighbours the ribbon reaches are
|
|
34
|
+
* fetched — usually two or three, since the line enters and leaves — and only for
|
|
35
|
+
* the handful of tiles the ribbon touches at all. Those neighbours are also, almost
|
|
36
|
+
* always, tiles Leaflet is already displaying, so they come from the browser cache.
|
|
37
|
+
* Set `false` if you would rather have the seams than the requests.
|
|
38
|
+
*/
|
|
39
|
+
seamlessEdges?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A tile layer that erases the Line of Control and Line of Actual Control from the
|
|
43
|
+
* tiles it loads.
|
|
44
|
+
*
|
|
45
|
+
* Compose it with the boundary overlay to get a single correct line on free raster
|
|
46
|
+
* tiles — this one removes what the basemap drew, that one adds India's claim:
|
|
47
|
+
*
|
|
48
|
+
* ```js
|
|
49
|
+
* import { suppressedTileLayer } from "leaflet-india-boundary/suppress";
|
|
50
|
+
* import { indiaBoundaryLayer } from "leaflet-india-boundary/leaflet";
|
|
51
|
+
*
|
|
52
|
+
* suppressedTileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
53
|
+
* attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
54
|
+
* }).addTo(map);
|
|
55
|
+
*
|
|
56
|
+
* indiaBoundaryLayer().addTo(map);
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* Read the module comment above before shipping this. The short version: it does not
|
|
60
|
+
* touch labels, so it does not make a map match India's official depiction.
|
|
61
|
+
*/
|
|
62
|
+
export declare function suppressedTileLayer(urlTemplate: string, options?: SuppressedTileLayerOptions): TileLayer;
|
|
63
|
+
export { INDIA_BOUNDARY_SUPPRESSION, SUPPRESSION_BBOX, type SuppressionLine, type SuppressionProperties, } from "./suppressionData.js";
|
|
64
|
+
//# sourceMappingURL=suppress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppress.d.ts","sourceRoot":"","sources":["../../src/suppress.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,gBAAgB,EACtB,MAAM,SAAS,CAAC;AAuGjB,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAClE;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAElD;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;;;;;;;;;OAeG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAgED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,0BAA+B,GACvC,SAAS,CAmHX;AA6OD,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAC"}
|