Topógrafos na Rede

Localize topógrafos e técnicos de cadastro por nome ou concelho utilizando as caixas de pesquisa. Pode também clicar em “Perto de mim” para centrar o mapa no local onde está.

Na lista à esquerda, clique num membro para ver a localização no mapa.

No mapa, clique num marcador para ver os dados de contacto.

`)); } function renderIframeList(){ const byC = {}; currentFiltered.forEach(m=>{ (byC[m._concelho] ||= []).push(m); }); let html = ''; if (!currentFiltered.length){ html = `
Sem resultados.
`; } else { Object.keys(byC).sort().forEach(c=>{ const arr = byC[c]; html += `

${escapeHtml(c)} (${arr.length})

`; arr.forEach(m=>{ const email = m.email ? String(m.email) : ''; const phone = m.telemovel ? String(m.telemovel) : ''; const phoneClean = cleanTel(phone); html += `
${escapeHtml(m.nome||'')}
`+ (email ? `` : ``) + (phone ? `` : ``) + `
`; }); html += `
`; }); html += ``; } iframeWrite(baseIframeHtml(html)); const doc = iframe.contentDocument || iframe.contentWindow.document; doc.querySelectorAll('.item').forEach(el=>{ el.addEventListener('click', ()=>{ const id = parseInt(el.getAttribute('data-id'),10); const m = all.find(x=>x._id===id); if (m) map.setView([m._lat,m._lng], Math.max(map.getZoom(), 11), {animate:true}); }); }); } // Helper: concelho selecionado (case-insensitive → devolve o label oficial ou '') function getSelectedConcelho(){ const val = (concelhoInput.value || '').trim().toLowerCase(); if (!val) return ''; const g = groups.find(x => String(x.concelho).toLowerCase() === val); return g ? g.concelho : ''; } // LISTA depende de Nome e Concelho selecionado let currentFiltered = []; function recomputeList(){ const fSearch = (document.getElementById('filter-search').value || ''); const nameTerms = normalizeStr(fSearch).split(' ').filter(Boolean); const concelhoSel = getSelectedConcelho(); // '' se não houver seleção válida currentFiltered = all.filter(m=>{ if (concelhoSel && m._concelho !== concelhoSel) return false; if (nameTerms.length){ const hay = normalizeStr(m.nome||''); for (let t of nameTerms){ if (!hay.includes(t)) return false; } } return true; }); if (currentFiltered.length === 0) renderIframeEmpty(); else renderIframeList(); } // ——— Autocomplete de Concelho (só recentra + filtra lista) ——— let acIndex = -1; let acOpen = false; function acBuildList() { const needle = (concelhoInput.value || '').toLowerCase().trim(); const set = new Set(); groups.forEach(g => { const name = String(g.concelho); if (!needle || name.toLowerCase().includes(needle)) set.add(name); }); const arr = Array.from(set).sort(); if (arr.length === 0) { acMenu.innerHTML = '
Sem correspondências
'; } else { acMenu.innerHTML = arr.map((name) => '
'+escapeHtml(name)+'
' ).join(''); } acMenu.querySelectorAll('.opt[role="option"]').forEach((el) => { el.addEventListener('mousedown', (ev) => { ev.preventDefault(); acSelect(el.getAttribute('data-val')); }); }); acIndex = -1; } function acOpenMenu() { if (acOpen) return; acOpen = true; acMenu.style.display = 'block'; concelhoInput.setAttribute('aria-expanded', 'true'); acBuildList(); } function acCloseMenu() { if (!acOpen) return; acOpen = false; acMenu.style.display = 'none'; concelhoInput.setAttribute('aria-expanded', 'false'); } function acFocus(idx) { acMenu.querySelectorAll('.opt[aria-selected="true"]').forEach(el=>el.setAttribute('aria-selected','false')); const els = acMenu.querySelectorAll('.opt[role="option"]'); if (!els.length) return; if (idx = els.length) idx = els.length - 1; acIndex = idx; const el = els[acIndex]; el.setAttribute('aria-selected','true'); el.scrollIntoView({ block:'nearest' }); } function acSelect(name) { concelhoInput.value = name || ''; acCloseMenu(); const c = concelhoToCoords[name]; if (c) map.setView([c.lat, c.lng], Math.max(map.getZoom(), 10), {animate:true}); recomputeList(); // { clearTimeout(acTimer); acTimer = setTimeout(() => { if (!acOpen) acOpenMenu(); else acBuildList(); }, 100); }); concelhoInput.addEventListener('keydown', (e) => { if (!acOpen && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) { acOpenMenu(); e.preventDefault(); return; } switch (e.key) { case 'ArrowDown': acFocus((acIndex { setTimeout(()=>{ acCloseMenu(); recomputeList(); }, 150); }); concelhoClearBtn.addEventListener('click', () => { concelhoInput.value = ''; acCloseMenu(); recomputeList(); // limpar → repõe lista (considerando pesquisa de nome) }); // Pesquisa por Nome → só a LISTA let searchTimer; searchInput.addEventListener('input', ()=>{ clearTimeout(searchTimer); searchTimer = setTimeout(()=>recomputeList(), 160); }); // Perto de mim (geolocalização) → apenas recentrar nearBtn.addEventListener('click', ()=>{ if (!navigator.geolocation) { alert('Geolocalização não suportada.'); return; } nearBtn.disabled = true; navigator.geolocation.getCurrentPosition((pos)=>{ const latlng = [pos.coords.latitude, pos.coords.longitude]; if (window._userMarker) map.removeLayer(window._userMarker); if (window._userCircle) map.removeLayer(window._userCircle); window._userMarker = L.circleMarker(latlng, { radius:6, weight:2, color:'#2563eb', fillColor:'#2563eb', fillOpacity:0.7 }).addTo(map); window._userCircle = L.circle(latlng, { radius: 15000, weight:1, color:'#2563eb', fillOpacity:0.05 }).addTo(map); map.setView(latlng, Math.max(map.getZoom(), 11), {animate:true}); nearBtn.disabled = false; }, (err)=>{ alert('Não foi possível obter localização ('+err.message+').'); nearBtn.disabled = false; }, { enableHighAccuracy:true, timeout:8000, maximumAge:0 }); }); // INIT map.setView(initialCenter, initialZoom); currentFiltered = all.slice(); // lista completa ao abrir renderIframeList(); })();
Scroll to Top