From 3f7e6604ea8e9fa0116534cc46ce79b4bd34e6a1 Mon Sep 17 00:00:00 2001 From: Mark Phillips Date: Wed, 14 Oct 2020 18:48:49 +0000 Subject: [PATCH] add search box --- mbgl-index.html | 20 +++++++++ mbgl-map.css | 79 ++++++++++++++++++++++++++++++++++++ mbgl-map.js | 105 +++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 189 insertions(+), 15 deletions(-) diff --git a/mbgl-index.html b/mbgl-index.html index c8ecf7b..5f47509 100644 --- a/mbgl-index.html +++ b/mbgl-index.html @@ -26,6 +26,26 @@ {% block content %}
+ + + +
Choose a location in the map to switch to 3D view. Then use mouse and W, A, S, D keys to move.
Cancel
diff --git a/mbgl-map.css b/mbgl-map.css index 57197e9..36ff4db 100644 --- a/mbgl-map.css +++ b/mbgl-map.css @@ -156,3 +156,82 @@ canvas.mapboxgl-canvas.crosshair-cursor { #cancel-3d-button:hover { background-color: #eeeeee; } + +#sidebar { + position: absolute; + width: 350px; + top: 0; + left: 0; + background-color: white; + padding: 0; + margin: 0; +} + +#search-box { + padding-top: 8px; + background-color: #eeeeee; + padding-bottom: 8px; +} + +#search-query-text { + border: 1px solid #ccc; + width: 280px; + height: 30px; + margin-left: 10px; +} + +#search-button { + height: 30px; + width: 30px; + display: inline-block; + background-color: #ed220d; + color: white; + line-height: 30px; + padding-left: 8px; + margin-right: 10px; + cursor: pointer; +} +#search-button:hover { + background-color: #8c1408; + color: #dddddd; +} + +#search-results { + position: relative; + border-top: 1px solid black; +} + +#search-results-close-button-wrapper { + position: relative; + width: 100%; + height: 25px; +} + +#search-results-close-button { + position: absolute; + right: 0px; + display: inline-block; + padding-left: 4px; + padding-right: 4px; + margin: 0; + font-size: 24px; +} + +#search-results-close-button:hover { + opacity: 0.3; + cursor: pointer; +} + +#search-results-results { + padding-top: 5px; + padding-bottom: 10px; + padding-right: 10px; +} + +#search-results-results ul { + padding-inline-start: 25px; +} + +#search-results-loading { + margin-left: 10px; +} diff --git a/mbgl-map.js b/mbgl-map.js index 396fd2d..415c089 100644 --- a/mbgl-map.js +++ b/mbgl-map.js @@ -176,20 +176,95 @@ document.addEventListener("DOMContentLoaded", function(){ timefilter.filter(currentYear); }); -// // idle is fired after sourcedata, is first fired when everything is initially set up. Might be used instead -// // of sourcedata, but initial idle takes a bit longer. Could be useful if there are multiple vector layers to load. -// map.once('idle', function() { -// //timefilter.filter(1850) -// }); -// -// // Get stats events listening. -// map.on('idle', function() { -// //timefilter.getStats('antique','buildings', 1800, 2020) -// }); -// map.on('sourcedata', function(e) { -// if (e.isSourceLoaded == true) { -// //stats = timefilter.getStats('antique','buildings', 1800, 2020) -// } -// }); + searchButton = document.getElementById("search-button"); + searchQueryText = document.getElementById("search-query-text"); + + searchButton.addEventListener("click", (e) => { + DoSearch(); + }); + searchQueryText.addEventListener("keydown", (e) => { + if (e.key == "Enter") { + DoSearch(); + } + }); + + searchResults = document.getElementById("search-results"); + searchResultsList = document.getElementById("search-results-list"); + searchResultsCloseButton = document.getElementById("search-results-close-button"); + searchResultsLoading = document.getElementById("search-results-loading"); + + function hideSearchResults() { + searchResults.classList.add('kartta-hidden'); + } + + searchResultsCloseButton.addEventListener("click", hideSearchResults); + + function searchResultsItem(text, url) { + const li = document.createElement("li"); + if (url) { + const a = document.createElement("a"); + a.setAttribute("href", url); + a.innerHTML = text; + a.addEventListener("click", hideSearchResults); + li.appendChild(a); + } else { + li.innerHTML = text; + } + return li; + } + + function BBoxToZoomLevel(bbox) { + // for now always use 13.5 + return 13.5; + } + + function searchResultsURL(item) { + return "/#" + BBoxToZoomLevel(item) + "/" + item.lat + "/" + item.lon; + } + + + function DoSearch() { + const query = searchQueryText.value; + const sanitizedQuery = sanitizeString(query); + const encodedSanitizedQuery = encodeURI(sanitizedQuery); + const bounds = map.getBounds(); + const viewbox = [bounds.getWest(),bounds.getSouth(),bounds.getEast(),bounds.getNorth()].join(','); + const url = 'https://nomina.re.city/search?format=json&extratags=1' + + '&q=' + encodedSanitizedQuery + + '&viewbox=' + viewbox + + '&accept-language=en-US,en'; + searchResults.classList.remove('kartta-hidden'); + searchResultsLoading.classList.remove("kartta-hidden"); + while (searchResultsList.firstChild) { + searchResultsList.removeChild(searchResultsList.firstChild); + } + + fetch(url) + .then(response => { + if (response.status === 200 || response.status === 0) { + return Promise.resolve(response.json()); + } else { + return Promise.reject(new Error(response.statusText)); + } + }) + .then(data => { + searchResultsLoading.classList.add("kartta-hidden"); + if (data.length == 0) { + searchResultsList.appendChild(searchResultsItem("No results found.")); + } + data.forEach(item => { + searchResultsList.appendChild(searchResultsItem(item.display_name, searchResultsURL(item))); + }); + }) + .catch(e => { + console.log(e); + }); + + } + + function sanitizeString(str){ + str = str.replace(/[^a-z0-9áéíóúñü \.,_-]/gim,""); + return str.trim(); + } });