Используем Google Places JavaScript на практике

Автор: | 26.09.2012

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

Что же эта за библиотека?

Google Places JavaScript позволяют вашему приложению выполнять поиск мест (под которыми в данном API понимаются учреждения, географические местоположения или достопримечательности), расположенных в определенной области, например на участке карты или около фиксированной точки.

В самом начале необходимо подключить библиотеку для использования.

Для этого нужно добавить параметр libraries=places в строку подключения API Google Maps v3.

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

Для примера мы создадим скрипт с возможностью поиска адресов и объектов, а также Вы можете настроить поиск с дополнительными параметрами: ключевое слово, тип объекта и радиус.

Весь код будет состоять из трех файлов:

index.html — основной файл с html-кодом разметки нашей страницы с картой;
script.js — файл содержащий весь JavaSript-код;
main.css — файл со стилями.

Вот полный код каждого файла.

Код файла index.html:

<!DOCTYPE html>
<html lang="en" >
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Используем Google Places JavaScript на практике</title>
        <link href="css/main.css" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="https://www.google.com/jsapi"></script>
        <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
        <script src="js/script.js"></script>
    </head>
    <body>
 
        <div id="container" class="container">
            <div id="gmap_canvas"></div>
            <div class="actions">
                <div class="button">
                    <label for="gmap_where">Найти:</label>
                    <input id="gmap_where" type="text" name="gmap_where" /></div>
                <div id="button2" class="button" onclick="findAddress(); return false;">Адрес</div>
                <div class="button">
                    <label for="gmap_keyword">Ключевое слово (optional):</label>
                    <input id="gmap_keyword" type="text" name="gmap_keyword" /></div>
                <div class="button">
                    <label for="gmap_type">Тип места:</label>
                    <select id="gmap_type">
                        <option value="art_gallery">Галереи</option>
                        <option value="atm">Банкоматы</option>
                        <option value="bank">Банк</option>
                        <option value="bar">Бар</option>
                        <option value="cafe">Кафе</option>
                        <option value="food">Закусочные</option>
                        <option value="hospital">Больница</option>
                        <option value="police">Полиция</option>
                        <option value="shop">Магазин</option>
                    </select>
                </div>
                <div class="button">
                    <label for="gmap_radius">Радиус:</label>
                    <select id="gmap_radius">
                        <option value="500">500</option>
                        <option value="1000">1000</option>
                        <option value="1500">1500</option>
                        <option value="5000">5000</option>
                    </select>
                </div>
                <input type="hidden" id="lat" name="lat" value="55.755786" />
                <input type="hidden" id="lng" name="lng" value="37.617633" />
                <div id="button1" class="button" onclick="findPlaces(); return false;">Найти организации</div>
            </div>
        </div>
    </body>
</html>

Код файла main.css:

*{
    margin:0;
    padding:0;
}
body {
    background-color:#EEEEEE;
    color:#fff;
    font:14px/1.3 Arial,sans-serif;
}
 
/* main styles */
.container {
    height: 700px;
    margin: 20px auto;
    position: relative;
    width: 900px;
}
#gmap_canvas {
    height: 700px;
    position: relative;
    width: 900px;
}
.actions {
    background-color: #FFFFFF;
    bottom: 30px;
    padding: 10px;
    position: absolute;
    right: 30px;
    z-index: 2;
 
    border-top: 1px solid #abbbcc;
    border-left: 1px solid #a7b6c7;
    border-bottom: 1px solid #a1afbf;
    border-right: 1px solid #a7b6c7;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
}
.actions label {
    display: block;
    margin: 2px 0 5px 10px;
    text-align: left;
}
.actions input, .actions select {
    width: 85%;
}
.button {
    background-color: #d7e5f5;
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d7e5f5), color-stop(100%, #cbe0f5));
    background-image: -webkit-linear-gradient(top, #d7e5f5, #cbe0f5);
    background-image: -moz-linear-gradient(top, #d7e5f5, #cbe0f5);
    background-image: -ms-linear-gradient(top, #d7e5f5, #cbe0f5);
    background-image: -o-linear-gradient(top, #d7e5f5, #cbe0f5);
    background-image: linear-gradient(top, #d7e5f5, #cbe0f5);
    border-top: 1px solid #abbbcc;
    border-left: 1px solid #a7b6c7;
    border-bottom: 1px solid #a1afbf;
    border-right: 1px solid #a7b6c7;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
    -webkit-box-shadow: inset 0 1px 0 0 white;
    -moz-box-shadow: inset 0 1px 0 0 white;
    box-shadow: inset 0 1px 0 0 white;
    color: #1a3e66;
    font: normal 11px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
    line-height: 1;
    margin-bottom: 5px;
    padding: 6px 0 7px 0;
    text-align: center;
    text-shadow: 0 1px 1px #fff;
    width: 150px;
}
.button:hover {
    background-color: #ccd9e8;
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ccd9e8), color-stop(100%, #c1d4e8));
    background-image: -webkit-linear-gradient(top, #ccd9e8, #c1d4e8);
    background-image: -moz-linear-gradient(top, #ccd9e8, #c1d4e8);
    background-image: -ms-linear-gradient(top, #ccd9e8, #c1d4e8);
    background-image: -o-linear-gradient(top, #ccd9e8, #c1d4e8);
    background-image: linear-gradient(top, #ccd9e8, #c1d4e8);
    border-top: 1px solid #a1afbf;
    border-left: 1px solid #9caaba;
    border-bottom: 1px solid #96a3b3;
    border-right: 1px solid #9caaba;
    -webkit-box-shadow: inset 0 1px 0 0 #f2f2f2;
    -moz-box-shadow: inset 0 1px 0 0 #f2f2f2;
    box-shadow: inset 0 1px 0 0 #f2f2f2;
    color: #163659;
    cursor: pointer;
}
.button:active {
    border: 1px solid #8c98a7;
    -webkit-box-shadow: inset 0 0 4px 2px #abbccf, 0 0 1px 0 #eeeeee;
    -moz-box-shadow: inset 0 0 4px 2px #abbccf, 0 0 1px 0 #eeeeee;
    box-shadow: inset 0 0 4px 2px #abbccf, 0 0 1px 0 #eeeeee;
}

Код файла script.js:

var geocoder;
var map;
var markers = Array();
var infos = Array();
 
function initialize() {
    // определяем геокодер
    geocoder = new google.maps.Geocoder();
 
	var myLatlng = new google.maps.LatLng(55.755786, 37.617633);
 
    var myOptions = { // параметры карты по умолчанию
        zoom: 14,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('gmap_canvas'), myOptions);
}
 
//функция удаления овелеев с карты
function clearOverlays() {
    if (markers) {
        for (i in markers) {
            markers[i].setMap(null);
        }
        markers = [];
        infos = [];
    }
}
 
// функция закрытия балунов с информацией
function clearInfos() {
    if (infos) {
        for (i in infos) {
            if (infos[i].getMap()) {
                infos[i].close();
            }
        }
    }
}
 
// функция поиска адреса
function findAddress() {
    var address = document.getElementById("gmap_where").value;
 
    // скрипт использует геокодер для определения местоположения по адресу
    geocoder.geocode( { 'address': address}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) { // и, если все в порядке
 
            // определяем новый центр карты
            var addrLocation = results[0].geometry.location;
			console.log(addrLocation);
            map.setCenter(addrLocation);
 
            // сохраняем координаты в скрытых перемееных
            document.getElementById('lat').value = results[0].geometry.location.lat();
            document.getElementById('lng').value = results[0].geometry.location.lng();
 
            // добавляем новую метку на карту
            var addrMarker = new google.maps.Marker({
                position: addrLocation,
                map: map,
                title: results[0].formatted_address,
                icon: 'marker.png'
            });
        } else {
            alert('Геокодирование было ошибочным, по следующим причинам: ' + status);
        }
    });
}
 
// функция поиска мест
function findPlaces() {
 
    // передаем значения для поиска переменным
    var type = document.getElementById('gmap_type').value;
    var radius = document.getElementById('gmap_radius').value;
    var keyword = document.getElementById('gmap_keyword').value;
 
    var lat = document.getElementById('lat').value;
    var lng = document.getElementById('lng').value;
    var cur_location = new google.maps.LatLng(lat, lng);
 
    // готовим запрос к Places
    var request = {
        location: cur_location,
        radius: radius,
        types: [type]
    };
    if (keyword) {
        request.keyword = [keyword];
    }
 
    // отправляем запрос
    service = new google.maps.places.PlacesService(map);
    service.search(request, createMarkers);
}
 
// добавляем метки
function createMarkers(results, status) {
    if (status == google.maps.places.PlacesServiceStatus.OK) {
 
        // удаляем предидущий результат с карты
        clearOverlays();
 
        // добавляем новые метки на карту
        for (var i = 0; i < results.length; i++) {
            createMarker(results[i]);
        }
    } else if (status == google.maps.places.PlacesServiceStatus.ZERO_RESULTS) {
        alert('Извините, ничего не найдено');
    }
}
 
// функция для добавления одной метки
function createMarker(obj) {
 
    // создаем новый объект
    var mark = new google.maps.Marker({
        position: obj.geometry.location,
        map: map,
        title: obj.name
    });
    markers.push(mark);
 
    // подготавливаем содержимое для балуна
    var infowindow = new google.maps.InfoWindow({
        content: '<img src="' + obj.icon + '" /><font style="color:#000;">' + obj.name + 
        '<br />Рейтинг: ' + obj.rating + '<br />Адрес: ' + obj.vicinity + '</font>'
    });
 
    // добавляем обработчик клика по метке
    google.maps.event.addListener(mark, 'click', function() {
        clearInfos();
        infowindow.open(map,mark);
    });
    infos.push(infowindow);
}
 
// инициализация
google.maps.event.addDomListener(window, 'load', initialize);

При задании начальных параметров для нашей карты, мы создаем пустой объект geocoder и начальное положение центра карты в Москве.

Для поиска мы вводим нужный адрес в поле (Брюсов переулок, 4), нажимаем на кнопку «Адрес» и скрипт, используя геокодирование определят нужный адрес на карте, отмечая его меткой.

Теперь мы можем начать поиск объектов с использованием API Places.

Функция findPlaces собирает в месте все введенные параметры (тип места, радиус, ключевое слово) , формирует запрос на PlacesService.

Полученный ответ фукция createMarker выводит на карту в виде группы меток.

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

Скачать архив с файлами примера

Подробнее о библиотеке Google Maps JavaScript API V3 Places можно прочитать в документации

Для написания заметки использовалась статья «Google Places API – practice».

Используем Google Places JavaScript на практике: 2 комментария

  1. Рома

    Спасибо, Админ, что внял просьбам! Это очень полезный и применимый урок. Только один минус — приходится ждать, пока Гугл пополнит свою базу по всем городам… Но зато потом будет красота…
    Еще вопрос: есть ли какое-либо ограничение по количеству запросов? Вроде что-то слышал о 10 000, или это не тот случай?

  2. Вова

    Спасибо.
    С Вашего позволения, укажу еще на один недостаток.
    При перемещении карты не пересчитывается центр карты, который указан при инициализации и следовательно не формируется заново массив искомых точек.
    Неплохо было бы объявить var CenterMarker и от него отталкиваться.

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

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