Skip to content

Commit 08097ed

Browse files
authored
1 parent 6fd6f27 commit 08097ed

File tree

4 files changed

+83
-13
lines changed

4 files changed

+83
-13
lines changed

proxy/css/ui.css

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ body {
2727
#search-results, #search-milestones-form {
2828
display: none;
2929
}
30-
#search-results .no-results {
31-
text-align: center;
32-
}
3330

3431
#legend {
3532
position: absolute;

proxy/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ <h5 class="modal-title">Search</h5>
9292
</div>
9393
</div>
9494
</form>
95-
<div class="list-group" id="search-results"></div>
95+
<div id="search-results"></div>
9696
</div>
9797
</div>
9898
</div>

proxy/js/styles.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,13 @@ const sources = {
889889
tileSize: 256,
890890
attribution: '<a href="https://www.openstreetmap.org/about" target="_blank">&copy; OpenStreetMap contributors</a>'
891891
},
892+
search: {
893+
type: 'geojson',
894+
data: {
895+
type: 'FeatureCollection',
896+
features: [],
897+
},
898+
},
892899
openrailwaymap_low: {
893900
type: 'vector',
894901
url: `${origin}/railway_line_low`,
@@ -954,6 +961,18 @@ const backgroundMap = {
954961
}
955962
};
956963

964+
const searchResults = {
965+
id: 'search',
966+
type: 'circle',
967+
source: 'search',
968+
paint: {
969+
'circle-radius': 8,
970+
'circle-color': 'rgba(183, 255, 0, 0.7)',
971+
'circle-stroke-width': 2,
972+
'circle-stroke-color': 'black',
973+
}
974+
};
975+
957976
// TODO remove all [switch, [zoom]] to ensure legend displays only visible features
958977
const layers = {
959978
standard: [
@@ -1838,6 +1857,7 @@ const layers = {
18381857
'text-padding': 10,
18391858
},
18401859
},
1860+
searchResults,
18411861
],
18421862

18431863
speed: [
@@ -2011,6 +2031,7 @@ const layers = {
20112031
'symbol-spacing': 100,
20122032
},
20132033
},
2034+
searchResults,
20142035
],
20152036

20162037
signals: [
@@ -2303,6 +2324,7 @@ const layers = {
23032324
],
23042325
}
23052326
},
2327+
searchResults,
23062328
],
23072329

23082330
electrification: [
@@ -2562,6 +2584,7 @@ const layers = {
25622584
'symbol-spacing': 100,
25632585
},
25642586
},
2587+
searchResults,
25652588
],
25662589

25672590
gauge: [
@@ -2839,6 +2862,7 @@ const layers = {
28392862
'symbol-spacing': 100,
28402863
},
28412864
},
2865+
searchResults,
28422866
],
28432867
};
28442868

proxy/js/ui.js

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ const backgroundRasterUrlControl = document.getElementById('backgroundRasterUrl'
1313
const legend = document.getElementById('legend')
1414
const legendMapContainer = document.getElementById('legend-map')
1515

16+
function registerLastSearchResults(results) {
17+
const data = {
18+
type: 'FeatureCollection',
19+
features: results.map(result => ({
20+
type: 'Feature',
21+
geometry: {
22+
type: 'Point',
23+
coordinates: [result.latitude, result.longitude],
24+
},
25+
})),
26+
};
27+
map.getSource('search').setData(data);
28+
}
29+
1630
function facilitySearchQuery(type, term) {
1731
const encoded = encodeURIComponent(term)
1832

@@ -67,20 +81,48 @@ function searchForMilestones(ref, position) {
6781
}
6882

6983
function showSearchResults(results, renderItem) {
70-
let content = '';
71-
if (results.length === 0) {
72-
content += `<div class="list-group-item no-results"><i>No results</i></div>`
73-
} else {
74-
results.forEach(result => {
75-
content += `<a class="list-group-item list-group-item-action" href="javascript:hideSearchResults(); map.easeTo({center: [${result.latitude}, ${result.longitude}], zoom: 15}); hideSearch()">${renderItem(result)}</a>`
76-
})
77-
}
78-
searchResults.innerHTML = content;
84+
registerLastSearchResults(results);
85+
86+
const bounds = results.length > 0
87+
? JSON.stringify(results.reduce(
88+
(bounds, result) =>
89+
bounds.extend({lat: result.longitude, lon: result.latitude}),
90+
new maplibregl.LngLatBounds({lat: results[0].longitude, lon: results[0].latitude})
91+
).toArray())
92+
: null;
93+
94+
searchResults.innerHTML = results.length === 0
95+
? `
96+
<div class="mb-1 d-flex align-items-center">
97+
<span class="flex-grow-1">
98+
<span class="badge badge-light">0 results</span>
99+
</span>
100+
</div>
101+
`
102+
: `
103+
<div class="mb-1 d-flex align-items-center">
104+
<span class="flex-grow-1">
105+
<span class="badge badge-light">${results.length} results</span>
106+
</span>
107+
<button class="btn btn-sm btn-primary" type="button" style="vertical-align: text-bottom" onclick="viewSearchResultsOnMap(${bounds})">
108+
<svg width="auto" height="16" viewBox="-4 0 36 36" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M14 0c7.732 0 14 5.641 14 12.6C28 23.963 14 36 14 36S0 24.064 0 12.6C0 5.641 6.268 0 14 0Z" fill="white"/><circle fill="var(--primary)" fill-rule="nonzero" cx="14" cy="14" r="7"/></g></svg>
109+
Show on map
110+
</button>
111+
</div>
112+
<div class="list-group">
113+
${results.map(result =>
114+
`<a class="list-group-item list-group-item-action" href="javascript:hideSearchResults(); map.easeTo({center: [${result.latitude}, ${result.longitude}], zoom: 15}); hideSearch()">
115+
${renderItem(result)}
116+
</a>`
117+
).join('')}
118+
</div>
119+
`;
79120
searchResults.style.display = 'block';
80121
}
81122

82123
function hideSearchResults() {
83124
searchResults.style.display = 'none';
125+
registerLastSearchResults([]);
84126
}
85127

86128
function showSearch() {
@@ -118,6 +160,13 @@ function searchMilestones() {
118160
hideSearchResults();
119161
}
120162

163+
function viewSearchResultsOnMap(bounds) {
164+
hideSearch();
165+
map.fitBounds(bounds, {
166+
padding: 40,
167+
});
168+
}
169+
121170
function showConfiguration() {
122171
backgroundSaturationControl.value = configuration.backgroundSaturation ?? defaultConfiguration.backgroundSaturation;
123172
backgroundOpacityControl.value = configuration.backgroundOpacity ?? defaultConfiguration.backgroundOpacity;

0 commit comments

Comments
 (0)