Yandex maps api 2.1 transition
In this article, I want to start a series of articles on working with the Yandex.Maps API. The Yandex.Maps documentation is quite complete, but the degree of fragmentation of information in it is high, when you first enter the documentation without half a liter, you can’t figure it out, and to solve a problem, you can spend a lot of time searching through the documentation and in a search engine. This series of articles will talk about practical solutions to the most common cases of using the Yandex.Maps API of the latest, at the time of this writing, version 2.1.
When laying out a site in contact information, it is often necessary to insert a map on which the location of the organization for which the site is being developed will be marked. In the simplest cases, this can be just a screenshot from online maps (or not online):
For insert interactive map map builder can be used
https://tech.yandex.ru/maps/tools/constructor/ :
If we need a more advanced use of maps (our own labels, programmatic movement of maps, etc.), then for this we need to use the Yandex.Maps API: https://tech.yandex.ru/maps/jsapi/ . As an example of how to use maps, this article will look at creating a map with the simple addition of a custom label and balloon.
First, let's connect the API components:
If some large application is being developed using maps, then it is better to connect the API components of a certain version so that when updating the API on the Yandex side, nothing breaks in production:
The map will need to be placed in some block, for example in div#map. Next, the map must be created in this block (after the map and DOM readiness event is triggered):
ymaps.ready(init) ; function init() ( var myMap; myMap = new ymaps.Map ("map" , ( center: [ 55.76 , 37.64 ] , zoom: 7 ) ) ; ) |
Here we indicate:
- block identifier map, where we will create a map;
- center— the center of the map indicating the width and longitude;
- zoom— map scale factor.
By default, Yandex.Maps creates a lot of unnecessary elements, which in most cases are not needed on websites. Basically, it is enough to apply 2 conditions to the controls and to the behavior of the map:
- of the map elements, only the zoom slider is present;
- the map should not be zoomed with the mouse scroll.
To fulfill these requirements, we supplement the code:
ymaps.ready(init) ; function init() ( var myMap; myMap = new ymaps.Map ("map" , ( center: [ 55.76 , 37.64 ] , zoom: 13 , controls: ) ) ; myMap.behaviors .disable ("scrollZoom" ) ; myMap. controls .add ("zoomControl" , ( position: ( top: 15 , left: 15 ) ) ) ; ) |
Here we have disabled scrollzoom and added "zoom control" positioned from the top left corner.
Now we need to add a label to the map, for the article we will download its image from http://medialoot.com/item/free-vector-map-location-pins/ and place it in the code as follows:
ymaps.ready(init) ; function init() ( var myMap; myMap = new ymaps.Map ("map" , ( center: [ 55.7652 , 37.63836 ] , zoom: 17 , controls: ) ) ; myMap.behaviors .disable ("scrollZoom" ) ; myMap. controls .add ("zoomControl" , ( position: ( top: 15 , left: 15 ) ) ) ; var myPlacemark = new ymaps.Placemark ([ 55.7649 , 37.63836 ] , ( ) , ( iconLayout: "default#image" , iconImageHref : , iconImageSize: [ 40 , 51 ] , iconImageOffset: [ - 20 , - 47 ] ) ) ; myMap.geoObjects .add (myPlacemark) ; ) |
Here we declare a variable myPlacemark, in which we write the marker, in the first parameter ymaps.Placemark specify the label coordinates, and in the third parameter:
- indicate in iconLayout that a custom label image will be used;
- iconImageHref- path to the image;
- iconImageSize- specify the size of the image;
- iconImageOffset- we indicate the shift from the upper left corner of the picture to the point of the image, which we point to the object we need. This is necessary so that when the map is scaled, the position of the label does not go astray. Why the offset is indicated in negative values - only God knows the creator of the API.
And through myMap.geoObjects.add() add a marker to the map.
And now let's make a balloon that will be shown when we click on the map label, we will take the layout of the balloon and its contents from http://designdeck.co.uk/a/1241
ymaps.ready(init) ; function init() ( var myMap; myMap = new ymaps.Map ("map" , ( center: [ 55.7652 , 37.63836 ] , zoom: 17 , controls: ) ) ; myMap.behaviors .disable ("scrollZoom" ) ; myMap. controls .add ("zoomControl" , ( position: ( top: 15 , left: 15 ) ) ) ; var html = " "; html += ""
; html +=" " ; var myPlacemark = new ymaps.Placemark ([ 55.7649 , 37.63836 ] , ( balloonContent: html ) , ( iconLayout: "default#image" , iconImageHref: "http://site/files/APIYaMaps1/min_marker.png", iconImageSize: [ 40 , 51 ] , iconImageOffset: [ - 20 , - 47 ] , balloonLayout: "default#imageWithContent" , balloonContentSize: [ 289 , 151 ] , balloonImageHref: "http://site/files/APIYaMaps1/min_popup.png", balloonImageOffset: [ - 144 , - 147 ] , balloonImageSize: [ 289 , 151 ] , balloonShadow: false ) ) ; myMap.geoObjects .add (myPlacemark) ; )"; html += " " ; html += "The Victoria Tower Gardens " ; html += "" ; html +="City of London " ; html += "" ; html += "United Kingdom " ; html += "020 7641 5264 " ; html += " |
We are here:
- in balloonContent specify the content that will be displayed when the balloon is opened;
- balloonLayout- specify that a custom image will be used as the balloon layout;
- balloonContentSize and balloonImageSize— sizes of content and images, respectively;
- balloonImageHref- path to the image;
- balloonImageOffset- offset relative to the upper left corner;
- balloonShadow— disabling the shadow of the balloon (it doesn't affect anything with custom images).
A release candidate is a version of the API, which is available for public use, but is still under approval. Before installing the release candidate as a stable version, as soon as it is released, it is tested for bugs that may lead to API functionality degradation. By using release candidates in your projects, you can help us timely identify potential errors. You can also pretest your app"s operation with a new version of the API.
Release candidates should be used in the app development and testing environment. This will help you avoid errors in the production environment. You can enable a release candidate as follows:
If some time after publishing a release candidate no errors that lead to functionality degradation are found, the release candidate is installed as a stable version of the API and can be accessed via the link api-maps.yandex.ru/2.1.
Enabling the current version
When using your application, we recommend specifying the major version (i.e., do not specify the third number of the version). This guarantees that the current version, that is, the latest stable version of the corresponding major version, will be automatically enabled. For example, if you specify version 2.1, the latest available stable version 2.1.x will be enabled (for example, 2.1.47):
Enabling a set version
Although full compatibility is guaranteed between minor versions, in rare cases you may find that your client application does not work as intended when you enable the latest API version. To avoid these situations, in particularly crucial cases you may need to enable a specific API version. For that, specify its number in its entirety:
Note. If you use a set version, try regularly switching it to a newer version (for example, once every few months). The matter is that over time we can disable the minor version you are using in your project, and then the current version of the API will be enabled automatically. However, the version update might cause your app to stop working correctly. For this reason, we recommend that you keep track of API updates and switch to newer versions as soon as possible.
Summary table
The table below provides recommendations for enabling different versions of the API, depending on the type and complexity of your project.
Project type | ||
---|---|---|
Project type | Recommended version for running applications | Recommended version under development |
---|---|---|
Medium and large projects with a basic map | Latest version of to test the functionality. |
|
Medium and large projects with complex map features | Set version to test the functionality. |
|
Projects using the commercial version of the API | Set version (see the note below) |
Note. If you use a set version, try regularly switching it to a newer version. The matter is that over time we can disable the minor version you are using in your app, and then the current version of the API will be enabled automatically. However, the version update might cause your app to stop working correctly. For this reason, we recommend that you keep track of API updates and switch to newer versions as soon as possible.
Мы выпустили бета-версию API Яндекс.Карт 2.1 . Главная ее особенность - полный редизайн интерфейса карты. Причем изменения затронули не только внешний вид, но и поведение элементов управления картой. Поскольку изначально было понятно, что поломки обратной совместимости не избежать, мы также внесли архитектурные изменения, которые были необходимы для улучшения работы API (о них ближе к концу поста).
Что касается дизайна, нам было важно, чтобы интерфейс одинаково хорошо выглядел на устройствах и экранах разных размеров. Одна из основных сложностей заключается в том, что мы никогда не знаем заранее, как будет выглядеть сервис или сайт со встроенными картами. Поэтому при разработке редизайна нам нужно было постараться предусмотреть максимум вариантов.
Для решения наших задач мы решили в новой версии реализовать адаптивный дизайн интерфейса. На Yet another Conference дизайнер madhare и разработчик zloylos выступили с докладом о том, зачем нам понадобилась адаптивность и как именно мы ее реализовали в API . В этом посте я опишу предысторию и концепцию наших решений, расскажу о том, что еще нового появилось в версии 2.1-beta, а также о том, что еще изменится к релизу 2.1.
Зачем мы думаем о дизайне?
После релиза версии 2.0 мы уже писали пост , в котором рассказывали о нашем подходе к разработке API. Суть концепции заключается в том, что мы делаем продукт не только для разработчиков, но и для тех, кто будет пользоваться результатами их работы. Если человеку будет удобно и приятно пользоваться нашими картами, и он будет требовать от любимых сервисов именно их - это будет настоящий успех. При этом разработчикам тоже должно быть легко и приятно удовлетворять желания пользователей, а значит мы должны по-максимуму упростить их работу с API. С такими мыслями мы начали работу над версией 2.0, а новая 2.1-бета стала логичным продолжением этой же концепции.Исследование
Наблюдая за инсталляциями нашего API и анализируя кейсы использования карт, мы выделили два основных типа разработчиков:- Решают типовые задачи, не хотят тратить много времени, предпочитают готовые интерфейсы Яндекса. Таких примерно 90%.
- Решают нестандартные задачи или предпочитают даже типовые задачи решать по-своему. Им не подходят стандартные элементы управления. Нужна серьезная кастомизация карт. Логично, что это оставшиеся 10%.
Определившись с аудиториями, мы начали изучать кейсы использования. Оказалось, что в нашем случае основное значение имеет, как ни странно, размер. У нас получилось 3+1 варианта: маленькая, средняя, большая карта и мобильные сайты.
Рисуем дизайн для карт разных размеров
Самый тяжелый случай - маленькие карты. Кажется, что из-за маленького размера стоит убирать все элементы управления картой, но и терять функциональность тоже не хочется. Поэтому специально для маленьких карт мы сделали новый набор контролов:Также был добавлен новый элемент управления - «развернуть карту на весь экран». Он экономит место на сайте за счет размещения небольшой карты, а у конечного пользователя остается возможность посмотреть большую карту. Все нужное поведение карты запрограммировано уже на стороне API. Вообще идея этой кнопки родилась, когда мы думали о решении для мобильных устройств. Карта приемлемого размера на десктопе может стать совершенно бесполезной на мобильном. Фулскрин решает эту проблему:
Помимо этого изменился дизайн балунов для небольших размеров карт. Теперь на маленьких картах и экранах мобильных устройств стандартный балун заменяется на плашку внизу экрана. Это позволяет сохранить большую информативность карты для пользователей. При желании эту опцию можно отключить.
Со средними картами все гораздо проще. Поскольку есть, где развернуться:
Как и с большими картами:
Чтобы максимально упростить работу разработчиков при выборе элементов управления картой, мы сделали три готовых набора для разных размеров карты.
map.controls.add("default");
Список доступных ключей:
smallMapDefaultSet // для маленькой
mediumMapDefaultSet // для обычной
largeMapDefaultSet // для большой
Разумеется, по-прежнему можно самостоятельно указывать нужные контролы.
myMap.controls
.add("trafficControl") // пробки.add("searchControl") // поиск.add("zoomControl") // зум-контрол.add("typeSelector") // слои.add("geolocationControl") // геолокация.add("fullscreenControl") // фуллскрин
…
Адаптивность
Недостаточно просто отрисовать дизайн интерфейса для разных размеров карт. Ведь страницу с картой могут открывать на разных экранах. Именно поэтому решено было реализовывать адаптивное поведение интерфейсов карты. Различные элементы интерфейса перестраиваются и меняют свой размер в зависимости от фактического размера контейнера карты.Адаптивное поведение мы реализовали через control.Manager . Также его можно задавать и для тех кнопок и списков, которые вы создаете сами:
Работы по ускорению и оптимизации
Геообъект - это главная сущность на карте. За такой титул ему приходится расплачиваться довольно сложной и громоздкой структурой. Первая итерация работ над геообъектами заключалась в распределении нагрузки при их создании. Мы постарались вынести все подготовительные операции из конструктора геообъекта в места, где они действительно становятся нужны. Это дало очень хорошие результаты. Также в некоторых местах мы сделали ленивую инициализацию сущностей с помощью _defineGetter_ и defineProperty (_defineGetter_, кстати, немного быстрее). Мы сократили количество подписок на события геообъектов внутри нашей системы событий. Частично помог прием подписки сразу на группу геообъектов с последующим определением в обработчике целевого объекта. Здесь нужно признаться, что ускорение можно пощупать только на dom и canvas метках, новые svg метки нам предстоит дорабатывать (why we call it beta? Because it beta then nothing… ;)Во время работы у нас было время на небольшую уборку в коде, по ее результатам приведем микровыводы:
Микровывод 1. При передаче функции-обработчика намного выгоднее передавать отдельно функцию, отдельно контекст. Если у вас чешутся руки сделать bind сразу, подумайте, можете ли вы это себе позволить.
Микровывод 2. Сокращайте количество промежуточных массивов, объектов и анонимных функций. Они не всегда хорошо чистятся garbage collector-ом.
Прочие изменения
- В версии API 2.0 для определения местоположения по IP или с помощью Geolocation API разработчикам приходится самостоятельно использовать необходимые методы и обрабатывать полученный результат. В версии 2.1 достаточно просто добавить новый стандартный элемент управления:
control.GeolocationControl(parameters) Также был улучшен механизм определения местоположения пользователя, используемый в API. Теперь автоматически выбирается наиболее точный результат из браузерной геолокации и геолокации по IP-адресу. - Стандартные метки в API были перерисованы в SVG, а это значит, что им можно задавать произвольные цвета.
- Система пакетов в версии 2.1 будет ликвидирована. Интерфейсы API изменены таким образом, чтобы максимально вынести загрузку компонент API по требованию, для чего большинство отображений были переведены в асинхронный режим. Работы еще ведутся.
- Для такого масштабного обновления нам пришлось пожертвовать обратной совместимостью с версией 2.0. Также к официальному релизу версии 2.1 может сломаться обратная совместимость для некоторых частей бета-версии:
- Существенно изменится кластеризатор.
- Будет переписан map.action.Manager.
- Promises будут реализованы по
29 апреля 2014 года было объявлено, что новая версия API Яндекс.Карт 2.1 выходит из статуса беты и теперь Вы можете на неё безопасно переходить.
В нескольких ближайших заметках я планирую познакомить Вас с данной версией API.
Основные отличительные особенности JavaScript API Яндекс.Карт версии 2.1:
— новый адаптивный дизайн интерфейсов карты;
— мультимаршрутизатор — возможность построения всех возможных маршрутов вместо одного;
— модульная система API. Список всех модулей API приведен в справочнике.
— новый способ отображения объектов на карте, который позволяет создавать больше меток, чем в версии 2.0.
Подробную документацию по новой версии API Яндекс.Карт 2.1 можно прочитать .
Давайте рассмотрим простейший пример создания карты с использованием API Яндекс.Карт 2.1.
Вот его код:
At the very beginning, we connect the maps API at http://api-maps.yandex.ru/
Let's look at the options in more detail:
lang - set by two parameters language_region,
language - two-digit language code. Specified in ISO 639-1 format.
region - two-digit country code. Specified in ISO 3166-1 format.
On the this moment the following locales are supported:
lang=ru_RU;
lang=en_US;
lang=ru_UA;
lang=uk_UA;
lang=tr_TR.
Additional options can be used:
coordorder - the order in which geographic coordinates are specified in API functions that accept longitude-latitude pairs as input (for example, Placemark).
Possible values:
latlong - [latitude, longitude] - used by default;
longlat - [longitude, latitude].
Default value: latlong.
load - List of modules to load.
Default value: package.full.
mode - API loading mode.
mode=release - API code can be downloaded in packaged form to minimize traffic and execution speed in the browser;
mode=debug - download mode as source code.
Default value: release.
Read more about connection options
To display the map, a container of a non-zero size is specified, any block-type HTML element can be used as a container, in the example it is div.
Map parameters are set in the code:
myMap = new ymaps.Map('map', (
center: , // center of the Nizhny Novgorod map
zoom: 12 - zoom level
});
The map should be created after the entire web page has loaded. This will make sure that the container for the map has been created and can be accessed by id. To initialize the map after the page has loaded, you can use the ready() function.
The ready function will be called when the API has been loaded and the DOM has been generated.
ymaps.ready(init);
function init()(
// Create an instance of the map and bind it to the container with
// given id ("map").
myMap = new ymaps.Map('map', (
// When initializing the map, you must specify
// its center and scale factor.
center: , // Nizhny Novgorod
zoom: 12
});
By default, the map displays all available controls.
Map type - scheme.
The API provides five built-in map types:
Scheme (yandex#map) - by default;
Satellite (yandex#satellite);
Hybrid (yandex#hybrid);
People's map (yandex#publicMap);
Hybrid of the national map (yandex#publicMapHybrid).
Example with determining the type of map Satellite
Example code:
As I said before, the default set of 'mediumMapDefaultSet' controls is added to the map by default.
In order to add the necessary controls to the map, you can specify a list of corresponding keys in the controls parameter when creating the map.
Here is the example code for map scale and type controls.
Example code:
|
It is possible to set the behavior of the map using the behaviors parameter.
By setting its values, we can enable or disable various options for the map's behavior:
scaling the map by double-clicking the mouse button;
dragging the map with the mouse or single touch;
scaling the map when selecting an area with the left mouse button;
scaling the map with a multi-touch touch;
scaling the map when selecting an area right click mice;
distance measurement;
zooming the map with the mouse wheel.
Code example with mouse wheel zoom disabled.
|
It is possible to change the parameters of a map after it has been created.
Turn on mouse wheel zoom
myMap.behaviors.enable("scrollZoom");
Turn off
myMap.behaviors.disable("scrollZoom");
Installing a new type of map Folk
myMap.setType('yandex#publicMap');
Setting up a new map center
That's all for now.
To be continued…