Реализация поиска по данным пользователя с использованием API Google Maps v3

Автор: | 13.06.2011

На своем блоге я как-то уже рассказывал в заметке «Реализация поиска по данным пользователя с использованием API Google Maps», как можно осуществить поиск по данным пользователя с использованием PHP и MySQL.

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

И так нам понадобятся файлы из уже упомянутой заметки:

index.html – содержит html и Java script код вывода карты и результатов поиска;

файл phpsqlinfo_dbinfo.php – служит для соединения с базой данных;

phpsqlsearch_genxml.php – в нем осуществляется поисковый запрос к таблице в базе данных и формируется XML-код с результатами поиска.

И файл файл markers.sql — для создания таблицы markers в базе данных и заполнения ее.

Скачать zip-архив с файлами.

Мы будем изменять файл index.html — основной файл с выводом карты.

Еще один важный момент, дело в том, что в третьей версии API Google Maps отсутствует функция для загрузки и разбора XML-файлов GdownloadUrl.

Поэтому для релизации необходимой функциональности мы будем использовать готовый скрипт файл downloadxml.js.

Загрузить его можно отсюда или с моего сайта.

И естественно его необходимо подключить для использования строкой:

<script type="text/javascript" src="downloadxml.js"></script>

Открываем файл index.html в текстовом редакторе, сохраняем его копию под новым именем, например, usersearch_gmapv3.html и начинаем его изменение.

Первое, что необходимо сделать — это изменить параметры для вызова API и определение начальных параметров карты.

Строку вызова API

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAACHCJdlgAEGcD_flKUFEmVhQlAYd20Yeej0MiKNuYPUGBnCwDThQlwUCPtCqtX3RC7LUKE-JYan3T4g"
            type="text/javascript"></script>

заменяем на

<script src="http://maps.google.com/maps/api/js?sensor=false"
            type="text/javascript"></script>

И сразу после нее добавляем строку для подключения файла downloadxml.js

<script type="text/javascript" src="downloadxml.js"></script>

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

var map, infoWindow;
 
var side_bar_html = ""; 
 
var gmarkers = new Array();
 
var infowindow = new google.maps.InfoWindow(
  { 
    size: new google.maps.Size(150,50)
});

Затем определяем начальные параметры для инициализации карты.

Вместо кода:

    function load() {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById('map'));
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        map.setCenter(new GLatLng(56.317213,43.993976), 12);
      }
    }

Пишем следующий код:

function initialize() {
      map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(56.317213,43.993976),
        zoom: 12,
        mapTypeId: 'roadmap',
        mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
      }); 
 infoWindow = new google.maps.InfoWindow();
}

И также нам нужно изменить код в теге body c

<body onload="load()" onunload="GUnload()">

на <body onload="initialize()">

Теперь мы должны изменить код функции searchLocations, в которой мы передаем поисковый запрос в скрипт phpsqlsearch_genxml.php и обрабатываем полученный ответ в виде XML-файла с параметрами для найденных меток.

Новый код функции searchLocations:

function searchLocations() {
     var name = document.getElementById('addressInput').value;
     var searchUrl = 'phpsqlsearch_genxml.php?name=' + name;
	downloadUrl(searchUrl, function(data) {
 
 	var marker;
    var xml = xmlParse(data);
    var markers = xml.documentElement.getElementsByTagName("marker");
    var bounds = new google.maps.LatLngBounds();
    clearOverlay();
 
    var sidebar = document.getElementById('sidebar');
    sidebar.innerHTML = '';
    if (markers.length == 0) {
        sidebar.innerHTML = 'Ничего не найдено.';
        return;
    } 
 
    for (var i = 0; i < markers.length; i++) {
    var name = markers[i].getAttribute('name');
    var address = '<strong>'+name+'</strong><br>'+markers[i].getAttribute('address');
 
    var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute('lat')),
                                 parseFloat(markers[i].getAttribute('lng')));         
    marker = createMarker(point, name, address);  
	bounds.extend(point);     
	}         
	map.fitBounds(bounds);
	document.getElementById("sidebar").innerHTML = side_bar_html; 
     });
   }

В начале функции мы берем введенное значение для поиска из элемента формы input с Id addressInput и передаем в файл phpsqlsearch_genxml.php.

После этого полученный ответ обрабатывается функцией downloadUrl.

Мы задаем значения для переменных и удаляем с карты предыдущие результаты поиска, вызывая функцию clearOverlay();

Также очищаем слайдбар, если ничего не найдено, то выводим соответствующие сообщение.

Иначе, мы формируем из полученных данных, маркеры на карте и ссылки в слайдбаре.

За это отвечает функция createMarker, которая получает в качестве входных параметров координаты точки, наименование маркера и содержимое балуна (в нашем случае html-код с именем и адресом).

Координаты точки добавляются в массив, для дальнейшего показа области с найденными данными (Bounds) на карте.

Код функции createMarker:

function createMarker(latlng, name, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        map: map        
        });
 
google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
});
 
gmarkers.push(marker);
side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '</a><br>';
}

В этой функции из преданных данных формируется маркер на карте, а по клику по маркеру открывается балун с необходимым содержанием.

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

Код функции myclick:

function myclick(i) {
  var latLng = gmarkers[i].getPosition();
  map.setCenter(latLng);
  map.setZoom(17);
  google.maps.event.trigger(gmarkers[i], "click");
}

И последняя фуккция clearOverlay:

function clearOverlay() {
     infoWindow.close();
     for (var i = 0; i < gmarkers.length; i++) {
       gmarkers[i].setMap(null);
     }
     gmarkers.length = 0;
 
     side_bar_html = "";
     document.getElementById("sidebar").innerHTML = side_bar_html;
   }

Здесь мы закрываем все открытие балуны infoWindow.close();, удаляем метки с карты, очищаем слайдбар.

Функциии createMarker и createSidebarEntry, которые использоваолись в старой версии файла, мы удаляем.

Окончательный код файла usersearch_gmapv3.html

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Пример поиск по своим данным с выводом на Google Maps v3</title> 
<script src="http://maps.google.com/maps/api/js?sensor=false"
            type="text/javascript"></script> 
<script type="text/javascript" src="downloadxml.js"></script> 
 
<script type="text/javascript"> 
var map, infoWindow;
 
var side_bar_html = ""; 
 
var gmarkers = new Array();
 
var infowindow = new google.maps.InfoWindow(
  { 
    size: new google.maps.Size(150,50)
});
 
function createMarker(latlng, name, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        map: map        
        });
 
google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
});
 
gmarkers.push(marker);
side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '</a><br>';
}
 
function initialize() {
      map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(56.317213,43.993976),
        zoom: 12,
        mapTypeId: 'roadmap',
        mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
      }); 
 infoWindow = new google.maps.InfoWindow();
}
 
function searchLocations() {
     var name = document.getElementById('addressInput').value;
     var searchUrl = 'phpsqlsearch_genxml.php?name=' + name;
	downloadUrl(searchUrl, function(data) {
 
 	var marker;
    var xml = xmlParse(data);
    var markers = xml.documentElement.getElementsByTagName("marker");
    var bounds = new google.maps.LatLngBounds();
    clearOverlay();
 
    var sidebar = document.getElementById('sidebar');
    sidebar.innerHTML = '';
    if (markers.length == 0) {
        sidebar.innerHTML = 'Ничего не найдено.';
        return;
    } 
 
    for (var i = 0; i < markers.length; i++) {
    var name = markers[i].getAttribute('name');
    var address = '<strong>'+name+'</strong><br>'+markers[i].getAttribute('address');
 
    var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute('lat')),
                                 parseFloat(markers[i].getAttribute('lng')));         
    marker = createMarker(point, name, address);  
	bounds.extend(point);     
	}         
	map.fitBounds(bounds);
	document.getElementById("sidebar").innerHTML = side_bar_html; 
     });
   }
 
function myclick(i) {
  var latLng = gmarkers[i].getPosition();
  map.setCenter(latLng);
  map.setZoom(17);
  google.maps.event.trigger(gmarkers[i], "click");
}
 
function clearOverlay() {
     infoWindow.close();
     for (var i = 0; i < gmarkers.length; i++) {
       gmarkers[i].setMap(null);
     }
     gmarkers.length = 0;
 
     side_bar_html = "";
     document.getElementById("sidebar").innerHTML = side_bar_html;
   } 
 
  </script> 
 
  <style type="text/css">
 
html, body { height: 100%; } 
 
font-family: Arial, Helvetica, sans-serif;
font-size: 10px;
</style>
 
 
  </head> 
 
  <body onload="initialize()"> 
<p> Поиск: <input type="text" id="addressInput"/> 
<input type="button" onclick="searchLocations()" value="Найти"/> 
</p> 
 
<div id="mymap_div" style="width:800px;"> 
<div id="sidebar" style="float:left; width: 200px; height: 500px; overflow: auto;"></div> 
<div id="map" style="margin-left: 200px; width: 600px; height:500px;"></div> 
</div> 
 
  </body> 
</html>

Посмотреть работу примера в действии

В форме поиска набираем — кафе.

Найденные результаты отображаются в боковой панели и виде маркеров на карте.

Щелкнув по одному из названий в панели с боку, например Безухов, арт-кафе ЗАО "Кофебук" , откроется окно с информацией о кафе и произойдет центрирование карты.

Реализация поиска по данным пользователя с использованием API Google Maps v3: 12 комментариев

  1. Drawer

    Сутки пытаюсь заставить работать скрипт — толку 0.
    В указанном Вами архиве файла index.html нет, вместо него я так понимаю usersearch_gmap.html. При попытке поиска кириллицей и латиницей названий кафе — выдает «Ничего не найдено». Смена кодировок в базе и файлах не дает результатов. Да кстати если указать неправильные данные БД, скрипт «проглатывает» и никаких результатов не выдает.
    Не могли бы Вы выложить все файлы окончательного варианта проекта?

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

      Архив с файлами проекта.
      Замечание, для корректной работы примера необходимо наличие PHP 5.
      Проверьте, создается ли и в каком виде XML-файл с результатами поиска в файле phpsqlsearch_genxml.php

  2. Николай

    Тоже уже вторые сутки пинаю скрипт — ничегошеньки.
    Уже и ручками по пунктам все переписывал и готовый заливал, и права триста раз переапроверял. Не работает.
    При попытке поиска — ничего не найдено.
    База есть. Коннект к ней верен.
    Вот что выдает
    phpsqlsearch_genxml.php :

    This page contains the following errors:

    error on line 1 at column 1: Document is empty
    Below is a rendering of the page up to the first error.

    Если чем-то можете помочь, буду очень рад. Так как в коде вообще ничего не смыслю — тупо перепечатываю символы ))
    Спасибо.

  3. Николай

    В IE — высыпается в ошибку: Invalid query: Table ‘wifi.markers_ussearch’ doesn’t exist
    БД — wifi

  4. Никита

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

  5. Андрей

    Добрый день!
    Решил построить карту именно на API 3, но решений по реализации поиска по типу API 2 или как на Яндекс.Картах я не нашел. Неужели нет возможности добавить на карту возможность поиска по карте обычным методом addControl или как это реализовано в API 3 через добавление элементов контроля?
    Буду благодарен за любую посказку. Сам уже кажется все просмотрел и перепробовал ничего не работает(((

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

      По каким данным осуществлять поиск? По своим меткам или по Google Maps?

  6. Александр

    А у меня так и не заработало. И данные базы правильные, и файлы в кодировке UTF-8 без BOM — не работает и всё. Выдаёт «Ничего не найдено». Что не так может быть? У Никиты, вижу, заработало?

  7. Александр

    В файле phpsqlsearch_genxml.php в запросе к базе убрал «WHERE MATCH ( name ) AGAINST(‘».$name.»‘ IN BOOLEAN MODE)» и заработало Почему так? Ну и название таблицы в нем не «markers_ussearch», а «markers».
    И еще вопрос. Как изначально на карте вывести все маркеры из базы?

  8. Александр

    а как в функции searchLocations()передать кроме категории и другие параметры для поиска?

    var minvalue = document.getElementById(‘minPrice’).value;
    var maxvalue = document.getElementById(‘maxPrice’).value;

    var searchUrl = ‘/modules/mod_ea_google/phpsqlsearch_genxml.php?cat=’+cat +’&minvalue=4000000&maxvalue=30000000’;

    У меня ничего не происходит.

  9. Александр

    Если поля для поиска заключить в теги (в данном примере их нету почему-то), — не работает. Почему?

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

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