Skip to content

Commit f8487b2

Browse files
authored
Merge pull request #44 from OpenHistoricalMap/1153-add-style-layer-inspector
Addresses OpenHistoricalMap/issues#1153 by …
2 parents e403b02 + b28c9c6 commit f8487b2

3 files changed

Lines changed: 157 additions & 6 deletions

File tree

index.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#map {
2+
width: 100%;
3+
height:100%
4+
}
5+
6+
#popup {
7+
position: absolute;
8+
display: none;
9+
background: #fff;
10+
padding: 10px;
11+
border-radius: 6px;
12+
box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
13+
z-index: 10;
14+
max-width: 420px;
15+
font-family: monospace;
16+
font-size: 12px
17+
}
18+
19+
pre {
20+
background: #f6f6f6;
21+
padding: 6px;
22+
border-radius: 4px;
23+
overflow: auto;
24+
max-height: 140px
25+
}
26+
27+
.copy-btn {
28+
margin-left: 8px;
29+
border: 0;
30+
background: #eee;
31+
padding: 2px 6px;
32+
border-radius: 4px;
33+
cursor: pointer;
34+
font-size: 12px
35+
}
36+
37+
.layer-title {
38+
display: flex;
39+
align-items: center;
40+
justify-content: space-between;
41+
font-weight: 600;
42+
margin-bottom: 6px
43+
}
44+
45+
.layer-left {
46+
display: flex;
47+
align-items: center;
48+
gap: 8px
49+
}
50+
51+
button.close {
52+
margin-top: 8px
53+
}

index.html

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22
<head>
33
<script src="./node_modules/maplibre-gl/dist/maplibre-gl.js"></script>
44
<link href="./node_modules/maplibre-gl/dist/maplibre-gl.css" rel="stylesheet" />
5+
<link href="./index.css" rel="stylesheet" />
56
</head>
67
<body>
7-
<div id="map" style="width:100%;height:100%"></div>
8+
<div id="map"></div>
9+
<div id="popup">
10+
<div><strong>Style:</strong> <span id="s-name"></span></div>
11+
<div><strong>Style URL:</strong> <span id="s-url"></span></div>
12+
<hr/>
13+
<div id="layers"></div>
14+
<button id="close" class="close">Close</button>
15+
</div>
816

917
<script type="module">
1018
import StyleFlipperControl from "./node_modules/maplibre-gl-style-flipper/index.js";
@@ -31,7 +39,7 @@
3139
},
3240
};
3341

34-
var map = new maplibregl.Map({
42+
let map = new maplibregl.Map({
3543
container: 'map',
3644
style: mapStyles["historical"].url,
3745
center: [-74.033, 40.6259],
@@ -40,13 +48,103 @@
4048
})
4149

4250
// Create an instance of StyleFlipperControl
43-
const styleFlipperControl = new StyleFlipperControl(mapStyles);
51+
const flipper = new StyleFlipperControl(mapStyles);
4452

4553
// Set the initial style code
46-
styleFlipperControl.setCurrentStyleCode("historical");
54+
flipper.setCurrentStyleCode("historical");
4755

4856
// Add the control to the map
49-
map.addControl(styleFlipperControl, "bottom-right");
57+
map.addControl(flipper, "bottom-right");
58+
59+
const
60+
p = document.getElementById("popup"),
61+
sName = document.getElementById("s-name"),
62+
sUrl = document.getElementById("s-url"),
63+
layersEl = document.getElementById("layers"),
64+
closeBtn = document.getElementById("close")
65+
;
66+
67+
map.on("load", () => {
68+
map.on("click", (e) => {
69+
e.originalEvent.stopPropagation();
70+
const cur = flipper.currentStyleCode || "historical";
71+
sName.textContent = cur;
72+
sUrl.textContent = mapStyles[cur].url || "";
73+
74+
layersEl.innerHTML = "";
75+
const tol = 2;
76+
const bbox = [[e.point.x - tol, e.point.y - tol], [e.point.x + tol, e.point.y + tol]];
77+
const features = map.queryRenderedFeatures(bbox);
78+
79+
if (!features || features.length === 0) {
80+
layersEl.textContent = "No rendered features at this point.";
81+
} else {
82+
const byLayer = {};
83+
features.forEach(f => {
84+
const id = (f.layer && f.layer.id) ? f.layer.id : "(no-layer)";
85+
(byLayer[id] || (byLayer[id] = [])).push(f);
86+
});
87+
for (const lid of Object.keys(byLayer)) {
88+
const wrapper = document.createElement("div");
89+
const title = document.createElement("div");
90+
title.className = "layer-title";
91+
92+
const left = document.createElement("div");
93+
left.className = "layer-left";
94+
const nameSpan = document.createElement("span");
95+
nameSpan.textContent = `${lid}${byLayer[lid].length} feature(s)`;
96+
left.appendChild(nameSpan);
97+
98+
const copyBtn = document.createElement("button");
99+
copyBtn.className = "copy-btn";
100+
copyBtn.type = "button";
101+
copyBtn.innerText = "📋";
102+
copyBtn.title = "Copy layer id";
103+
copyBtn.dataset.layer = lid;
104+
105+
// copy handler
106+
copyBtn.addEventListener("click", async (ev) => {
107+
ev.stopPropagation(); // avoid closing popup
108+
try {
109+
await navigator.clipboard.writeText(lid);
110+
const prev = copyBtn.innerText;
111+
copyBtn.innerText = "Copied!";
112+
setTimeout(() => copyBtn.innerText = prev, 1200);
113+
} catch (err) {
114+
copyBtn.innerText = "Err";
115+
setTimeout(() => copyBtn.innerText = "📋", 1200);
116+
}
117+
});
118+
119+
left.appendChild(copyBtn);
120+
title.appendChild(left);
121+
122+
// append features props (only properties) below
123+
const propsDiv = document.createElement("div");
124+
byLayer[lid].forEach((feat, i) => {
125+
const pre = document.createElement("pre");
126+
pre.textContent = `feature ${i} id:${feat.id ?? "n/a"}\n` + JSON.stringify(feat.properties || {}, null, 2);
127+
propsDiv.appendChild(pre);
128+
});
129+
130+
title.style.marginBottom = "6px";
131+
wrapper.appendChild(title);
132+
wrapper.appendChild(propsDiv);
133+
layersEl.appendChild(wrapper);
134+
}
135+
}
136+
137+
p.style.left = (e.originalEvent.clientX + 10) + "px";
138+
p.style.top = (e.originalEvent.clientY + 10) + "px";
139+
p.style.display = "block";
140+
});
141+
});
142+
143+
// close handling: ignore clicks inside popup
144+
document.addEventListener("click", (ev) => {
145+
if (!p.contains(ev.target)) p.style.display = "none";
146+
});
147+
closeBtn.addEventListener("click", () => p.style.display = "none");
50148

51149
</script>
52150

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "module",
77
"scripts": {
88
"build": "scripts/prepare.js",
9-
"start": "browser-sync start --server --port 8888 --https --startPath #7.33/40.487/-73.554 --files ['historical/*', 'railway/*', 'japanese_scroll/*', 'woodblock/*']"
9+
"start": "browser-sync start --server --port 8888 --https --startPath #7.33/40.487/-73.554 --files ['index.html', 'index.css', 'historical/*', 'railway/*', 'japanese_scroll/*', 'woodblock/*']"
1010
},
1111
"repository": {
1212
"type": "git",

0 commit comments

Comments
 (0)