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

В этой заметке я расскажу на примере, как можно реализовать поиск по адресу с авто подстановкой результатов в строку поиска, с использованием 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».

  • Гость: че-то не пашет
  • Гость: в опере по крайней мере, firefox вроде норм
  • Гость: все пашет, надо было в опере user.js отрубить
  • Гость: Благодарность за подробный урок, наглядно информативно, а главное уникально.
  • Гость: Как сделать так: при загрузке скрипт проверяет поля с координатами на пустоту, и если в них уже есть координаты, то он ставит метку на карту (приэтом сохранить геокодирование), заранее спасибо
  • Гость: Прикольно. Как раз искал такую фичу с авто дополнением для своего сайта.
  • Гость: Подскажите пожалуйста, как быть в такой ситуации? Мне не нужны поля для ввода адреса. Допустим я уже знаю адрес, а координаты мне как раз надо получить, тоесть интересуют 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); } }); } Так вот, что странно, если форму не отправлять, то я могу увидет алерт, видно, что координаты правильные я получил, но вот если форма отправляется, то даже алерт не выскакивает. Такое впечатление, что эта функция отработать не успевает как бы... Подскажите пожалуйста, где я ошибаюсь?
  • Гость: Нужно проверить правильность ID для соответствующих полей формы в которую передаются значения: lat и lng. Нет ли других ошибок в коде формы. Проверить в консоле ошибок Firefox
  • Гость: У меня есть переменная с адресом, мне надо чтобы поиск производился по ней, не могу разобраться как код исправить. Моя переменная $adress, прописываю ее, но отображается океан, помогите пожалуйста, сама форма поиска адреса не нужна.
  • Гость: Вероятно перепутаны значения долготы и широты, попробуйте их поменять местами
  • Гость: 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им
  • Гость: Здравствуйте! Столкнулся с тем, что google при геокодировании (использовал код этого примера) может выводить адреса используя разные языки, например, для Кипра выводить: Кипр, Κύπρος, Cyprus... в результате поиск объектов по запросу - Кипр не выдает объекты с другими вариантами написания этой страны... Никто с этой проблемой не сталкивался? Можно ли передавать, как координаты в этом примере, код страны числом? Очень нужно))) плз!!!
  • Гость: В строке подключения API есть не обязательственный параметр language, для русского языка language=ru, а также область локализации region. <a href="http://code.google.com/intl/ru-RU/apis/maps/documentation/javascript/basics.html#Localization" rel="nofollow">Подробности</a>
  • Гость: А можно ли как-то вместо маркера или под маркером или рядом выводить допустим двухзначные данные? Ну допустим у меня стоят в разных зонах горда температурные датчики или еще чего, хочу чтобы визуально было видно. Сам не сильно силен в java и прочем, сейчас только учусь.
  • Гость: Здравствуйте! Не подскажите: А как ограничить результаты выдачи только по городам?
  • Гость: ... прикольно конечно работает с описками....круто.. но вот как автодополнение что-то мало результатов показывает...на последующих этапах..., как-то ложёво...на 4 букве на 5 букве вообще уходит в ступор... допустим москв: нет вариантов- а вот москяя....на те пожалуйства...Москва Россия.. :((
  • Гость: Спасибо, отличный рабочий пример!
  • Гость: Подскажите пожалуйста, как можно вставить фрейм карты с геокодингом в страницу wordpress(свой хостинг)??
  • Гость: Спасибо, очень пригодилось!
  • Гость: Здравствуйте сори если пишу не совсем по теме но не нашел нормального форума по Google API Уменя есть задача нанести на одну карту несколько маршрутов тоесть есть массив в котором содержаться названия начальных и конечных точек маршрутов типа такого {"начало"=&gt;"конец"} {"начало"=&gt;"конец"} и надо проложить и нарисовать все эти маршруты на одной карте я пробовал через DirectionsRenderer но он выдает только 1 маршрут убирая предыдущий подскажите что делать?
  • Гость: С jQuery v1.8.3 jquery.com уже не работает пример