Прямое геокодирование (Forward Geocoding) — процесс преобразования текстового описания места в географические координаты. В качестве входных данных могут выступать адреса, названия городов, стран, улиц, достопримечательностей, организаций и других объектов. Результатом работы геокодера становятся координаты широты и долготы, а также дополнительная информация о найденном объекте.
В экосистеме Mapbox прямое геокодирование выполняется через Geocoding API. В приложениях на базе Mapbox GL JS этот механизм позволяет:
Типичный сценарий работы выглядит следующим образом:
Для выполнения запросов требуется access token Mapbox.
Создание карты:
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [37.6176, 55.7558],
zoom: 10
});
После инициализации карты можно выполнять геокодирование через HTTP-запросы или готовый плагин поиска.
Базовый URL имеет следующий формат:
https://api.mapbox.com/geocoding/v5/mapbox.places/{search_text}.json
Пример запроса:
const query = 'Moscow';
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${query}.json?access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(data => {
console.log(data);
});
После выполнения запроса сервер возвращает JSON-документ с массивом найденных объектов.
Типичный ответ содержит поле features.
Пример сокращённого результата:
{
"type": "FeatureCollection",
"query": ["moscow"],
"features": [
{
"id": "place.123456",
"type": "Feature",
"place_name": "Moscow, Russia",
"center": [37.6176, 55.7558],
"geometry": {
"type": "Point",
"coordinates": [37.6176, 55.7558]
}
}
]
}
Наиболее важные поля:
| Поле | Назначение |
|---|---|
id |
Уникальный идентификатор объекта |
place_name |
Полное название объекта |
center |
Координаты центра |
geometry |
Геометрия объекта |
text |
Основное название |
properties |
Дополнительные свойства |
context |
Информация о регионе и стране |
Самая распространённая задача — извлечение координат найденного места.
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/London.json?access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(data => {
const place = data.features[0];
const longitude = place.center[0];
const latitude = place.center[1];
console.log(longitude, latitude);
});
Массив координат всегда содержит:
[longitude, latitude]
Порядок элементов критически важен. Ошибка в порядке координат приводит к отображению точки в неверном месте.
После получения координат карта может автоматически перейти к нужному месту.
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/Berlin.json?access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(data => {
const coordinates = data.features[0].center;
map.flyTo({
center: coordinates,
zoom: 13
});
});
Метод flyTo() создаёт плавную анимацию перемещения.
Параметры:
map.flyTo({
center: [13.405, 52.52],
zoom: 13,
speed: 1.5,
curve: 1.2,
essential: true
});
После геокодирования часто требуется показать результат на карте.
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/Paris.json?access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(data => {
const coordinates = data.features[0].center;
new mapboxgl.Marker()
.setLngLat(coordinates)
.addTo(map);
});
Дополнительно можно отобразить всплывающее окно.
const popup = new mapboxgl.Popup({
offset: 25
}).setText('Paris');
new mapboxgl.Marker()
.setLngLat(coordinates)
.setPopup(popup)
.addTo(map);
Современный подход предполагает применение
async/await.
async function geocode(placeName) {
const response = await fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${placeName}.json?access_token=${mapboxgl.accessToken}`
);
const data = await response.json();
return data.features[0];
}
Использование:
const place = await geocode('Rome');
console.log(place.place_name);
console.log(place.center);
Такой код легче читать и поддерживать.
По умолчанию поиск выполняется по всему миру.
Для повышения точности можно ограничить поиск конкретной страной.
Поиск только в Германии:
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/Berlin.json?country=de&access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(console.log);
Поиск сразу по нескольким странам:
country=de,fr,it
Пример:
https://api.mapbox.com/geocoding/v5/mapbox.places/Main%20Street.json?country=us,ca
Подобный подход уменьшает количество ложных совпадений.
Geocoding API умеет фильтровать результаты по категориям.
Поддерживаются типы:
| Тип | Описание |
|---|---|
| country | Страна |
| region | Регион |
| district | Район |
| place | Город |
| locality | Населённый пункт |
| neighborhood | Микрорайон |
| postcode | Почтовый индекс |
| address | Адрес |
| poi | Точка интереса |
Поиск только городов:
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/York.json?types=place&access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(console.log);
Поиск только адресов:
types=address
Поиск нескольких категорий:
types=address,poi
Результаты могут возвращаться на разных языках.
Пример русского языка:
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/London.json?language=ru&access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(console.log);
Пример английского языка:
language=en
Несколько языков:
language=ru,en
Это особенно полезно для международных проектов.
Параметр limit определяет максимальное число найденных
объектов.
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/New.json?limit=5&access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(console.log);
Результат будет содержать не более пяти объектов.
Иногда необходимо учитывать текущее положение пользователя.
Для этого используется параметр proximity.
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/Main%20Street.json?proximity=37.6176,55.7558&access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(console.log);
Результаты, расположенные ближе к указанным координатам, получают более высокий приоритет.
Это значительно улучшает качество поиска адресов.
Запрос может вернуть множество объектов.
fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/Springfield.json?access_token=${mapboxgl.accessToken}`
)
.then(response => response.json())
.then(data => {
data.features.forEach(place => {
console.log(place.place_name);
});
});
Создание маркеров для каждого результата:
data.features.forEach(place => {
new mapboxgl.Marker()
.setLngLat(place.center)
.addTo(map);
});
Подход удобен для отображения списка совпадений.
Простейший пример поиска по нажатию кнопки.
HTML:
<input id="search">
<button id="btn">Найти</button>
Jav * aScript:
document
.getElementById('btn')
.addEventListener('click', async () => {
const value =
document.getElementById('search').value;
const response = await fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${value}.json?access_token=${mapboxgl.accessToken}`
);
const data = await response.json();
if (!data.features.length) {
return;
}
const place = data.features[0];
map.flyTo({
center: place.center,
zoom: 14
});
});
После ввода адреса карта автоматически переходит к найденному месту.
Mapbox предоставляет готовый интерфейс поиска.
Подключение стилей:
<link
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.css"
rel="stylesheet">
Подключение скрипта:
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.min.js"></script>
Создание поискового элемента:
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl
});
map.addControl(geocoder);
После добавления контрола появляются:
Плагин генерирует событие result.
geocoder.on('result', event => {
console.log(event.result);
});
Получение координат:
geocoder.on('result', event => {
const coordinates =
event.result.center;
console.log(coordinates);
});
Получение полного адреса:
geocoder.on('result', event => {
console.log(
event.result.place_name
);
});
Ограничение поиска странами:
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
countries: 'us,ca'
});
Поиск только адресов:
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
types: 'address'
});
Ограничение числа результатов:
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
limit: 3
});
Установка языка:
const geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
language: 'ru'
});
Сетевые запросы должны сопровождаться обработкой исключений.
async function geocode(query) {
try {
const response = await fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${query}.json?access_token=${mapboxgl.accessToken}`
);
if (!response.ok) {
throw new Error('Ошибка API');
}
const data = await response.json();
return data.features;
} catch (error) {
console.error(error);
return [];
}
}
Подобная проверка предотвращает аварийное завершение приложения.
При поиске в режиме реального времени желательно уменьшать количество обращений к серверу.
Для этого применяется техника debounce.
function debounce(callback, delay) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
callback(...args);
}, delay);
};
}
Использование:
const search = debounce(async value => {
const response = await fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${value}.json?access_token=${mapboxgl.accessToken}`
);
const data = await response.json();
console.log(data);
}, 300);
Такой подход уменьшает нагрузку на API и повышает производительность интерфейса.
Прямое геокодирование активно используется в различных типах картографических приложений:
Во всех этих сценариях прямое геокодирование служит связующим звеном между текстовыми данными пользователя и пространственными координатами, позволяя быстро находить объекты и отображать их на интерактивной карте Mapbox GL JS.