1// å°åã»ä½ææ¤ç´¢ï¼Nominatim forward geocodingï¼ããã¿ã³ããå·¦ã«æ¤ç´¢çªãå±éãã 2// åè£ã¯ãªãã¯ã§ãã®å ´æã¸flyToããããããã¢ããã®å®å表示ï¼popup.jsï¼ã¨åã 3// Nominatimã使ããããã¡ãã¯éã¸ãªã³ã¼ãã£ã³ã°ï¼ç·¯åº¦çµåº¦âåç§°ï¼ã§ãã¡ã㯠4// é ã¸ãªã³ã¼ãã£ã³ã°ï¼å°åâ緯度çµåº¦ï¼ã¨ããéããããã 5const DEBOUNCE_MS = 400; 6 7export function initSearch(map) { 8 const btn = document.getElementById('search-toggle'); 9 const panel = document.getElementById('search-panel'); 10 const input = document.getElementById('search-input'); 11 const resultsEl = document.getElementById('search-results'); 12 13 let debounceTimer = null; 14 let currentToken = 0; 15 16 function openPanel() { 17 panel.classList.add('visible'); 18 btn.classList.add('on'); 19 input.focus(); 20 } 21 function closePanel() { 22 panel.classList.remove('visible'); 23 btn.classList.remove('on'); 24 input.value = ''; 25 resultsEl.innerHTML = ''; 26 } 27 28 btn.addEventListener('click', (e) => { 29 e.stopPropagation(); 30 if (panel.classList.contains('visible')) closePanel(); 31 else openPanel(); 32 }); 33 34 // ããã«å¤ã¯ãªãã¯ã§éãã 35 document.addEventListener('click', (e) => { 36 if (!panel.classList.contains('visible')) return; 37 if (panel.contains(e.target)) return; 38 closePanel(); 39 }); 40 41 input.addEventListener('keydown', (e) => { 42 if (e.key === 'Escape') closePanel(); 43 }); 44 45 input.addEventListener('input', () => { 46 clearTimeout(debounceTimer); 47 const q = input.value.trim(); 48 if (!q) { resultsEl.innerHTML = ''; return; } 49 debounceTimer = setTimeout(() => runSearch(q), DEBOUNCE_MS); 50 }); 51 52 async function runSearch(q) { 53 const myToken = ++currentToken; 54 resultsEl.innerHTML = '<div class="search-result-empty">æ¤ç´¢ä¸...</div>'; 55 let data; 56 try { 57 const url = `https://nominatim.openstreetmap.org/search?format=jsonv2&q=${encodeURIComponent(q)}&countrycodes=jp&accept-language=ja&limit=6`; 58 data = await fetch(url).then(r => r.json()); 59 } catch (e) { 60 if (myToken === currentToken) resultsEl.innerHTML = '<div class="search-result-empty">æ¤ç´¢ã«å¤±æãã¾ãã</div>'; 61 return; 62 } 63 if (myToken !== currentToken) return; // å ¥åä¸ã«å¤ãæ¤ç´¢çµæãè¿ã£ã¦ããå ´åã¯ç ´æ£ 64 if (!data.length) { 65 resultsEl.innerHTML = '<div class="search-result-empty">è¦ã¤ããã¾ããã§ãã</div>'; 66 return; 67 } 68 resultsEl.innerHTML = ''; 69 for (const d of data) { 70 const item = document.createElement('div'); 71 item.className = 'search-result-item'; 72 item.textContent = d.display_name; 73 item.addEventListener('click', () => { 74 map.flyTo({ center: [+d.lon, +d.lat], zoom: 14, duration: 1200 }); 75 closePanel(); 76 }); 77 resultsEl.appendChild(item); 78 } 79 } 80}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.