Skip to content

Commit 6d1519e

Browse files
authoredMar 3, 2025··
add point query on right-click to map viewer (#1100)
1 parent 28d33a6 commit 6d1519e

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed
 

‎CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
* add `output_min` and `output_max` metadata attributes to `slope` algorithm (@tayden, https://github.com/developmentseed/titiler/pull/1089)
88

9+
* add point value query on right-click to map viewer (@hrodmn, https://github.com/developmentseed/titiler/pull/1100)
10+
911
## 0.21.1 (2025-01-29)
1012

1113
### titiler.core

‎src/titiler/core/titiler/core/factory.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -970,15 +970,19 @@ def map_viewer(
970970
tilejson_url = self.url_for(
971971
request, "tilejson", tileMatrixSetId=tileMatrixSetId
972972
)
973+
point_url = self.url_for(request, "point", lon="{lon}", lat="{lat}")
973974
if request.query_params._list:
974-
tilejson_url += f"?{urlencode(request.query_params._list)}"
975+
params = f"?{urlencode(request.query_params._list)}"
976+
tilejson_url += params
977+
point_url += params
975978

976979
tms = self.supported_tms.get(tileMatrixSetId)
977980
return self.templates.TemplateResponse(
978981
request,
979982
name="map.html",
980983
context={
981984
"tilejson_endpoint": tilejson_url,
985+
"point_endpoint": point_url,
982986
"tms": tms,
983987
"resolutions": [matrix.cellSize for matrix in tms],
984988
},

‎src/titiler/core/titiler/core/templates/map.html

+65
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,71 @@
221221
.catch(err => {
222222
console.warn(err);
223223
});
224+
225+
// run point query on right-click
226+
map.on('contextmenu', function(e) {
227+
const lat = e.latlng.lat.toFixed(3);
228+
const lng = e.latlng.lng.toFixed(3);
229+
230+
const popup = L.popup()
231+
.setLatLng(e.latlng)
232+
.setContent("<p>Loading point data...</p>")
233+
.openOn(map);
234+
235+
fetch(`{{ point_endpoint|safe }}`.replace('{lat}', lat).replace('{lon}', lng))
236+
.then(res => {
237+
if (res.ok) return res.json();
238+
239+
return res.json().then(errorData => {
240+
const error = new Error(errorData.detail || `Server error: ${res.status}`);
241+
error.status = res.status;
242+
error.errorData = errorData;
243+
throw error;
244+
})
245+
})
246+
.then(data => {
247+
const formatPopupContent = (data) => {
248+
let html = '<div style="max-width: 250px;">';
249+
250+
html += `<p><strong>Coordinates:</strong> ${lat}, ${lng}</p>`;
251+
252+
// single band case - just show the value
253+
if (data.band_names.length === 1) {
254+
const value = data.values[0] !== null ? data.values[0] : 'No data';
255+
html += `<p><strong>Value:</strong> ${value}</p>`;
256+
}
257+
// multiple bands case - show in a table
258+
else {
259+
html += '<table style="width: 100%; border-collapse: collapse;">';
260+
html += '<tr><th style="text-align: left; padding: 1px; border-bottom: 1px solid #ddd;">Band</th>' +
261+
'<th style="text-align: right; padding: 1px; border-bottom: 1px solid #ddd;">Value</th></tr>';
262+
263+
for (let i = 0; i < data.band_names.length; i++) {
264+
const value = data.values[i] !== null ? data.values[i] : 'No data';
265+
html += `<tr>
266+
<td style="text-align: left; padding: 1px;">${data.band_names[i]}</td>
267+
<td style="text-align: right; padding: 1px;">${value}</td>
268+
</tr>`;
269+
}
270+
271+
html += '</table>';
272+
}
273+
274+
html += '</div>';
275+
return html;
276+
};
277+
278+
popup.setContent(formatPopupContent(data));
279+
})
280+
.catch(err => {
281+
if (err.errorData && err.errorData.detail) {
282+
popup.setContent(`<p>${err.errorData.detail}</p>`);
283+
} else {
284+
popup.setContent(`<p>Error: ${err.message || 'An unknown error occurred'}</p>`);
285+
}
286+
});
287+
});
288+
224289
</script>
225290
</body>
226291
</html>

0 commit comments

Comments
 (0)
Please sign in to comment.