v8: district list via Overpass API + Nominatim fallback
This commit is contained in:
parent
0606f947b1
commit
6bd858b709
81
index.html
81
index.html
@ -157,56 +157,81 @@ function init(){
|
||||
function onRegionChange(){
|
||||
const name=document.getElementById('regionSelect').value;
|
||||
const r=REGIONS.find(x=>x.name===name);
|
||||
if(!r){document.getElementById('districtSelect').innerHTML='<option value="">— все —</option>';return;}
|
||||
map.setView(r.center,9);
|
||||
document.getElementById('locStatus').textContent='⏳ загрузка районов...';
|
||||
// Загружаем районы области через Nominatim
|
||||
fetch('https://nominatim.openstreetmap.org/search?format=json&q='+encodeURIComponent('районы '+name+' области')+'&countrycodes=kz&limit=30')
|
||||
.then(r=>r.json()).then(data=>{
|
||||
const sel=document.getElementById('districtSelect');
|
||||
const names=new Set();
|
||||
sel.innerHTML='<option value="">— все —</option>';
|
||||
data.forEach(item=>{
|
||||
const match=item.display_name.match(/^([^,]+),\s*([^,]+)/);
|
||||
if(match){
|
||||
let dname=match[1].trim();
|
||||
if(!dname.endsWith('район')&&!dname.endsWith('ауданы'))return;
|
||||
dname=dname.replace(/\s*ауданы$/,'').replace(/\s*район$/,'');
|
||||
if(!names.has(dname)){
|
||||
names.add(dname);
|
||||
const o=document.createElement('option');
|
||||
o.value=dname;
|
||||
o.textContent=dname+(dname.endsWith('ский')||dname.endsWith('ской')?' район':'');
|
||||
sel.appendChild(o);
|
||||
}
|
||||
}
|
||||
if(!r){document.getElementById('locStatus').textContent='';return;}
|
||||
map.setView(r.center,9);
|
||||
document.getElementById('locStatus').textContent='⏳ районы...';
|
||||
// Overpass: ищем админ-границы 6-8 уровня внутри области
|
||||
const q='[out:json];(area["name"="'+name+' область"]["admin_level"~"[46]"];)->.a;(rel(area.a)["admin_level"~"[678]"];);out tags;';
|
||||
fetch('https://overpass-api.de/api/interpreter?data='+encodeURIComponent(q))
|
||||
.then(r=>r.json())
|
||||
.then(data=>{
|
||||
if(!data||!data.elements){document.getElementById('locStatus').textContent='нет данных';return;}
|
||||
const names=new Set();
|
||||
data.elements.forEach(el=>{
|
||||
if(!el.tags||!el.tags.name)return;
|
||||
let n=el.tags.name.replace(/\s*ауданы$/,'').replace(/\s*районы$/,'').replace(/\s*район$/,'').trim();
|
||||
if(n&&!names.has(n))names.add(n);
|
||||
});
|
||||
document.getElementById('locStatus').textContent='';
|
||||
if(names.size===0)document.getElementById('locStatus').textContent='районы не найдены';
|
||||
const sorted=[...names].sort();
|
||||
sorted.forEach(n=>{
|
||||
const o=document.createElement('option');
|
||||
o.value=n;
|
||||
o.textContent=n;
|
||||
sel.appendChild(o);
|
||||
});
|
||||
document.getElementById('locStatus').textContent=sorted.length?'✅ районы: '+sorted.length: '⚠ районы не найдены';
|
||||
if(sorted.length===0){
|
||||
// fallback: поищем через Nominatim
|
||||
fetch('https://nominatim.openstreetmap.org/search?format=json&q='+encodeURIComponent(name+' район')+'&countrycodes=kz&limit=20')
|
||||
.then(r=>r.json()).then(data2=>{
|
||||
if(!data2.length)return;
|
||||
data2.forEach(item=>{
|
||||
const nm=item.display_name.split(',')[0].trim();
|
||||
const o=document.createElement('option');
|
||||
o.value=nm;o.textContent=nm;
|
||||
sel.appendChild(o);
|
||||
});
|
||||
document.getElementById('locStatus').textContent='✅ через Nominatim: '+data2.length;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
function onDistrictSelect(){
|
||||
searchLocation();
|
||||
}
|
||||
function searchLocation(){
|
||||
const parts=[document.getElementById('regionSelect').value];
|
||||
const r=document.getElementById('regionSelect').value;
|
||||
const d=document.getElementById('districtSelect').value;
|
||||
const v=document.getElementById('villageInput').value.trim();
|
||||
if(d)parts.push(d+(d.endsWith('ский')||d.endsWith('ской')?' район':''));
|
||||
const parts=[];
|
||||
if(r)parts.push(r+' область');
|
||||
if(d)parts.push(d+' район');
|
||||
if(v)parts.push(v);
|
||||
const q=parts.join(', ');
|
||||
if(!q){showToast('Выберите область или введите село');return;}
|
||||
if(!q||!v&&!d){showToast('Введите название села');return;}
|
||||
// Если есть район но нет села — летим в центр района
|
||||
if(!v&&d){
|
||||
document.getElementById('locStatus').textContent='⏳ поиск района...';
|
||||
fetch('https://nominatim.openstreetmap.org/search?format=json&q='+encodeURIComponent(d+' район '+r+' область')+'&countrycodes=kz&limit=5')
|
||||
.then(r=>r.json()).then(data=>{
|
||||
if(!data.length){showToast('❌ Район не найден');document.getElementById('locStatus').textContent='';return;}
|
||||
map.setView([data[0].lat,data[0].lon],11);
|
||||
document.getElementById('locStatus').textContent='📍 '+data[0].display_name.split(',')[0];
|
||||
});
|
||||
return;
|
||||
}
|
||||
document.getElementById('locStatus').textContent='⏳ поиск...';
|
||||
fetch('https://nominatim.openstreetmap.org/search?format=json&q='+encodeURIComponent(q)+'&countrycodes=kz&limit=8')
|
||||
.then(r=>r.json()).then(data=>{
|
||||
if(!data.length){showToast('❌ Не найдено: '+q);document.getElementById('locStatus').textContent='не найдено';return;}
|
||||
if(!data.length){showToast('❌ Не найдено');document.getElementById('locStatus').textContent='не найдено';return;}
|
||||
const loc=data[0];
|
||||
map.setView([loc.lat,loc.lon],16);
|
||||
const name=loc.display_name.split(',')[0];
|
||||
showToast('📍 '+name);
|
||||
document.getElementById('villageInput').value=name;
|
||||
document.getElementById('locStatus').textContent=name;
|
||||
// Автозагрузка OSM данных
|
||||
setTimeout(autoDetect,500);
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user