Yandex maps api 2.1. Why do we think about design?

We have released a beta version of the Yandex.Maps 2.1 API. Its main feature is a complete redesign of the map interface. Moreover, the changes affected not only appearance, but also the behavior of map controls. Since it was clear from the start that a backwards compatibility break was inevitable, we also made architectural changes that were necessary to improve API work(more about them towards the end of the post).

In terms of design, it was important to us that the interface looks equally good on devices and screens of different sizes. One of the main difficulties is that we never know in advance what a service or site with built-in maps will look like. Therefore, when developing the redesign, we had to try to provide as many options as possible.

To solve our problems, we decided to new version implement adaptive interface design. At Yet another Conference, designer madhare and developer zloylos gave a presentation on why we needed adaptability and how exactly we implemented it in the API. In this post, I will describe the background and concept of our solutions, talk about what else is new in version 2.1-beta, as well as what else will change for the 2.1 release.

Why do we think about design? After the release of version 2.0, we already wrote a post in which we talked about our approach to API development. The essence of the concept is that we are making a product not only for developers, but also for those who will use the results of their work. If a person finds it convenient and pleasant to use our cards, and he demands them from his favorite services, this will be a real success. At the same time, it should also be easy and pleasant for developers to satisfy the desires of users, which means we must simplify their work with the API as much as possible. With these thoughts in mind, we started working on version 2.0, and the new 2.1 beta became a logical continuation of the same concept. Research Observing installations of our API and analyzing cases of using cards, we identified two main types of developers:
  • They solve typical problems, do not want to spend a lot of time, and prefer ready-made Yandex interfaces. This is approximately 90%.
  • They solve non-standard problems or prefer to solve even standard problems in their own way. Standard controls do not suit them. Serious customization of maps is needed. It is logical that this is the remaining 10%.
So, we needed to do well first while leaving room for maneuver in second. Those. prepare a set of ready-made solutions that themselves control the appearance of the final map, i.e. “they do it well”, but at the same time, if desired, they can be customized to suit your own needs. The main task was to maintain balance.

Having decided on the audiences, we began to study use cases. It turned out that in our case, oddly enough, size is of primary importance. We ended up with 3+1 options: small, medium, large map and mobile sites.

We draw designs for cards of different sizes. The most difficult case is small cards. It seems that due to the small size it is worth removing all the card controls, but you also don’t want to lose functionality. Therefore, especially for small maps, we made a new set of controls:

A new control has also been added - “expand the map to full screen”. It saves space on the site by placing small map, and the end user still has the opportunity to view large map. All the necessary behavior of the card is already programmed on the API side. In general, the idea for this button was born when we were thinking about a solution for mobile devices. A map of a reasonable size on a desktop can become completely useless on a mobile device. Fullscreen solves this problem:

In addition, the design of baluns for small map sizes has changed. Now on small maps and mobile device screens the standard balloon is replaced with a bar at the bottom of the screen. This allows you to keep the map more informative for users. If desired, this option can be disabled.

With medium cards everything is much simpler. Because there is room to turn around:

As with large maps:

To make it as easy as possible for developers when choosing map controls, we made three ready-made sets for different map sizes.
map.controls.add("default");
List of available keys:
smallMapDefaultSet // for small
mediumMapDefaultSet // for normal
largeMapDefaultSet // for large

Of course, you can still specify the necessary controls yourself.
myMap.controls .add("trafficControl") // traffic.add("searchControl") // search.add("zoomControl") // zoom control.add("typeSelector") // layers.add("geolocationControl ") // geolocation.add("fullscreenControl") // fullscreen...

Adaptability It is not enough to simply render the interface design for different card sizes. After all, a page with a map can be opened on different screens. That is why it was decided to implement adaptive behavior of the map interfaces. Various interface elements rearrange and change size depending on the actual size of the map container.

We implemented adaptive behavior through control.Manager . You can also set it for those buttons and lists that you create yourself:


Acceleration and optimization work A geo object is the main entity on the map. For such a title he has to pay with a rather complex and cumbersome structure. The first iteration of work on geo-objects consisted of distributing the load during their creation. We tried to move all the preparatory operations from the geoobject constructor to the places where they are actually needed. This gave very good results. Also in some places we made lazy initialization of entities using _defineGetter_ and defineProperty (_defineGetter_, by the way, is a little faster). We have reduced the number of subscriptions to geo object events within our event system. Partially what helped was accepting a subscription to a group of geo-objects at once and then defining the target object in the handler. Here we must admit that the acceleration can only be felt on the dom and canvas labels, we have to finalize the new svg labels (why we call it beta? Because it beta then nothing... ;)

While working, we had time to do a little cleaning in the code; based on its results, here are the micro-findings:
Micro-conclusion 1. When passing a handler function, it is much more profitable to pass the function separately and the context separately. If you're itching to do a bind right away, consider whether you can afford it.
Micro-inference 2. Reduce the number of intermediate arrays, objects and anonymous functions. They are not always cleaned well by the garbage collector.

Other changes
  • In version API 2.0, to determine location by IP or using the Geolocation API, developers must independently use the necessary methods and process the result. In version 2.1, you simply add a new standard control:
    control.GeolocationControl(parameters) The user location mechanism used in the API has also been improved. Now the most accurate result is automatically selected from browser geolocation and geolocation by IP address.
  • The standard labels in the API have been redrawn in SVG, which means they can be given custom colors.
  • The package system in version 2.1 will be eliminated. The APIs have been modified to accommodate on-demand loading of API components as much as possible, for which most mappings have been moved to asynchronous mode. Work is still underway.
  • For such a large update we had to sacrifice backward compatibility with version 2.0. Also, by the official release of version 2.1, backward compatibility for some parts of the beta version may break:
    • The clusterer will change significantly.
    • Map.action.Manager will be rewritten.
    • Promises will be implemented according to
  • 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 go to the documentation, you won’t be able to figure it out without half a liter, 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, the latest, at the time of writing, version 2.1.

    When laying out a website in contact information, it is often necessary to insert a map on which the location of the organization for which the website is being developed will be marked. In the simplest cases, this can simply be a screenshot from online maps (or not online):

    To insert interactive map map constructor 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 using maps, this article will look at creating a map by simply adding a custom label and balloon.

    First, let's connect the API components:

    If you are developing a large application using maps, then it is better to connect 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— map center indicating width and longitude;
  • zoom— map scale factor.
  • By default, Yandex.Maps creates a lot of unnecessary elements that 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 card:

  • Of the map elements, there is only a zoom slider;
  • The map should not change the scale by scrolling the mouse.
  • 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 "zoomControl" with positioning from the upper left corner.

    Now you need to add a pin to the map; for the article, 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 We indicate the coordinates of the mark, and in the third parameter:

  • indicate in iconLayout that a custom label image will be used;
  • iconImageHref— path to the image;
  • iconImageSize— indicate the dimensions of the image;
  • iconImageOffset— we indicate the shift from the upper left corner of the picture to the point in the image, which we point to the volume we need. This is necessary so that when scaling the map the position of the mark does not get lost. Why the offset is indicated in negative values ​​- only God knows the creator of the API.
  • And through myMap.geoObjects.add() add a mark to the map.

    Now let’s make a balloon, which will be displayed when you click on the map label; we’ll take the balloon layout 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 += "" ; html += "

    The Victoria Tower Gardens

    " ; html += "" ; html += "

    City of London

    " ; html += "" ; html += "

    United Kingdom

    " ; html += "

    020 7641 5264

    " ; 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) ; )

    Here we are:

  • V balloonContent specify the content that will be displayed when the balloon is opened;
  • balloonLayout— we indicate that a custom image will be used as a balloon layout;
  • balloonContentSize And balloonImageSize— content and image sizes, respectively;
  • balloonImageHref— path to the image;
  • balloonImageOffset— offset relative to the upper left corner;
  • balloonShadow— disabling the shadow of the balloon (with custom images does not affect anything).
  • 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 critical 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.

    On April 29, 2014, it was announced that the new version of the Yandex.Maps API 2.1 is leaving beta status and you can now safely switch to it.

    In the next few posts I plan to introduce you to this version of the API.

    Basic distinctive features JavaScript API Yandex.Maps version 2.1:

    — new adaptive design of map interfaces;

    — multirouter — the ability to build all possible routes instead of just one;

    — modular API system. A list of all API modules is given in the reference book.

    - a new way of displaying objects on the map, which allows you to create more markers than in version 2.0.

    Detailed documentation on the new version of the Yandex.Maps API 2.1 can be read.

    Let's look at the simplest example of creating a map using the Yandex.Maps 2.1 API.

    Here is his code:

    The simplest example creating a map using the Yandex.Maps API 2.1. var myMap; // Wait for the API to load and the DOM to be ready. ymaps.ready(init); function init () ( // Creating a map instance and binding it to a container with // a given id ("map"). myMap = new ymaps.Map("map", ( // When initializing a map, you must specify // its center and zoom factor. center: , // Nizhny Novgorod zoom: 12 ));

    At the very beginning, we connect the maps API at http://api-maps.yandex.ru/

    Let's take a closer look at the parameters:

    lang - specified by two language_region parameters,

    language - two-digit language code. Specified in ISO 639-1 format.
    region - two-digit country code. Specified in ISO 3166-1 format.

    The following locales are currently supported:

    lang=ru_RU;
    lang=en_US;
    lang=ru_UA;
    lang=uk_UA;
    lang=tr_TR.

    Additional parameters 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 loaded modules.

    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 in source code form.

    Default value: release.

    You can read more about connection parameters

    To display the map, a container of non-zero size is specified; any block-type HTML element can be used as a container, in the example it is a div.

    Map parameters are set in code:

    myMap = new ymaps.Map('map', (
    center: , // center of the Nizhny Novgorod map
    zoom: 12 - zoom level
    });

    You should create a map after the entire web page has loaded. This will ensure that the container for the card 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 is loaded and the DOM is formed

    ymaps.ready(init);

    function init() (
    // Create a map instance and bind it to a container with
    // given id ("map").
    myMap = new ymaps.Map('map', (
    // When initializing the map, you must specify
    // its center and scaling factor.
    center: , // Nizhny Novgorod
    zoom: 12
    });

    By default, the map displays all available controls.

    Card type - diagram.

    The API provides five built-in map types:

    Scheme (yandex#map) - default;
    Satellite (yandex#satellite);
    Hybrid (yandex#hybrid);
    People's Map (yandex#publicMap);
    Hybrid people's map(yandex#publicMapHybrid).

    Example with determining the type of card Satellite

    Example code:

    Let's select the card type - Satellite. An example of creating a map using the Yandex.Maps API 2.1. body, html ( padding: 0; margin: 0; width: 100%; height: 100%; ) var myMap; // Wait for the API to load and the DOM to be ready. ymaps.ready(init); function init () ( // Creating a map instance and binding it to a container with // a given id ("map"). myMap = new ymaps.Map("map", ( // When initializing a map, you must specify // its center and zoom factor. center: , // Nizhny Novgorod zoom: 12, type: "yandex#satellite" ));

    As I already said, the default set of controls 'mediumMapDefaultSet' 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 it.

    Here is an example code for controls for map scale and type.

    Example code:

    body, html ( padding: 0; margin: 0; width: 100%; height: 100%; )

    Map controls. An example of creating a map using the Yandex.Maps API 2.1. body, html ( padding: 0; margin: 0; width: 100%; height: 100%; ) var myMap; // Wait for the API to load and the DOM to be ready. ymaps.ready(init); function init () ( // Creating a map instance and binding it to a container with // a given id ("map"). myMap = new ymaps.Map("map", ( // When initializing a map, you must specify // its center and zoom factor. center: , // Nizhny Novgorod zoom: 12, controls: ["zoomControl", "typeSelector"] ));

    It is possible to set the behavior of the map using the behaviors parameter.

    By setting its values, we can enable or disable various map behavior parameters:

    zoom the map by double clicking the mouse button;

    dragging the map using the mouse or single touch;

    zooming the map when selecting an area with the left mouse button;

    zoom map using multi-touch touch;

    zooming the map when selecting an area with the right mouse button;

    distance measurement;

    zooming the map with the mouse wheel.

    Example code with mouse wheel zoom disabled.

    body, html ( padding: 0; margin: 0; width: 100%; height: 100%; )

    Managing card behavior. An example of creating a map using the Yandex.Maps API 2.1. body, html ( padding: 0; margin: 0; width: 100%; height: 100%; ) var myMap; // Wait for the API to load and the DOM to be ready. ymaps.ready(init); function init () ( // Creating a map instance and binding it to a container with // a given id ("map"). myMap = new ymaps.Map("map", ( // When initializing a map, you must specify // its center and zoom factor. center: , // Nizhny Novgorod zoom: 12 )); myMap.behaviors.disable("scrollZoom");

    It is possible to change the map parameters after it has been created.

    Enable zooming with the mouse wheel

    myMap.behaviors.enable("scrollZoom");

    Turn off

    myMap.behaviors.disable("scrollZoom");

    Install new type Narodnaya cards

    myMap.setType('yandex#publicMap');

    Setting a new map center

    That's all for now.

    To be continued…

    Share: