@@ -13,6 +13,20 @@ const backgroundRasterUrlControl = document.getElementById('backgroundRasterUrl'
1313const legend = document . getElementById ( 'legend' )
1414const 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+
1630function facilitySearchQuery ( type , term ) {
1731 const encoded = encodeURIComponent ( term )
1832
@@ -67,20 +81,48 @@ function searchForMilestones(ref, position) {
6781}
6882
6983function 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
82123function hideSearchResults ( ) {
83124 searchResults . style . display = 'none' ;
125+ registerLastSearchResults ( [ ] ) ;
84126}
85127
86128function 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+
121170function showConfiguration ( ) {
122171 backgroundSaturationControl . value = configuration . backgroundSaturation ?? defaultConfiguration . backgroundSaturation ;
123172 backgroundOpacityControl . value = configuration . backgroundOpacity ?? defaultConfiguration . backgroundOpacity ;
0 commit comments