|
149 | 149 | <map-link rel="query" data-query-link="true" tref="https://geo.weather.gc.ca/geomet/?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&LAYERS=CURRENT_CONDITIONS&QUERY_LAYERS=CURRENT_CONDITIONS&WIDTH={w}&HEIGHT={h}&FORMAT=image%2Fpng&TRANSPARENT=TRUE&INFO_FORMAT=application%2Fjson&STYLES={style}&CRS=EPSG:3978&BBOX={xmin},{ymin},{xmax},{ymax}&I={i}&J={j}"></map-link> |
150 | 150 | </map-extent> |
151 | 151 | </map-layer> |
| 152 | + <map-layer label="Photon Search" checked> |
| 153 | + <map-meta name="projection" content="CBMTILE"></map-meta> |
| 154 | + <map-link rel="suggestions" tref="https://photon.komoot.io/api?q={searchTerms}"></map-link> |
| 155 | + <map-link rel="search" tref="https://photon.komoot.io/api?q={searchTerms}"></map-link> |
| 156 | + </map-layer> |
152 | 157 | </mapml-viewer> |
153 | 158 | <map lang="fr" is="web-map" projection="OSMTILE" zoom="14" lat="45.406314" lon="-75.6883335" controls controlslist="geolocation search"> |
154 | 159 | <map-layer data-testid="osm-layer" label="OpenStreetMap" checked > |
|
190 | 195 | document.addEventListener('DOMContentLoaded', () => { |
191 | 196 | const viewer = document.querySelector('mapml-viewer'); |
192 | 197 |
|
193 | | - function renderGeonameResults(container, items, map) { |
| 198 | + function renderResults(container, responses, map) { |
194 | 199 | container.innerHTML = ''; |
195 | | - for (const item of items) { |
196 | | - const btn = document.createElement('button'); |
197 | | - btn.className = 'mapml-search-result'; |
198 | | - btn.setAttribute('type', 'button'); |
199 | | - btn.textContent = item.name |
200 | | - + (item.concise ? ' (' + item.concise.code + ')' : '') |
201 | | - + (item.province ? ', ' + item.province.code : ''); |
202 | | - btn.addEventListener('click', () => { |
203 | | - if (item.bbox && item.bbox.length === 4) { |
204 | | - const [west, south, east, north] = item.bbox; |
205 | | - map.fitBounds([[south, west], [north, east]]); |
206 | | - } else { |
207 | | - map.setView([item.latitude, item.longitude], 10); |
| 200 | + for (const r of responses) { |
| 201 | + const data = r.data; |
| 202 | + if (!data) continue; |
| 203 | + // geogratis format (items array) |
| 204 | + if (data.items) { |
| 205 | + for (const item of data.items) { |
| 206 | + const btn = document.createElement('button'); |
| 207 | + btn.className = 'mapml-search-result'; |
| 208 | + btn.setAttribute('type', 'button'); |
| 209 | + btn.textContent = item.name |
| 210 | + + (item.concise ? ' (' + item.concise.code + ')' : '') |
| 211 | + + (item.province ? ', ' + item.province.code : ''); |
| 212 | + btn.addEventListener('click', () => { |
| 213 | + if (item.bbox && item.bbox.length === 4) { |
| 214 | + const [west, south, east, north] = item.bbox; |
| 215 | + map.fitBounds([[south, west], [north, east]]); |
| 216 | + } else { |
| 217 | + map.setView([item.latitude, item.longitude], 10); |
| 218 | + } |
| 219 | + map._container |
| 220 | + .querySelector('.mapml-search-panel') |
| 221 | + .classList.remove('mapml-search-panel-open'); |
| 222 | + }); |
| 223 | + container.appendChild(btn); |
| 224 | + } |
| 225 | + } |
| 226 | + // GeoJSON format (Photon etc.) |
| 227 | + if (data.features) { |
| 228 | + for (const feature of data.features) { |
| 229 | + const props = feature.properties || {}; |
| 230 | + const parts = [props.name]; |
| 231 | + for (const key of ['city', 'county', 'state', 'country']) { |
| 232 | + if (props[key] && props[key] !== props.name) parts.push(props[key]); |
| 233 | + } |
| 234 | + const btn = document.createElement('button'); |
| 235 | + btn.className = 'mapml-search-result'; |
| 236 | + btn.setAttribute('type', 'button'); |
| 237 | + btn.textContent = parts.filter(Boolean).join(', ') || 'Unnamed'; |
| 238 | + btn.addEventListener('click', () => { |
| 239 | + const bbox = feature.bbox |
| 240 | + || (props.extent && props.extent.length === 4 ? props.extent : null); |
| 241 | + if (bbox && bbox.length === 4) { |
| 242 | + const [west, south, east, north] = bbox; |
| 243 | + map.fitBounds([[south, west], [north, east]]); |
| 244 | + } else if (feature.geometry && feature.geometry.coordinates) { |
| 245 | + const [lon, lat] = feature.geometry.coordinates; |
| 246 | + map.setView([lat, lon], props.zoom || 14); |
| 247 | + } |
| 248 | + map._container |
| 249 | + .querySelector('.mapml-search-panel') |
| 250 | + .classList.remove('mapml-search-panel-open'); |
| 251 | + }); |
| 252 | + container.appendChild(btn); |
208 | 253 | } |
209 | | - map._container |
210 | | - .querySelector('.mapml-search-panel') |
211 | | - .classList.remove('mapml-search-panel-open'); |
212 | | - }); |
213 | | - container.appendChild(btn); |
| 254 | + } |
214 | 255 | } |
215 | 256 | } |
216 | 257 |
|
217 | 258 | viewer.addEventListener('mapsuggestions', (e) => { |
218 | 259 | e.preventDefault(); |
219 | 260 | const container = viewer._map._container.querySelector('.mapml-search-results'); |
220 | | - const allItems = e.detail.responses.flatMap(r => (r.data && r.data.items) || []); |
221 | | - renderGeonameResults(container, allItems, viewer._map); |
| 261 | + renderResults(container, e.detail.responses, viewer._map); |
222 | 262 | }); |
223 | 263 |
|
224 | 264 | viewer.addEventListener('mapsearch', (e) => { |
225 | 265 | e.preventDefault(); |
226 | 266 | const container = viewer._map._container.querySelector('.mapml-search-results'); |
227 | | - const allItems = e.detail.responses.flatMap(r => (r.data && r.data.items) || []); |
228 | | - renderGeonameResults(container, allItems, viewer._map); |
| 267 | + renderResults(container, e.detail.responses, viewer._map); |
229 | 268 | }); |
230 | 269 |
|
231 | 270 | // --- geonames.org custom handler for the <map is="web-map"> element --- |
|
0 commit comments