Задача: реализовать поиск по картам Яндекс с проверкой запроса и подсказками от геосаджеста. Перерисовать карту так, чтобы в центре был найденный объект. Учитывая тип объекта (дом, улица, город, область и пр.) изменить масштаб карты.
Дано: Яндекс карты на сайте с массивом точек.
Результат:
Полный код доступен в файле scripts.js
Алгоритм:
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&apikey=<ключ геокодера>&suggest_apikey=<ключ геосаджеста>"></script>
ymaps.init()
function init(){
myMap = new ymaps.Map("map", {
center: [55.76, 37.64],
zoom: 10,
easing: 'ease-in-out',
duration: 200,
controls: []
});
myMap.controls.add('zoomControl', {
size: 'small',
float: 'none',
position: {
bottom: '30px',
right: '10px'
}
});
}
const pointsList = [
{
"city": "Название города (заголовок)",
"address": "Адрес (описание)",
"pos": "Координаты (долгота широта)"
},
...
]
Добавление точек:
let locationMapData = {
"type": "FeatureCollection",
"features": []
}
pointsList.forEach((point, i) => {
if(point.pos != 'error' && point.pos != 'notFound' ) {
let ft = {
type: 'Feature',
id: point.hasOwnProperty("city") && point.city.replaceAll('"', '"') + i + 'id',
geometry: {
type: 'Point',
coordinates: [point.pos.split(' ')[1], point.pos.split(' ')[0]]
},
properties: {
balloonContentHeader: point.hasOwnProperty("city") && point.city.replaceAll('"', '"'),
balloonContentBody: `${point.address.replaceAll('"', '"')}
`
},
options: {
preset: 'islands#dotIcon',
iconColor: '#000000'
}
}
locationMapData["features"].push(ft)
}
})
searchInput.addEventListener("input", function(e){
const { value } = e.target
const debouncedSearch = debounce(search, 350)
if(value.length > 3){
debouncedSearch(value)
}
})
function search(query){
ymaps.suggest(query).then(function (items) {
renderResults(items)
});
}
function debounce(callee, timeoutMs) {
return function perform(...args) {
let previousCall = this.lastCall
this.lastCall = Date.now()
if (previousCall && this.lastCall - previousCall <= timeoutMs) {
clearTimeout(this.lastCallTimer)
}
this.lastCallTimer = setTimeout(() => callee(...args), timeoutMs)
}
}
function renderResults(items){
const root = document.querySelector(".suggestResults")
root.innerHTML = ''
items.forEach(({displayName, value}) => {
const item = document.createElement('a')
item.setAttribute("href", "#")
item.classList.add("list-group-item", "list-group-item-action")
item.innerHTML = displayName
root.append(item)
item.addEventListener('click', function(e){
e.preventDefault()
runGeocoder(value)
root.innerHTML = ''
searchInput.value = displayName
})
})
}
function runGeocoder(value){
let myGeocoder = ymaps.geocode(value, {
json: true
});
myGeocoder.then(
function (res) {
const zoom = {
house: 16,
street: 15,
metro: 15,
district: 11,
province:10,
locality: 9
}
const kind = res.GeoObjectCollection.featureMember[0].GeoObject.metaDataProperty
.GeocoderMetaData.kind
const coords = res.GeoObjectCollection.featureMember[0].GeoObject.Point.pos.split(" ").map(el => parseFloat(el)).reverse()
myMap.setCenter(coords, zoom[kind])
},
function (err) {
console.error(err)
}
);
}
Если вдруг для вас страница оказалась полезной: