v8: district list via Overpass API + Nominatim fallback

This commit is contained in:
Dauren777 2026-06-19 06:28:02 +00:00
parent 0606f947b1
commit 6bd858b709

View File

@ -157,56 +157,81 @@ function init(){
function onRegionChange(){ function onRegionChange(){
const name=document.getElementById('regionSelect').value; const name=document.getElementById('regionSelect').value;
const r=REGIONS.find(x=>x.name===name); 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 sel=document.getElementById('districtSelect');
const names=new Set();
sel.innerHTML='<option value="">— все —</option>'; sel.innerHTML='<option value="">— все —</option>';
data.forEach(item=>{ if(!r){document.getElementById('locStatus').textContent='';return;}
const match=item.display_name.match(/^([^,]+),\s*([^,]+)/); map.setView(r.center,9);
if(match){ document.getElementById('locStatus').textContent='⏳ районы...';
let dname=match[1].trim(); // Overpass: ищем админ-границы 6-8 уровня внутри области
if(!dname.endsWith('район')&&!dname.endsWith('ауданы'))return; const q='[out:json];(area["name"="'+name+' область"]["admin_level"~"[46]"];)->.a;(rel(area.a)["admin_level"~"[678]"];);out tags;';
dname=dname.replace(/\s*ауданы$/,'').replace(/\s*район$/,''); fetch('https://overpass-api.de/api/interpreter?data='+encodeURIComponent(q))
if(!names.has(dname)){ .then(r=>r.json())
names.add(dname); .then(data=>{
const o=document.createElement('option'); if(!data||!data.elements){document.getElementById('locStatus').textContent='нет данных';return;}
o.value=dname; const names=new Set();
o.textContent=dname+(dname.endsWith('ский')||dname.endsWith('ской')?' район':''); data.elements.forEach(el=>{
sel.appendChild(o); 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=''; const sorted=[...names].sort();
if(names.size===0)document.getElementById('locStatus').textContent='районы не найдены'; 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(){ function onDistrictSelect(){
searchLocation(); searchLocation();
} }
function searchLocation(){ function searchLocation(){
const parts=[document.getElementById('regionSelect').value]; const r=document.getElementById('regionSelect').value;
const d=document.getElementById('districtSelect').value; const d=document.getElementById('districtSelect').value;
const v=document.getElementById('villageInput').value.trim(); 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); if(v)parts.push(v);
const q=parts.join(', '); 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='⏳ поиск...'; document.getElementById('locStatus').textContent='⏳ поиск...';
fetch('https://nominatim.openstreetmap.org/search?format=json&q='+encodeURIComponent(q)+'&countrycodes=kz&limit=8') fetch('https://nominatim.openstreetmap.org/search?format=json&q='+encodeURIComponent(q)+'&countrycodes=kz&limit=8')
.then(r=>r.json()).then(data=>{ .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]; const loc=data[0];
map.setView([loc.lat,loc.lon],16); map.setView([loc.lat,loc.lon],16);
const name=loc.display_name.split(',')[0]; const name=loc.display_name.split(',')[0];
showToast('📍 '+name); showToast('📍 '+name);
document.getElementById('villageInput').value=name; document.getElementById('villageInput').value=name;
document.getElementById('locStatus').textContent=name; document.getElementById('locStatus').textContent=name;
// Автозагрузка OSM данных
setTimeout(autoDetect,500); setTimeout(autoDetect,500);
}); });
} }