Автозаполнение, прямое и обратное геокодирование

В примере представлены функции автозаполнения адреса, прямого и обратного геокодирования.
Используемые инструменты:
  • API GeoTree - принимает текстовую строку, географические координаты и возвращает ближайшие объекты к указанной точке.
  • Плагин jQuery Autocomplete - используется для автоподстановки (автодополнения) данных.
  • Leaflet - библиотека с открытым исходным кодом, написанная на JavaScript, предназначенная для отображения карт на веб-сайтах.
  • OpenStreetMap - загрузка тайлов карты (тайлы - небольшие изображения одинаковых размеров, которые и служат фрагментами большой картины).

Пример


Показать исходный код с комментариями
Открыть пример на отдельной странице

<!DOCTYPE html>
<html>
  <head>
    <title>Автозаполнение, прямое и обратное геокодирование</title>
    <link rel="stylesheet" href="https://files.geotree.ru/leaflet/leaflet-1.7.1.css">
    <link rel="stylesheet" href="https://files.geotree.ru/jquery/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://files.geotree.ru/jquery/jquery-1.12.4.js" defer></script>
    <script src="https://files.geotree.ru/jquery/ui/1.12.1/jquery-ui.js" defer></script>
    <script src="https://files.geotree.ru/leaflet/leaflet-1.7.1.js" defer></script>
    <style>
      .ui-autocomplete-loading {
        background: white url("https://files.geotree.ru/jquery/ui/images/ui-anim_basic_16x16.gif") right center no-repeat;
      }
    </style>
  </head>
  <body onload="page_loaded();">
    <div id="map" style="width: 100%; height: 100vh; z-index: 0;">
      <div id="info" style="position: absolute; z-index: 1000; width: calc(100% - 100px); left: 50px;">
        <input type="text" id="address" placeholder="Адрес" style="width: 100%; font-weight: bolder; padding: 5px; border-radius: 5px; margin-top: 5px;">
      </div>
    </div>
<script>
var URL_API="https://api.geotree.ru/address.php?";
function page_loaded() {
  myIcon = L.icon({ //параметры отображения маркера
    iconUrl: "https://files.geotree.ru/leaflet/markers/blue.png",
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [0, 0]
  });
  let center={lon: 37.6231, lat: 55.7525};
  map = L.map("map", {closePopupOnClick:false} ).setView(center, 12); //установить центр карты и масштаб
  L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
    maxZoom: 18,
    attribution: "&copy; <a href='https://openstreetmap.org/copyright'>OpenStreetMap contributors</a>"
  }).addTo(map);
  marker=L.marker(center, {icon: myIcon}).addTo(map); //установка маркера в центр карты
  popup=marker.bindPopup("").openPopup(); //добавление попапа к маркеру
  autocomplete_init(); //инициализация модуля Autocomplete
  map.on("moveend", map_onmoveend); //обработка события "завершение движение карты"
  map_onmoveend();
}

//Обработчик события завершения перемещения карты
function map_onmoveend() {
  autocomplete_set_source(); //установить URL для получения подсказок (учиытывая новые координаты центра карты)
  let center=map.getCenter();
  var url=URL_API+"limit=1&lon="+center.lng+"&lat="+center.lat; //URL для получения информации о ближайшем объекте
  jQuery.get(url)
  .done(function(data) {
    let item=data[0]; //ближайший найденный объект
    let value=item.value; //полное наименование
	$("#address").val(value);
    let geopoint=item_geopoint(item); //получение координат найденного объекта
    marker.setLatLng(geopoint).bindPopup(value); //перемещение маркера
  })
}

//Иницилизация параметров автозаполнения
function autocomplete_init() {
  $("#address").autocomplete({
    minLength: 0, //минимальное количество символов для отображения подсказок
    delay: 0, //задержка отображения подсказок
    select: autocomplete_select, //обработчик события выбора подсказки
	appendTo: "#info" //для корректной работы в полноэкранном режиме
  });
}


//Обработчик события выбора подсказки
function autocomplete_select(event, ui) {
  let geopoint=item_geopoint(ui.item); //координаты найденного объекта
  map.flyTo(geopoint); //перемещение карты
}

//Получение координат найденного объекта, в зависимости от его типа
function item_geopoint(item) {
  //в предоставленных подсказках могут быть адреса (type="address") и населённые пункты (type="place")
  if (item.type=="address") {
    return item.geo_inside;
  } else if (item.type=="place") {
    let level_info=item.levels[item.level];
    return level_info.geo_inside;
  }
}

function autocomplete_set_source() {
  //функция устанавливающая URL для получения подсказок
  let center=map.getCenter();
  //URL формируется из API ключа и координат центра карты
  $("#address").autocomplete("option", "source", URL_API+"lon="+center.lng+"&lat="+center.lat);
}

</script>
</body>
</html>
На весь экран