Maps JavaScript API версии 2 не используется с 26 мая 2021 года. Если на вашем сайте есть карты, которые используют эту версию, они перестанут работать и будут возвращать ошибки JavaScript. Чтобы продолжить пользоваться этими картами, перейдите на Maps JavaScript API версии 3. Это руководство поможет вам выполнить необходимые действия.
Обзор
Процесс переноса для каждого приложения будет немного отличаться, однако есть несколько шагов, общих для всех проектов:
- Приобретите новый ключ. Теперь для управления ключами Maps JavaScript API используется консоль Google Cloud. Если вы все ещё используете ключ версии 2, обязательно получите новый ключ API, прежде чем начинать перенос.
- Обновите начальную загрузку API. В большинстве приложений Maps JavaScript API версии 3 загружается с помощью следующего кода:
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
- Обновите код. Объем необходимых изменений будет во многом зависеть от вашего приложения. Вот некоторые из них:
- Всегда ссылайтесь на пространство имен google.maps. В версии 3 весь код Maps JavaScript API хранится в пространстве имен
google.maps.*, а не в глобальном пространстве имен. В рамках этого процесса большинство объектов также было переименовано. Например, вместо GMap2 теперь будет загружаться google.maps.Map.
- Удалите все ссылки на устаревшие методы. Удален ряд служебных методов общего назначения, таких как
GDownloadURL и GLog.
Замените эту функцию сторонними служебными библиотеками или удалите эти ссылки из кода.
- Добавьте библиотеки в код(необязательно). Многие функции были вынесены в библиотеки утилит, чтобы каждое приложение загружало только те части API, которые будут использоваться.
- (Необязательно.) Настройте проект для использования внешних файлов v3.
Внешние файлы версии 3 можно использовать для проверки кода с помощью Closure Compiler или для активации автозаполнения в IDE.
Подробнее
о расширенной компиляции и внешних файлах…
- Тестируйте и повторяйте. На этом этапе вам ещё предстоит кое-что сделать, но хорошая новость заключается в том, что вы уже будете на пути к новому приложению с картами v3.
Изменения в Maps JavaScript API версии 3
Прежде чем планировать переход, ознакомьтесь с различиями между Maps JavaScript API v2 и Maps JavaScript API v3. Новейшая версия Maps JavaScript API была написана с нуля с акцентом на современные методы программирования на JavaScript, более широкое использование библиотек и упрощенный API.
В API добавлено много новых функций, а некоторые из уже существующих были изменены или удалены. В этом разделе описаны некоторые ключевые различия между двумя выпусками.
Ниже приведены некоторые из изменений в API v3.
- Оптимизированная базовая библиотека. Многие дополнительные функции были перенесены в библиотеки, что позволило сократить время загрузки и синтаксического анализа Core API. Благодаря этому карты быстро загружаются на любых устройствах.
- Улучшена производительность некоторых функций, таких как отрисовка многоугольников и размещение маркеров.
- Новый подход к клиентским лимитам на использование, который лучше подходит для общих адресов, используемых мобильными прокси-серверами и корпоративными брандмауэрами.
- Добавлена поддержка нескольких современных браузеров и мобильных браузеров. Поддержка Internet Explorer 6 прекращена.
- Удалены многие вспомогательные классы общего назначения (
GLog или
GDownloadUrl). Сегодня существует множество отличных библиотек JavaScript, которые предоставляют аналогичные функции, например Closure или jQuery.
- Просмотр улиц в HTML5 с возможностью загрузки на любом мобильном устройстве.
- Пользовательские панорамы в Просмотре улиц, созданные на основе ваших фотографий. С их помощью можно показывать горнолыжные склоны, дома, выставленные на продажу, и другие интересные места.
- Стилизованные карты позволяют изменять внешний вид элементов на базовой карте в соответствии с вашим уникальным визуальным стилем.
- Поддержка нескольких новых сервисов, таких как ElevationService и Distance Matrix.
- Улучшенный сервис построения маршрутов предлагает альтернативные маршруты, оптимизацию маршрутов (приблизительные решения
задачи коммивояжера), велосипедные маршруты (со
слоем велосипедных дорожек), маршруты на общественном транспорте и
перетаскиваемые маршруты.
- Обновленный формат геокодирования, который предоставляет более точную информацию о типе, чем значение
accuracy из Geocoding API версии 2.
- Поддержка нескольких информационных окон на одной карте.
Новый ключ
В Maps JavaScript API версии 3 используется новая система ключей, отличная от версии 2. Если вы уже используете ключ версии 3, ничего менять не нужно. Чтобы проверить это, посмотрите, есть ли в URL, по которому вы загружаете Maps JavaScript API, параметр key. Если значение ключа начинается с ABQIAA, вы используете ключ версии 2. Если у вас ключ версии 2, вам нужно перейти на версию 3. Это позволит:
Ключ передается при загрузке Maps JavaScript API v3.
Подробнее о том, как создавать ключи API…
Если вы являетесь клиентом Google Maps APIs for Work, то можете использовать идентификатор клиента с параметром client вместо параметра key. Идентификаторы клиентов по-прежнему поддерживаются в Maps JavaScript API v3, и их не нужно обновлять.
Загрузка API
Первое изменение, которое вам нужно будет внести в код, касается способа загрузки API. В версии 2 Maps JavaScript API загружается с помощью запроса к http://maps.google.com/maps. Если вы загружаете Maps JavaScript API версии 3, вам нужно будет внести следующие изменения:
- Загрузите API из
//maps.googleapis.com/maps/api/js
- Удалите параметр
file.
- Обновите параметр
key, указав новый ключ v3. Клиенты Google Maps APIs for Work должны использовать параметр client.
- (Только для тарифного плана Premium платформы Google Карт.) Убедитесь, что параметр
client указан в соответствии с инструкциями в
руководстве для разработчиков.
- Удалите параметр
v, чтобы запросить последнюю конечную версию, или измените его значение в соответствии со схемой управления версиями v3.
- (Необязательно.) Замените параметр
hl на language, сохранив его значение.
- (Необязательно.) Добавьте параметр
libraries, чтобы загрузить дополнительные библиотеки.
В простейшем случае начальная загрузка версии 3 будет содержать только параметр ключа API:
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
В примере ниже запрашивается последняя версия Maps JavaScript API v2 на немецком языке:
<script src="//maps.google.com/maps?file=api&v=2.x&key=YOUR_API_KEY&hl=de"></script>
В примере ниже показан эквивалентный запрос для v3.
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&language=de"></script>
Пространство имен google.maps
Пожалуй, самым заметным изменением в Maps JavaScript API v3 является введение пространства имен google.maps. В API версии 2 все объекты по умолчанию помещаются в глобальное пространство имен, что может привести к конфликтам имен. В версии 3 все объекты находятся в пространстве имен google.maps.
При переносе приложения в версию 3 вам нужно будет изменить код, чтобы использовать новое пространство имен. К сожалению, простой поиск по букве G и замена на google.maps. не сработает, но это хорошее правило, которое можно применять при проверке кода. Ниже приведены примеры эквивалентных классов в версиях 2 и 3.
| Версия 2 |
Версия 3 |
GMap2 |
google.maps.Map |
GLatLng |
google.maps.LatLng |
GInfoWindow |
google.maps.InfoWindow |
GMapOptions |
google.map.MapOptions |
G_API_VERSION |
google.maps.version |
GPolyStyleOptions |
google.maps.PolygonOptions or
google.maps.PolylineOptions |
Удалите устаревший код
В Maps JavaScript API версии 3 есть аналоги для большинства функций версии 2, однако некоторые классы больше не поддерживаются. В рамках перехода вам следует либо заменить эти классы сторонними служебными библиотеками, либо удалить эти ссылки из своего кода. Существует множество отличных библиотек JavaScript, которые предоставляют аналогичные функции, например Closure или jQuery.
У следующих классов нет аналогов в Maps JavaScript API версии 3:
GBounds | GLanguage |
GBrowserIsCompatible | GLayer |
GControl | GLog |
GControlAnchor | GMercatorProjection |
GControlImpl | GNavLabelControl |
GControlPosition | GObliqueMercator |
GCopyright | GOverlay |
GCopyrightCollection | GPhotoSpec |
GDownloadUrl | GPolyEditingOptions |
GDraggableObject | GScreenOverlay |
GDraggableObjectOptions | GStreetviewFeatures |
GFactualGeocodeCache | GStreetviewLocation |
GGeoAddressAccuracy | GStreetviewOverlay |
GGeocodeCache | GStreetviewUserPhotosOptions |
GGoogleBar | GTileLayerOptions |
GGoogleBarAdsOptions | GTileLayerOverlayOptions |
GGoogleBarLinkTarget | GTrafficOverlayOptions |
GGoogleBarListingTypes | GUnload |
GGoogleBarOptions | GXml |
GGoogleBarResultList | GXmlHttp |
GInfoWindowTab | GXslt |
GKeyboardHandler | |
Сравнить код
Ниже приведено сравнение двух приложений, написанных с использованием API версий 2 и 3.
<!DOCTYPE html>
<html>
<head>
<script src="//maps.google.com/maps?file=api&v=2&key=YOUR_API_KEY"></script>
<style>
html, body, #map { height: 100%; margin: 0; }
</style>
<script>
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(
document.getElementById('map'));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.setUIToDefault();
map.addOverlay(new GMarker(new GLatLng(37.4419, -122.1419)));
}
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="map"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<style>
html, body, #map { height: 100%; margin: 0; }
</style>
<script>
function initialize() {
var map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(37.4419, -122.1419),
map: map
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
Как видите, между этими двумя приложениями есть несколько различий. Некоторые заметные изменения:
- Изменился адрес загрузки API.
- Методы
GBrowserIsCompatible() и GUnload() больше не требуются в версии 3 и были удалены из API.
- Объект
GMap2 заменен на google.maps.Map в качестве центрального объекта в API.
- Свойства теперь загружаются через классы Options. В примере выше мы задали три свойства, необходимых для загрузки карты (
center, zoom и mapTypeId), с помощью встроенного объекта MapOptions.
- Пользовательский интерфейс по умолчанию включен в версии v3. Чтобы отключить эту функцию, задайте для свойства
disableDefaultUI значение true в объекте MapOptions.
Сводка
Теперь вы знаете, как перейти с версии 2 на версию 3 Maps JavaScript API.
В зависимости от вашего приложения вам может потребоваться дополнительная информация. В следующих разделах приведены инструкции по переносу для конкретных случаев, с которыми вы можете столкнуться. Кроме того, в процессе обновления вам могут пригодиться следующие ресурсы:
Если у вас возникли проблемы или вопросы, связанные с этим документом, нажмите на ссылку Отправить отзыв в верхней части страницы.
В этом разделе подробно сравниваются наиболее популярные функции Maps JavaScript API версий 2 и 3. Каждый раздел справочника предназначен для чтения по отдельности. Мы рекомендуем не читать это руководство целиком, а использовать его как справочный материал по мере необходимости.
- События – регистрация и обработка событий.
- Элементы управления – управление элементами навигации, которые появляются на карте.
- Наложения – добавление и редактирование объектов на карте.
- Типы карт – фрагменты, которые составляют базовую карту.
- Слои – добавление и редактирование контента в виде группы, например слоев KML или слоев трафика.
- Сервисы. Работа с сервисами геокодирования, маршрутов и Просмотра улиц.
События
Модель событий Maps JavaScript API версии 3 похожа на модель версии 2, хотя в ней многое изменилось.
Новое событие для поддержки MVC
API v3 добавляет новый тип события для отражения изменений состояния MVC. Теперь события бывают двух типов:
- Пользовательские события (например, события нажатия кнопок мыши), которые передаются из DOM в Maps JavaScript API. Они отличаются от стандартных событий DOM.
- Уведомления об изменениях состояния MVC, отражающие изменения объектов Maps API. Их названия имеют формат
property_changed.
Каждый объект Maps API экспортирует несколько именованных событий. Приложения, заинтересованные в определенных событиях, должны регистрировать прослушиватели событий для этих событий и выполнять код при их получении. Этот механизм, основанный на событиях, одинаков в Maps JavaScript API версий 2 и 3, за исключением того, что пространство имен изменилось с GEvent на google.maps.event:
GEvent.addListener(map, 'click', function() {
alert('You clicked the map.');
});
google.maps.event.addListener(map, 'click', function() {
alert('You clicked the map.');
});
Как удалять прослушиватели событий
В целях повышения производительности рекомендуется удалять прослушиватель событий, когда он больше не нужен. Удаление прослушивателя событий в версиях 2 и 3 выполняется одинаково:
- При создании прослушивателя событий возвращается непрозрачный объект (GEventListener в версии 2, MapsEventListener в версии 3).
- Чтобы удалить прослушиватель событий, передайте этот объект методу
removeListener() (GEvent.removeListener() в версии 2 или google.maps.event.removeListener() в версии 3).
Как прослушивать события DOM
Если вы хотите перехватывать события DOM (модели DOM) и реагировать на них, в версии 3 предусмотрен статический метод google.maps.event.addDomListener(), эквивалентный методу GEvent.addDomListener() в версии 2.
Как использовать переданные аргументы в событиях
События пользовательского интерфейса часто передают аргумент, к которому затем может обращаться прослушиватель событий. Большинство аргументов событий в версии 3 были упрощены, чтобы обеспечить большую согласованность между объектами в API. Подробную информацию можно найти в справочнике по API версии 3.
В прослушивателях событий версии 3 аргумент overlay отсутствует. Если вы зарегистрируете событие click на карте версии 3, обратный вызов будет происходить только тогда, когда пользователь нажимает на базовую карту. Если вам нужно реагировать на клики по оверлеям, вы можете зарегистрировать дополнительные обратные вызовы.
// Passes an overlay argument when clicking on a map
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
map.setUIToDefault();
GEvent.addListener(map,'click', function(overlay, latlng) {
if (latlng) {
var marker = new GMarker(latlng);
map.addOverlay(marker);
}
});
// Passes only an event argument
var myOptions = {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'),
myOptions);
google.maps.event.addListener(map, 'click', function(event) {
var marker = new google.maps.Marker({
position: event.latLng,
map: map
});
});
Элементы управления
Maps JavaScript API показывает элементы управления пользовательского интерфейса, позволяющие пользователям взаимодействовать с картой. Вы можете настроить внешний вид элементов управления с помощью API.
Изменения типов элементов управления
В API версии 3 были внесены некоторые изменения в типы control.
- В API версии 3 поддерживаются дополнительные типы карт, в том числе карты рельефа, а также возможность добавлять собственные типы карт.
- Иерархический элемент управления v2,
GHierarchicalMapTypeControl, больше не доступен.
Похожего эффекта можно добиться с помощью элемента управления google.maps.MapTypeControlStyle.HORIZONTAL_BAR.
- Горизонтальный макет, который в версии 2 задавался с помощью
GMapTypeControl, в версии 3 недоступен.
Как добавить элементы управления на карту
В Maps JavaScript API v2 элементы управления добавлялись на карту с помощью метода addControl() объекта карты. В версии 3 вместо прямого доступа к элементам управления или их изменения вы изменяете связанный объект MapOptions. В примере ниже показано, как настроить карту, добавив следующие элементы управления:
- кнопки, позволяющие пользователю переключаться между доступными типами карт;
- масштаб карты.
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
// Add controls
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
var myOptions = {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
// Add controls
mapTypeControl: true,
scaleControl: true
};
var map = new google.maps.Map(document.getElementById('map'),
myOptions);
Как разместить элементы управления на карте
Позиционирование элементов управления значительно изменилось в версии v3. Во второй версии метод addControl() принимает необязательный второй параметр, который позволяет указать положение элемента управления относительно углов карты.
В версии 3 положение элемента управления задается с помощью свойства position в настройках элемента. Оно не задается абсолютными значениями. Вместо этого API распределяет элементы управления на экране так, чтобы они, с учетом размера карты и других ограничений, не перекрывали объекты на карте.
Это гарантирует, что стандартные элементы управления будут совместимы с вашими.
Подробнее о том, как управлять расположением элементов в версии 3…
Следующий код изменяет положение элементов управления из вышеприведенных примеров:
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
// Add map type control
map.addControl(new GMapTypeControl(), new GControlPosition(
G_ANCHOR_TOP_LEFT, new GSize(10, 10)));
// Add scale
map.addControl(new GScaleControl(), new GControlPosition(
G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 20)));
var myOptions = {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
// Add map type control
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.TOP_LEFT
},
// Add scale
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_RIGHT
}
};
var map = new google.maps.Map(document.getElementById('map'),
myOptions);
Пользовательские элементы управления
Используйте Maps JavaScript API, чтобы создать собственные элементы управления навигацией.
Чтобы настроить элементы управления с помощью API версии 2, нужно создать подкласс класса GControl и определить обработчики для методов initialize() и getDefaultPosition().
В версии 3 нет эквивалента классу GControl. Вместо этого элементы управления представлены как элементы DOM. Чтобы добавить пользовательский элемент управления с помощью API версии 3, создайте структуру DOM для элемента управления в конструкторе как дочерний элемент Node (например, элемент <div>) и добавьте прослушиватели событий для обработки любых событий DOM. Чтобы добавить экземпляр пользовательского элемента управления на карту, поместите Node в массив controls[position] карты.
В примерах кода ниже показано, как добавить на карту собственный элемент управления, используя реализацию класса HomeControl, которая соответствует требованиям к интерфейсу, описанным выше (подробности см. в документации по собственным элементам управления).
map.addControl(new HomeControl(),
GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10)));
var homeControlDiv = document.createElement('DIV');
var homeControl = new HomeControl(homeControlDiv, map);
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(
homeControlDiv);
Наложения
Наложения представляют собой объекты, которые вы добавляете на карту, чтобы обозначить точки, линии, области или наборы объектов.
Как добавлять и удалять оверлеи
Типы объектов, представленных наложением, в версиях 2 и 3 одинаковы, но обрабатываются по-разному.
В API версии 2 наложения добавлялись на карту и удалялись с нее с помощью методов addOverlay() и removeOverlay() объекта GMap2. В версии 3 вы назначаете карту для наложения с помощью свойства map связанного класса параметров наложения.
Вы также можете добавить или удалить наложение, вызвав метод setMap() объекта наложения и указав нужную карту. Чтобы удалить наложение, задайте для свойства map значение null.
В версии 3 нет метода clearOverlays().
Если вы работаете с разными наложениями, создайте массив для их хранения. Вы сможете удалять оверлеи из массива, по очереди вызывая метод setMap() для каждого из них и передавая значение null.
Перетаскиваемые маркеры
По умолчанию маркеры реагируют на нажатия, но не поддерживают операцию перетаскивания. В следующих двух примерах добавляется перетаскиваемый маркер:
var myLatLng = new GLatLng(-25.363882, 131.044922);
var map = new GMap2(document.getElementById('map'));
map.setCenter(myLatLng, 4);
var marker = new GMarker(latLng, {
draggable: true
});
map.addOverlay(marker);
var myLatLng = new google.maps.LatLng(-25.363882, 131.044922);
var map = new google.maps.Map(
document.getElementById('map'), {
center: myLatLng,
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: myLatLng,
draggable: true,
map: map
});
Значки.
Вы можете определить собственный значок для отображения вместо маркера по умолчанию.
Чтобы использовать собственный образ в v2, вы можете создать экземпляр GIcon из G_DEFAULT_ICON type и изменить его. Если ваше изображение больше или меньше значка по умолчанию, необходимо указать его с помощью экземпляра GSize.
В API v3 этот процесс немного проще.
Просто задайте в свойстве маркера icon URL собственного изображения, и API автоматически подберет размер значка.
Maps JavaScript API также поддерживает сложные значки.
Сложный значок может состоять из нескольких фрагментов, иметь сложную форму или задавать порядок наложения изображений относительно других слоев. Чтобы добавить фигуру к маркеру в версии 2, необходимо указать дополнительное свойство в каждом экземпляре GIcon и передать его в качестве параметра конструктору GMarker. В версии 3 для заданных таким образом значков в качестве свойства icon следует устанавливать объекты типа Icon.
Тени маркеров не поддерживаются в v3.
В следующих примерах показан флаг на пляже Бонди-Бич в Австралии, причем прозрачная часть значка неактивна.
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(-25.363882, 131.044922), 4);
map.setUIToDefault();
var flagIcon = new GIcon(G_DEFAULT_ICON);
flagIcon.image = '/images/beachflag.png';
flagIcon.imageMap = [1, 1, 1, 20, 18, 20, 18 , 1];
var bbLatLng = new GLatLng(-33.890542, 151.274856);
map.addOverlay(new GMarker(bbLatLng, {
icon: flagIcon
}));
var map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
var bbLatLng = new google.maps.LatLng(-33.890542, 151.274856);
var bbMarker = new google.maps.Marker({
icon: '/images/beachflag.png'
shape: shape,
position: bbLatLng,
map: map
});
Ломаные линии
Ломаная линия состоит из массива объектов LatLng и набора отрезков, соединяющих эти точки в заданной последовательности.
Создание и отображение объекта Polyline в версии 3 аналогично использованию объекта GPolyline в версии 2. В приведенных ниже примерах кода показано, как нарисовать полупрозрачную геодезическую ломаную линию шириной 3 пикселя, соединяющую Цюрих и Сидней через Сингапур.
var polyline = new GPolyline(
[
new GLatLng(47.3690239, 8.5380326),
new GLatLng(1.352083, 103.819836),
new GLatLng(-33.867139, 151.207114)
],
'#FF0000', 3, 0.5, {
geodesic: true
});
map.addOverlay(polyline);
var polyline = new google.maps.Polyline({
path: [
new google.maps.LatLng(47.3690239, 8.5380326),
new google.maps.LatLng(1.352083, 103.819836),
new google.maps.LatLng(-33.867139, 151.207114)
],
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 3,
geodesic: true
});
polyline.setMap(map);
Кодированные ломаные линии
В версии 3 не поддерживается создание объектов Polyline непосредственно из закодированных ломаных линий. Вместо этого в библиотеке геометрии предусмотрены методы кодирования и декодирования ломаных линий. Подробнее о том, как загрузить эту библиотеку, читайте в разделе Библиотеки в Maps API версии 3.
В примерах ниже рисуется одна и та же закодированная ломаная линия. В коде версии 3 используется метод decodePath() из пространства имен google.maps.geometry.encoding.
var polyline = new GPolyline.fromEncoded({
points: 'kwb`Huqbs@ztzwGgvpdQbw}uEoif`H',
levels: 'PPP',
zoomFactor: 2,
numLevels: 18,
color: '#ff0000',
opacity: 0.8,
weight: 3
});
map.addOverlay(polyline);
var polyline = new google.maps.Polyline({
path: google.maps.geometry.encoding.decodePath(
'kwb`Huqbs@ztzwGgvpdQbw}uEoif`H'),
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 3,
});
polyline.setMap(map);
Многоугольники
Многоугольник определяет область внутри замкнутого контура. Как и объект Polyline, объект Polygon состоит из упорядоченной последовательности точек. Класс Polygon в версии 3 очень похож на класс GPolygon в версии 2, за исключением того, что вам больше не нужно повторять начальную вершину в конце пути, чтобы замкнуть контур. API версии 3 автоматически замыкает все многоугольники, соединяя последнюю координату с первой. В приведенных ниже фрагментах кода создается многоугольник, представляющий Бермудский треугольник.
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(24.886436, -70.268554), 5);
var bermudaTriangle = new GPolygon(
[
new GLatLng(25.774252, -80.190262),
new GLatLng(18.466465, -66.118292),
new GLatLng(32.321384, -64.75737),
new GLatLng(25.774252, -80.190262)
],
'#FF0000', 2, 0.8, '#FF0000', 0.35);
map.addOverlay(bermudaTriangle);
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(24.886436, -70.268554),
mapTypeId: google.maps.MapTypeId.TERRAIN,
zoom: 5
});
var bermudaTriangle = new google.maps.Polygon({
paths: [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.75737)
],
strokeColor: '#FF0000',
strokeWeight: 2,
strokeOpacity: 0.8,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
Формы, редактируемые пользователем
Пользователям можно разрешить изменять ломаные линии и многоугольники. Следующие фрагменты кода эквивалентны:
map.addOverlay(polyline);
polyline.enableEditing();
polyline.setMap(map);
polyline.setEditable(true);
Дополнительные возможности рисования описаны в разделе Библиотека Drawing документации по Maps JavaScript API версии 3.
Информационные окна
Объект InfoWindow служит для отображения контента в плавающем окне поверх карты. Между информационными окнами в v2 и v3 есть ряд важных отличий:
- API версии 2 поддерживает только один объект
GInfoWindow на карту, а API версии 3 – несколько параллельных объектов InfoWindow на каждой карте.
- В версии 3
InfoWindow остается открытым при нажатии на карту. Окно GInfoWindow версии 2 закрывается автоматически, когда вы нажимаете на карту. Вы можете эмулировать поведение версии 2, добавив прослушиватель click в объект Map.
- В API версии 3 нет встроенной поддержки вкладок в окне
InfoWindow.
Наземные наложения
Для размещения изображения на карте можно воспользоваться объектом GroundOverlay. Конструктор для объекта GroundOverlay в версиях 2 и 3 практически одинаков: в качестве параметров указываются URL и границы изображения.
В следующем примере на карту в качестве наложения добавляется старинная карта Ньюарка (штат Нью-Джерси):
var bounds = new GLatLngBounds(
new GLatLng(40.716216, -74.213393),
new GLatLng(40.765641, -74.139235));
var overlay = new GGroundOverlay(
'http://lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
bounds);
map.addOverlay(overlay);
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(40.716216, -74.213393),
new google.maps.LatLng(40.765641, -74.139235));
var overlay = new google.maps.GroundOverlay(
'http://lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
bounds);
overlay.setMap(map);
Типы карт
Типы карт, доступные в версиях 2 и 3, немного различаются, но все основные типы карт доступны в обеих версиях API. По умолчанию в версии 2 используются стандартные фрагменты дорожной карты. Однако в версии 3 при создании объекта google.maps.Map необходимо указать определенный тип карты.
Общие типы карт
В v2 и v3 имеется четыре базовых типа карт:
MapTypeId.ROADMAP (заменяет G_NORMAL_MAP) – дорожная карта.
MapTypeId.SATELLITE (заменяет G_SATELLITE_MAP) – спутниковые снимки Google Планета Земля.
MapTypeId.HYBRID (заменяет G_HYBRID_MAP) – комбинация обычной карты и спутниковых снимков.
MapTypeId.TERRAIN (заменяет G_PHYSICAL_MAP) – физическая карта с информацией о рельефе.
Ниже приведены примеры настроек режима карты местности в v2 и v3:
map.setMapType(G_PHYSICAL_MAP);
map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
В Maps JavaScript API версии 3 также внесены некоторые изменения в менее распространенные типы карт:
- Фрагменты карт для небесных тел, кроме Земли, недоступны в качестве типов карт в API версии 3, но к ним можно получить доступ как к специальным типам карт. Пример можно посмотреть в статье Пользовательские типы карт.
- В версии 3 нет специального типа карты, который заменяет тип
G_SATELLITE_3D_MAP из версии 2. Вместо этого вы можете интегрировать плагин Google Планета Земля в карты версии 3, используя эту библиотеку.
Сервис Maximum Zoom Imagery
Спутниковые снимки не всегда доступны с высокими уровнями масштабирования. Если вы хотите узнать максимальный доступный уровень масштабирования, прежде чем задавать его, используйте класс google.maps.MaxZoomService. Этот класс заменяет метод GMapType.getMaxZoomAtLatLng() из версии 2.
var point = new GLatLng(
180 * Math.random() - 90, 360 * Math.random() - 180);
var map = new GMap2(document.getElementById("map"));
map.setUIToDefault();
map.setCenter(point);
map.setMapType(G_HYBRID_MAP);
map.getCurrentMapType().getMaxZoomAtLatLng(point,
function(response) {
if (response.status) {
map.setZoom(response.zoom);
} else {
alert("Error in Max Zoom Service.");
}
});
var myLatlng = new google.maps.LatLng(
180 * Math.random() - 90, 360 * Math.random() - 180);
var map = new google.maps.Map(
document.getElementById("map"),{
zoom: 0,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.HYBRID
});
var maxZoomService = new google.maps.MaxZoomService();
maxZoomService.getMaxZoomAtLatLng(
myLatlng,
function(response) {
if (response.status == google.maps.MaxZoomStatus.OK) {
map.setZoom(response.zoom);
} else {
alert("Error in Max Zoom Service.");
}
});
Изображения перспективной аэрофотосъемки
При включении аэрофотосъемки в версии 3 элементы управления аналогичны элементу GLargeZoomControl3D в версии 2, но есть дополнительный элемент управления "Поворот" для поворота в поддерживаемых направлениях.
Города, для которых доступны снимки под углом 45°, можно посмотреть на карте поддерживаемых городов. Если для выбранного местоположения доступны изображения под углом 45°, в меню кнопки "Спутник" Maps API добавляется соответствующий пункт.
Слои
Слои – это объекты на карте, состоящие из одного или нескольких наложений. Ими можно управлять как единым целым. Обычно они представляют собой наборы объектов.
Поддерживаемые слои
API v3 предоставляет доступ к нескольким разным слоям. Эти слои перекрываются с классом GLayer версии 2 в следующих областях:
-
Объект
KmlLayer преобразует элементы KML и GeoRSS в наложения версии 3, обеспечивая эквивалент слоя GeoXml версии 2.
- Объект
TrafficLayer создает слой, показывающий загруженность дорог, аналогично наложению GTrafficOverlay в версии 2.
Эти слои отличаются от слоев v2. Различия описаны ниже. Чтобы добавить слой на карту, вызовите метод setMap() и передайте ему объект Map, на котором следует отобразить слой.
Подробную информацию о поддерживаемых слоях можно найти в документации по слоям.
Слои KML и GeoRSS
Maps JavaScript API поддерживает форматы данных KML и GeoRSS для отображения географической информации. Чтобы включить файлы KML или GeoRSS в карту, они должны быть общедоступными. В версии 3 эти форматы данных отображаются с помощью экземпляра KmlLayer, который заменяет объект GGeoXml из версии 2.
Версия 3 API более гибко обрабатывает KML, позволяя подавлять информационные окна и изменять реакцию на клик. Подробнее см. в разделе Слои KML и GeoRSS (для версии 3).
При отрисовке KmlLayer действуют ограничения на размер и сложность. Подробную информацию можно найти в документации по KmlLayer.
В следующих примерах приведено сравнение способов загрузки файла KML.
geoXml = new GGeoXml(
'https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml');
map.addOverlay(geoXml);
var layer = new google.maps.KmlLayer(
'https://googlearchive.github.io/js-v2-samples/ggeoxml/cta.kml', {
preserveViewport: true
});
layer.setMap(map);
Слой "Пробки"
В версии 3 вы можете добавлять на карту информацию о загруженности дорог в реальном времени (если этот слой поддерживается в регионе) с помощью объекта TrafficLayer. Информация о дорожном движении предоставляется на момент выполнения запроса. В примерах ниже показана информация о дорожном движении в Лос-Анджелесе:
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(34.0492459, -118.241043), 13);
map.setUIToDefault();
var trafficOptions = {incidents:false};
trafficInfo = new GTrafficOverlay(trafficOptions);
map.addOverlay(trafficInfo);
var map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(34.0492459, -118.241043),
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 13
});
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
В отличие от версии 2, в версии 3 для конструктора TrafficLayer нет параметров. Дорожно-транспортные происшествия в v3 не поддерживаются.
Службы
Геокодирование
Maps JavaScript API предоставляет объект geocoder для динамического геокодирования адресов, введенных пользователем. Если вам нужно геокодировать статические известные адреса, ознакомьтесь с документацией по Geocoding API.
Geocoding API был значительно обновлен и улучшен. В него были добавлены новые функции, а также изменен способ представления данных.
В API версии 2 GClientGeocoder предоставлял два разных метода для прямого и обратного геокодирования, а также дополнительные методы, влияющие на выполнение геокодирования. В отличие от этого, объект Geocoder в версии 3 предоставляет только метод geocode(), который принимает объектный литерал, содержащий входные условия (в форме объекта Geocoding Requests), и метод обратного вызова. В зависимости от того, содержит ли запрос текстовый атрибут address или объект LatLng, Geocoding API возвращает ответ прямого или обратного геокодирования. Вы можете повлиять на то, как выполняется геокодирование, передав в запрос дополнительные поля:
- Если указать текстовое значение
address, будет выполнено прямое геокодирование, эквивалентное вызову метода getLatLng().
- Если включить объект
latLng, будет запущено обратное геокодирование, эквивалентное вызову метода getLocations().
- Добавление атрибута
bounds включает смещение области просмотра, что эквивалентно вызову метода setViewport().
- Атрибут
region позволяет включить предпочтение кода региона, что эквивалентно вызову метода setBaseCountryCode().
Ответы геокодирования в версии 3 сильно отличаются от ответов в версии 2. В API версии 3 вложенная структура, которая используется в версии 2, заменена на более плоскую, которую проще анализировать. Кроме того, ответы v3 более подробны: каждый результат содержит несколько компонентов адреса, которые помогают лучше понять разрешение каждого результата.
В следующем примере кода берется текстовый адрес и показывается первый результат его геокодирования:
var geocoder = new GClientGeocoder();
var infoPanel;
var map;
var AccuracyDescription = [
'Unknown accuracy', 'country level accuracy',
'region level accuracy', 'sub-region level accuracy',
'town level accuracy', 'post code level accuracy',
'street level accuracy', 'intersection level accuracy',
'address level accuracy', 'premise level accuracy',
];
function geocode_result_handler(response) {
if (!response || response.Status.code != 200) {
alert('Geocoding failed. ' + response.Status.code);
} else {
var bounds = new GLatLngBounds(new GLatLng(
response.Placemark[0].ExtendedData.LatLonBox.south,
response.Placemark[0].ExtendedData.LatLonBox.west
), new GLatLng(
response.Placemark[0].ExtendedData.LatLonBox.north,
response.Placemark[0].ExtendedData.LatLonBox.east
));
map.setCenter(bounds.getCenter(),
map.getBoundsZoomLevel(bounds));
var latlng = new GLatLng(
response.Placemark[0].Point.coordinates[1],
response.Placemark[0].Point.coordinates[0]);
infoPanel.innerHTML += '<p>1st result is <em>' +
// No info about location type
response.Placemark[0].address +
'</em> of <em>' +
AccuracyDescription[response.Placemark[0].
AddressDetails.Accuracy] +
'</em> at <tt>' + latlng + '</tt></p>';
var marker_title = response.Placemark[0].address +
' at ' + latlng;
map.clearOverlays();
var marker = marker = new GMarker(
latlng,
{'title': marker_title}
);
map.addOverlay(marker);
}
}
function geocode_address() {
var address = document.getElementById('input-text').value;
infoPanel.innerHTML = '<p>Original address: ' + address + '</p>';
geocoder.getLocations(address, geocode_result_handler);
}
function initialize() {
map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(38, 15), 2);
map.setUIToDefault();
infoPanel = document.getElementById('info-panel');
}
var geocoder = new google.maps.Geocoder();
var infoPanel;
var map;
var marker;
function geocode_result_handler(result, status) {
if (status != google.maps.GeocoderStatus.OK) {
alert('Geocoding failed. ' + status);
} else {
map.fitBounds(result[0].geometry.viewport);
infoPanel.innerHTML += '<p>1st result for geocoding is <em>' +
result[0].geometry.location_type.toLowerCase() +
'</em> to <em>' +
result[0].formatted_address + '</em> of types <em>' +
result[0].types.join('</em>, <em>').replace(/_/, ' ') +
'</em> at <tt>' + result[0].geometry.location +
'</tt></p>';
var marker_title = result[0].formatted_address +
' at ' + latlng;
if (marker) {
marker.setPosition(result[0].geometry.location);
marker.setTitle(marker_title);
} else {
marker = new google.maps.Marker({
position: result[0].geometry.location,
title: marker_title,
map: map
});
}
}
}
function geocode_address() {
var address = document.getElementById('input-text').value;
infoPanel.innerHTML = '<p>Original address: ' + address + '</p>';
geocoder.geocode({'address': address}, geocode_result_handler);
}
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(38, 15),
zoom: 2,
mapTypeId: google.maps.MapTypeId.HYBRID
});
infoPanel = document.getElementById('info-panel');
}
Маршруты
В Maps JavaScript API версии 3 класс GDirections из версии 2 заменен классом DirectionsService для расчета маршрутов.
Метод route() в версии 3 заменяет методы load() и loadFromWaypoints() из API версии 2. Этот метод принимает один литерал объекта DirectionsRequest, содержащий входные условия и метод обратного вызова, который выполняется после получения ответа. В этом объектном литерале можно задать параметры, аналогичные параметрам объектного литерала GDirectionsOptions в версии 2.
В Maps JavaScript API версии 3 отправка запросов на прокладку маршрутов отделена от их обработки, которая теперь выполняется с помощью класса DirectionsRenderer. Объект DirectionsRenderer можно связать с любой картой или объектом DirectionsResult с помощью методов setMap() и setDirections(). Поскольку средство прорисовки представляет собой объект MVCObject, оно автоматически находит изменения свойств маршрута и обновляет карту.
В следующем примере кода показано, как запросить пешеходный маршрут до определенного места по пешеходным дорожкам от адреса. Обратите внимание, что только версия 3 может проложить пешеходный маршрут по дорожке в Дублинском зоопарке.
var map;
var directions;
var directionsPanel;
function initialize() {
var origin = new google.maps.LatLng(53.348172, -6.297285);
var destination = new google.maps.LatLng(53.355502, -6.30557);
directionsPanel = document.getElementById("route");
map = new GMap2(document.getElementById('map'));
map.setCenter(origin, 10);
map.setUIToDefault();
directions = new GDirections(map, directionsPanel);
directions.loadFromWaypoints(
[origin, destination], {
travelMode: 'G_TRAVEL_MODE_WALKING',
});
}
var map;
var directionsRenderer;
var directionsService = new google.maps.DirectionsService();
function initialize() {
var origin = new google.maps.LatLng(53.348172, -6.297285);
var destination = new google.maps.LatLng(53.355502, -6.30557);
directionsRenderer = new google.maps.DirectionsRenderer();
map = new google.maps.Map(
document.getElementById('map'), {
center: origin,
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
directionsRenderer.setPanel(document.getElementById("route"));
directionsRenderer.setMap(map);
directionsService.route({
origin: origin,
destination: destination,
travelMode: google.maps.DirectionsTravelMode.WALKING
}, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(result);
}
});
}
Просмотр улиц
Google Просмотр улиц – это сервис, предоставляющий доступ к интерактивным круговым панорамам множества разных мест по всему миру. В отличие от версии 2, в которой для показа панорам требовался плагин Flash®, в версии 3 Просмотр улиц поддерживается встроенными возможностями браузера.
Изображения Просмотра улиц поддерживаются за счет использования объекта StreetViewPanorama в версии 3 или объекта GStreetviewPanorama в версии 2. У этих классов разные интерфейсы, но они выполняют одну и ту же роль: связывают контейнер div с изображениями Просмотра улиц и позволяют указывать местоположение и точку обзора панорамы в Просмотре улиц.
function initialize() {
var fenwayPark = new GLatLng(42.345573, -71.098326);
panoramaOptions = {
latlng: fenwayPark,
pov: {
heading: 35,
pitch: 5,
zoom: 1
}
};
var panorama = new GStreetviewPanorama(
document.getElementById('pano'),
panoramaOptions);
GEvent.addListener(myPano, "error", handleNoFlash);
}
function handleNoFlash(errorCode) {
if (errorCode == FLASH_UNAVAILABLE) {
alert('Error: Your browser does not support Flash');
return;
}
}
function initialize() {
var fenway = new google.maps.LatLng(42.345573, -71.098326);
var panoramaOptions = {
position: fenway,
pov: {
heading: 35,
pitch: 5,
zoom: 1
}
};
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('pano'),
panoramaOptions);
}
Прямой доступ к данным Просмотра улиц можно получить с помощью объекта StreetViewService в версии 3 или аналогичного объекта GStreetviewClient в версии 2. Оба сервиса предоставляют схожие интерфейсы для получения или проверки доступности данных Просмотра улиц и позволяют выполнять поиск по местоположению или идентификатору панорамы.
В версии 3 просмотр улиц включен по умолчанию: На карте появится значок человечка, а API будет использовать элемент div карты для показа панорам Просмотра улиц. В следующем примере кода показано, как эмулировать поведение версии 2, поместив панорамы в Просмотре улиц в отдельный элемент div.
var marker;
var panoClient = new GStreetviewClient();
function initialize() {
if (GBrowserIsCompatible()) {
var myPano = new GStreetviewPanorama(
document.getElementById('pano'));
GEvent.addListener(myPano, 'error', handleNoFlash);
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(42.345573, -71.098326), 16);
map.setUIToDefault();
GEvent.addListener(map, 'click', function(overlay, latlng) {
if (marker) {
marker.setLatLng(latlng);
} else {
marker = new GMarker(latlng);
map.addOverlay(marker);
}
var nearestPano = panoClient.getNearestPanorama(
latlng, processSVData);
});
function processSVData(panoData) {
if (panoData.code != 200) {
alert("Panorama data not found for this location.");
}
var latlng = marker.getLatLng();
var dLat = latlng.latRadians()
- panoData.location.latlng.latRadians();
var dLon = latlng.lngRadians()
- panoData.location.latlng.lngRadians();
var y = Math.sin(dLon) * Math.cos(latlng.latRadians());
var x = Math.cos(panoData.location.latlng.latRadians()) *
Math.sin(latlng.latRadians()) -
Math.sin(panoData.location.latlng.latRadians()) *
Math.cos(latlng.latRadians()) * Math.cos(dLon);
var bearing = Math.atan2(y, x) * 180 / Math.PI;
myPano.setLocationAndPOV(panoData.location.latlng, {
yaw: bearing
});
}
function handleNoFlash(errorCode) {
if (errorCode == FLASH_UNAVAILABLE) {
alert('Error: Your browser does not support Flash');
return;
}
}
}
}
// Load the API with libraries=geometry
var map;
var marker;
var panorama;
var sv = new google.maps.StreetViewService();
function radians(degrees) { return Math.PI * degrees / 180.0 };
function initialize() {
panorama = new google.maps.StreetViewPanorama(
document.getElementById("pano"));
map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(42.345573, -71.098326),
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 16
});
google.maps.event.addListener(map, 'click', function(event) {
if (!marker) {
marker = new google.maps.Marker({
position: event.latLng,
map: map
});
} else {
marker.setPosition(event.latLng);
}
sv.getPanoramaByLocation(event.latLng, 50, processSVData);
});
}
function processSVData(panoData, status) {
if (status == google.maps.StreetViewStatus.OK) {
alert("Panorama data not found for this location.");
}
var bearing = google.maps.geometry.spherical.computeHeading(
panoData.location.latLng, marker.getPosition());
panorama.setPano(panoData.location.pano);
panorama.setPov({
heading: bearing,
pitch: 0,
zoom: 1
});
panorama.setVisible(true);
marker.setMap(panorama);
}