Геокодирование с использованием API Google Maps v3 и JQuery

Автор: | 20.03.2011

В этой заметке я расскажу на примере, как можно реализовать поиск по адресу с авто подстановкой результатов в строку поиска, с использованием API Google Maps v3 и инструмента геокодирования.

Пример реализует сразу две возможности: поиск адреса с авто подстановкой результата и определение адреса перемещением маркера по карте.

Пример работы

Разработка кода примера будет проходить в четыре этапа.

1. Мы создаем HTML-документ и подключаем к нему javascript-библиотеку JQuery и jQuery UI – виджет и интерактивная библиотека, созданная на основе библиотеки jQuery, данная библиотека (jQuery UI) будет использоваться для реализации эффекта автозаполнения.
2. Определяем параметры нашей карты, геокодера и маркера.
3. Определим код для обработки результатов геокодирования и установки маркера с результатом на карту
4. Определяем код слушателя события перемещения маркера по карте и обратного геокодирования.

И так в начале нам необходимо скачать файлы с библиотеками JQuery и положить их в папку js.

Последнюю версию javascript-библиотеки Jquery можно скачать на официальном сайте, а набор виджетов jQuery UI , либо с моего блога jquery-1.4.2.min.js и jquery-ui-1.8.1.custom.min.js.

На первом этапе у нас имеется следующий код:

<html> 
  <head> 
    <title>Геокодирование с использованием API Google Maps v3</title> 
 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> 
    <script type="text/javascript" src="js/jquery-ui-1.8.1.custom.min.js"></script> 
 
	</head> 
  <body> 
    <label>Адрес для поиска: </label><input id="address" style="width:600px;" type="text"/> 
    <div id="map_canvas" style="width:800px; height:600px"></div><br/> 
    <label>Широта (latitude): </label><input id="latitude" type="text"/><br/> 
    <label>Длогота (longitude): </label><input id="longitude" type="text"/> 
  </body> 
</html>

На втором этапе мы определяем параметры для нашей карты, геокодера и маркера

var geocoder;
var map;
var marker;
 
function initialize(){
//Определение карты
  var latlng = new google.maps.LatLng(56.329917,44.009191999999985);
  var options = {
    zoom: 15,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };
 
  map = new google.maps.Map(document.getElementById("map_canvas"), options);
 
  //Определение геокодера
  geocoder = new google.maps.Geocoder();
 
  marker = new google.maps.Marker({
    map: map,
    draggable: true
  });
 
}

Функцию инициализации мы будем выполнять тогда, когда документ полностью загрузиться

$(document).ready(function() { 
 
  initialize();
 
});

Следующий этап при вводе в поле поиска адреса происходит геокодирование его с эффектом автозаполнения, при выборе конкретного значения (двойной щелчек левой кнопкой мыши по нужному адресу) на карте размещается маркер, а в подля долгота и широта значения его координат.

За это отвечает следующий код

$(function() {
    $("#address").autocomplete({
      //Определяем значение для адреса при геокодировании
      source: function(request, response) {
        geocoder.geocode( {'address': request.term}, function(results, status) {
          response($.map(results, function(item) {
            return {
              label:  item.formatted_address,
              value: item.formatted_address,
              latitude: item.geometry.location.lat(),
              longitude: item.geometry.location.lng()
            }
          }));
        })
      },
      //Выполняется при выборе конкретного адреса
      select: function(event, ui) {
        $("#latitude").val(ui.item.latitude);
        $("#longitude").val(ui.item.longitude);
        var location = new google.maps.LatLng(ui.item.latitude, ui.item.longitude);
        marker.setPosition(location);
        map.setCenter(location);
      }
    });

Последняя функция отвечает за обработку события перетаскивания маркера по карте. При перемещении маркера по его координатам происходит обратное геокодирование и если адрес определен, он заноситься в поле поиска адреса.

Весь код примера:

<html> 
  <head> 
    <title>Геокодирование с использованием API Google Maps v3</title> 
 
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
    <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> 
    <script type="text/javascript" src="js/jquery-ui-1.8.1.custom.min.js"></script> 
	<style>
	.ui-autocomplete {
	background-color: white;
	width: 300px;
	border: 1px solid #cfcfcf;
	list-style-type: none;
	padding-left: 0px;
}
	</style>
 
 
<script type="text/javascript">
 
var geocoder;
var map;
var marker;
 
function initialize(){
//Определение карты
  var latlng = new google.maps.LatLng(56.329917,44.009191999999985);
  var options = {
    zoom: 15,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };
 
  map = new google.maps.Map(document.getElementById("map_canvas"), options);
 
  //Определение геокодера
  geocoder = new google.maps.Geocoder();
 
  marker = new google.maps.Marker({
    map: map,
    draggable: true
  });
 
}
 
$(document).ready(function() { 
 
  initialize();
 
  $(function() {
    $("#address").autocomplete({
      //Определяем значение для адреса при геокодировании
      source: function(request, response) {
        geocoder.geocode( {'address': request.term}, function(results, status) {
          response($.map(results, function(item) {
            return {
              label:  item.formatted_address,
              value: item.formatted_address,
              latitude: item.geometry.location.lat(),
              longitude: item.geometry.location.lng()
            }
          }));
        })
      },
      //Выполняется при выборе конкретного адреса
      select: function(event, ui) {
        $("#latitude").val(ui.item.latitude);
        $("#longitude").val(ui.item.longitude);
        var location = new google.maps.LatLng(ui.item.latitude, ui.item.longitude);
        marker.setPosition(location);
        map.setCenter(location);
      }
    });
  });
 
  //Добавляем слушателя события обратного геокодирования для маркера при его перемещении  
  google.maps.event.addListener(marker, 'drag', function() {
    geocoder.geocode({'latLng': marker.getPosition()}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        if (results[0]) {
          $('#address').val(results[0].formatted_address);
          $('#latitude').val(marker.getPosition().lat());
          $('#longitude').val(marker.getPosition().lng());
        }
      }
    });
  });
 
});
 
 
	</script> 
  </head> 
  <body> 
    <label>Адрес для поиска: </label><input id="address" style="width:600px;" type="text"/> 
    <div id="map_canvas" style="width:800px; height:600px"></div><br/> 
    <label>Широта (latitude): </label><input id="latitude" type="text"/><br/> 
    <label>Длогота (longitude): </label><input id="longitude" type="text"/> 
  </body> 
</html>

В заключении заметки несколько полезных ссылок с дополнительной информацией

Информация по работе с маркерами в API Google Maps v3

Процесс геокодирования в API Google Maps v3

JQuery UI — Демонстрация автозаполнения

Для написания заметки использовалась статья «Geocode with Google Maps API v3».

Геокодирование с использованием API Google Maps v3 и JQuery: 21 комментарий

  1. Андре

    Благодарность за подробный урок, наглядно информативно, а главное уникально.

  2. APS

    Как сделать так:
    при загрузке скрипт проверяет поля с координатами на пустоту, и если в них уже есть координаты, то он ставит метку на карту (приэтом сохранить геокодирование), заранее спасибо

  3. Roman

    Прикольно. Как раз искал такую фичу с авто дополнением для своего сайта.

  4. Garry

    Подскажите пожалуйста, как быть в такой ситуации?
    Мне не нужны поля для ввода адреса. Допустим я уже знаю адрес, а координаты мне как раз надо получить, тоесть интересуют latitude и longitude.
    С помощью описанной функции я могу их вычислить, но вот проблема их сохранить и передать с формой на сервер 🙁

    Делаю так. Есть два скрытых поля:

    Перед отправкой формы, вызывается функция:
    function calculateLatLng()
    { var geocoder = new google.maps.Geocoder();
    var form = window.document.getElementById(‘step1form’);
    var lat=»; var lng=»;
    var address = ‘формирую нужный адрес’;
    geocoder.geocode( { ‘address’: address}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK)
    { window.document.getElementById(‘lat’).value = results[0].geometry.location.lat();
    window.document.getElementById(‘lng’).value = results[0].geometry.location.lng();
    alert(‘lat: ‘+results[0].geometry.location.lat()+’nlng: ‘+results[0].geometry.location.lng()+’ninputLat: ‘+window.document.getElementById(‘lat’).value+’ninputLng: ‘+window.document.getElementById(‘lng’).value);
    }
    });
    }

    Так вот, что странно, если форму не отправлять, то я могу увидет алерт, видно, что координаты правильные я получил, но вот если форма отправляется, то даже алерт не выскакивает. Такое впечатление, что эта функция отработать не успевает как бы…
    Подскажите пожалуйста, где я ошибаюсь?

    1. admin Автор записи

      Нужно проверить правильность ID для соответствующих полей формы в которую передаются значения: lat и lng. Нет ли других ошибок в коде формы.
      Проверить в консоле ошибок Firefox

  5. Виктор

    У меня есть переменная с адресом, мне надо чтобы поиск производился по ней, не могу разобраться как код исправить. Моя переменная $adress, прописываю ее, но отображается океан, помогите пожалуйста, сама форма поиска адреса не нужна.

    1. admin Автор записи

      Вероятно перепутаны значения долготы и широты, попробуйте их поменять местами

  6. Саня

    Garry, отправлять форму необходимо не по клику Submit, а по событию внутри

    geocoder.geocode( { ‘address’: address}, function(results, status) {

    То есть сама функция calculateLatLng() должна возврящать false чтобы форма не отправлялась.

    Но тут получаеться, при вызове submit формы из объекта geocoder.geocode() — у нас снова вызоветься функция calculateLatLng()

    Тут я вижу два подхода для разрешения коллизии:
    1. Делаем триггер, по которому повторно не вызываеться объект geocoder.geocode()

    2. делаем вторую форму со скрытыми полями и при отработке
    geocoder.geocode( { ‘address’: address}, function(results, status) {

    мы переносим все значения полей формы 1 в форму 2 + координаты и уже эту вторую форму submitим

  7. Alex

    Здравствуйте! Столкнулся с тем, что google при геокодировании (использовал код этого примера) может выводить адреса используя разные языки, например, для Кипра выводить: Кипр, Κύπρος, Cyprus… в результате поиск объектов по запросу — Кипр не выдает объекты с другими вариантами написания этой страны…
    Никто с этой проблемой не сталкивался?
    Можно ли передавать, как координаты в этом примере, код страны числом?
    Очень нужно))) плз!!!

    1. admin Автор записи

      В строке подключения API есть не обязательственный параметр language, для русского языка language=ru, а также область локализации region.
      Подробности

  8. Inv

    А можно ли как-то вместо маркера или под маркером или рядом выводить допустим двухзначные данные?
    Ну допустим у меня стоят в разных зонах горда температурные датчики или еще чего, хочу чтобы визуально было видно.
    Сам не сильно силен в java и прочем, сейчас только учусь.

  9. mas

    Здравствуйте!
    Не подскажите: А как ограничить результаты выдачи только по городам?

  10. mas

    … прикольно конечно работает с описками….круто..
    но вот как автодополнение что-то мало результатов показывает…на последующих этапах…, как-то ложёво…на 4 букве
    на 5 букве вообще уходит в ступор…

    допустим
    москв:
    нет вариантов-

    а вот москяя….на те пожалуйства…Москва Россия..
    :((

  11. Дима

    Подскажите пожалуйста, как можно вставить фрейм карты с геокодингом в страницу wordpress(свой хостинг)??

  12. Кирилл

    Здравствуйте сори если пишу не совсем по теме но не нашел нормального форума по Google API

    Уменя есть задача нанести на одну карту несколько маршрутов

    тоесть есть массив в котором содержаться названия начальных и конечных точек маршрутов типа такого {«начало»=>»конец»}
    {«начало»=>»конец»}

    и надо проложить и нарисовать все эти маршруты на одной карте
    я пробовал через DirectionsRenderer но он выдает только 1 маршрут убирая предыдущий
    подскажите что делать?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *