]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/leaflet.layers.js
Merge remote-tracking branch 'upstream/pull/6798'
[rails.git] / app / assets / javascripts / leaflet.layers.js
1 //= require @maptiler/maplibre-gl-omt-language
2 //= require maplibre/map
3 //= require maplibre/i18n
4
5 L.OSM.layers = function (options) {
6   const control = L.OSM.sidebarPane(options, "layers", "javascripts.map.layers.title", "javascripts.map.layers.header");
7
8   control.onAddPane = function (map, button, $ui, toggle) {
9     const layers = options.layers;
10
11     control.onContentLoaded = function () {
12       $ui.find(".base-layers>div").each(initBaseLayer);
13       initOverlays();
14     };
15     control.loadContent();
16
17     function initBaseLayer() {
18       const [container, input, item] = this.children;
19       const layer = layers.find(l => l.options.layerId === container.dataset.layer);
20       input.checked = map.hasLayer(layer);
21
22       map.whenReady(function () {
23         let miniMap;
24         $ui
25           .on("show", shown)
26           .on("hide", hide);
27
28         function shown() {
29           const center = map.getCenter();
30           miniMap = new OSM.MapLibre.Map({
31             container,
32             style: layer.options.style,
33             interactive: false,
34             attributionControl: false,
35             fadeDuration: 0,
36             zoomSnap: layer.options.isVectorStyle ? 0 : 1,
37             center: [center.lng, center.lat],
38             zoom: getZoomForMiniMap()
39           });
40
41           if (layer.options.layerId === "openmaptiles_osm") {
42             OSM.MapLibre.setOMTMapLanguage(miniMap);
43           }
44
45           map.on("moveend", moved);
46         }
47
48         function hide() {
49           map.off("moveend", moved);
50           miniMap.remove();
51         }
52
53         function moved() {
54           const center = map.getCenter();
55           const zoom = getZoomForMiniMap();
56           miniMap.easeTo({ center: [center.lng, center.lat], zoom });
57         }
58
59         function getZoomForMiniMap() {
60           return Math.max(Math.floor(map.getZoom() - 3), -1);
61         }
62       });
63
64       $(input).on("click", function () {
65         for (const other of layers) {
66           if (other !== layer) {
67             map.removeLayer(other);
68           }
69         }
70         map.addLayer(layer);
71       });
72
73       $(item).on("dblclick", toggle);
74
75       map.on("baselayerchange", function () {
76         input.checked = map.hasLayer(layer);
77       });
78     }
79
80     function initOverlays() {
81       $ui.find(".overlay-layers div.form-check").each(function () {
82         const item = this;
83         const layer = map[this.dataset.layerId];
84         const input = this.firstElementChild.firstElementChild;
85         $(item).tooltip("disable");
86
87         let checked = map.hasLayer(layer);
88
89         input.checked = checked;
90
91         $(input).on("change", function () {
92           checked = input.checked;
93           layer.cancelLoading?.();
94
95           if (checked) {
96             map.addLayer(layer);
97           } else {
98             map.removeLayer(layer);
99             $(`#layers-${name}-loading`).remove();
100           }
101         });
102
103         map.on("overlayadd overlayremove", function () {
104           input.checked = map.hasLayer(layer);
105         });
106
107         map.on("zoomend", function () {
108           const disabled = map.getBounds().getSize() >= item.dataset.maxArea;
109           input.disabled = disabled;
110
111           if (disabled && input.checked) {
112             input.click();
113             checked = true;
114           } else if (!disabled && !input.checked && checked) {
115             input.click();
116           }
117
118           item.classList.toggle("disabled", disabled);
119           $(item).tooltip(disabled ? "enable" : "disable");
120         });
121       });
122     }
123   };
124
125   return control;
126 };