-
-
Notifications
You must be signed in to change notification settings - Fork 628
Expand file tree
/
Copy pathprint-atlas-mask.ts
More file actions
62 lines (59 loc) · 2.15 KB
/
Copy pathprint-atlas-mask.ts
File metadata and controls
62 lines (59 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/** Temporary inverted-fill mask for the active Print Layout atlas feature. */
import { buildInvertedMask } from "@geolibre/map/derived-geometry";
import type { Feature, FeatureCollection, MultiPolygon, Polygon } from "geojson";
import type { GeoJSONSource, Map as MapLibreMap } from "maplibre-gl";
const SOURCE_ID = "geolibre-print-atlas-mask";
const FILL_LAYER_ID = "geolibre-print-atlas-mask-fill";
const featureCollections = new WeakMap<
Feature<Polygon | MultiPolygon>,
FeatureCollection<Polygon | MultiPolygon>
>();
/** Remove the atlas mask source and layer, if present. */
export function clearAtlasFeatureMask(map: MapLibreMap): void {
if (map.getLayer(FILL_LAYER_ID)) map.removeLayer(FILL_LAYER_ID);
if (map.getSource(SOURCE_ID)) map.removeSource(SOURCE_ID);
}
/**
* Show a translucent inverted fill around one polygon atlas feature.
*
* @param map - MapLibre map used by the Print Layout capture.
* @param feature - Current coverage feature.
* @returns Whether a polygon mask could be rendered.
*/
export function showAtlasFeatureMask(map: MapLibreMap, feature: Feature | undefined): boolean {
if (feature?.geometry?.type !== "Polygon" && feature?.geometry?.type !== "MultiPolygon") {
clearAtlasFeatureMask(map);
return false;
}
const polygonFeature = feature as Feature<Polygon | MultiPolygon>;
let collection = featureCollections.get(polygonFeature);
if (!collection) {
collection = {
type: "FeatureCollection",
features: [polygonFeature],
};
featureCollections.set(polygonFeature, collection);
}
const mask = buildInvertedMask(collection);
if (!mask) {
clearAtlasFeatureMask(map);
return false;
}
const source = map.getSource(SOURCE_ID) as GeoJSONSource | undefined;
if (source) source.setData(mask);
else map.addSource(SOURCE_ID, { type: "geojson", data: mask });
if (!map.getLayer(FILL_LAYER_ID)) {
map.addLayer({
id: FILL_LAYER_ID,
type: "fill",
source: SOURCE_ID,
metadata: { "geolibre:internal": true },
paint: {
"fill-color": "#ffffff",
"fill-opacity": 0.7,
"fill-outline-color": "rgba(0, 0, 0, 0)",
},
});
}
return true;
}