Documentation
Reference
2.1.50 (current version)
collection
interactivityModel
Interfaces

Search on a map

Geocoding

The API provides a geocoding service, which can determine an object's geographical coordinates based on its name (forward geocoding), or the opposite, find an object's name based on its coordinates (reverse geocoding).

Both types of geocoding (forward and reverse) are performed using the geocode function, which can be passed an object name as a string, or coordinates as an array.

var myGeocoder = ymaps.geocode("Petrozavodsk");
var myReverseGeocoder = ymaps.geocode([61.79,34.36]);

Restriction. When accessing the geocoding service, we recommend keeping the HTTP Referer header enabled. If this header is hidden or its transmission is disabled, search is available only within the following countries: Russia, Ukraine, Belarus, Kazakhstan, Georgia, Abkhazia, South Ossetia, Armenia, Azerbaijan, Moldova, Turkmenistan, Tajikistan, Uzbekistan, Kyrgyzstan and Turkey.

The geocode function is asynchronous, meaning that data is exchanged with the server while it is being executed.

Asynchronous interaction is implemented using promises. Invoking the geocode function causes immediate creation of a vow.Promise type object, which performs the set functions when either geocoding results or an error message are returned from the server.

The result of the geocode function is passed to the handler function as a GeoObjectCollection collection. This object implements the IGeoObject interface, meaning it can be placed on the map.

var myGeocoder = ymaps.geocode("Petrozavodsk");
myGeocoder.then(
    function (res) {
        alert('Object coordinates:' + res.geoObjects.get(0).geometry.getCoordinates());
    },
    function (err) {
        alert('Error');
    }
);

Geocoding results are passed to the handler function either as a GeoObjectCollection collection (by default) or in JSON format. The format of returned data is set in the json option (true/false). For more information about the format of returned data, see Search on the map.

The search can be performed across the entire world map, or in a specified rectangular area. However, a rectangular area might not strictly restrict the search. This means the search will be performed across the entire map, but the closer a found object is to the center of the area, the higher it will be ranked in the results.

For reverse geocoding, the type of object to find can be specified (such as building, street, neighborhood, town, or metro station).

Found objects are ranked based on their distance from the set point.

var myCoords = [55.754952,37.615319];
myMap.geoObjects.add(
    new ymaps.Placemark(myCoords,
        {iconContent:'Where is the metro?'},
        {preset: 'islands#greenStretchyIcon'}
    )
);
var myGeocoder = ymaps.geocode(myCoords, {kind: 'metro'});
myGeocoder.then(
    function (res) {
        var nearest = res.geoObjects.get(0);
        var name = nearest.properties.get('name');
        nearest.properties.set('iconContent', name);
        nearest.options.set('preset', 'islands#redStretchyIcon');
        myMap.geoObjects.add(res.geoObjects);
    },
    function (err) {
        alert('Error');
    }
);

When searching for streets, neighborhoods/regions, or cities/towns, their respective buildings are not included, regardless of size.

var myGeocoder = ymaps.geocode('Noviy Arbat, 10');
myGeocoder.then(
    function (res) {
        var coords = res.geoObjects.get(0).geometry.getCoordinates();
        var myGeocoder = ymaps.geocode(coords, {kind: 'street'});
        myGeocoder.then(
            function (res) {
                var street = res.geoObjects.get(0);
                var name = street.properties.get('name');
                // Outputs "Bolshaya Molchanovka street",
                // even though reverse geocoding
                // gives the coordinates of building 10 on Noviy Arbat street.
                alert(name);
            }
        );
});

Multi-address geocoding

It is often necessary to geocode multiple geographical objects. For example, when multiple cities, streets, or metro stations need to be marked on the map at once.

Most often, geocoding is done on the client side (meaning the browser sends requests to the geocoder). For multiple geocoding, this approach is not always optimal. The problem is that the geocoder only allows getting data for one object per request. So the more addresses you need to geocode, the more HTTP requests you have to send.

Sending a large number of HTTP requests increases traffic, and processing all the responses makes it take longer to display the data on the map. In addition, you will likely exceed the daily limit of 25,000 requests to the geocoder (see the User Agreement). When searching for one hundred objects on the map, for example, the browser sends the server one hundred requests. So if 300 users visit the site, the number of requests to the server will be 30,000.

The solution to this problem is geocoding data on the server side. If the same geographical objects always need to be found on the map, there is no point in geocoding separately on each client. In this case, it makes sense to perform it once on the server side and cache the result. Then the server passes clients the data that is prepared for adding to the map.

Server-side geocoding

To implement server-side geocoding, the Node.js module (multi-geocode) has been developed, which uses the HTTP geocoding service. This module allows searching for a large number of objects simultaneously, using their geographical names. The result can be added to a map using built-in API features.

Note. The multi-geocode module only allows performing forward geocoding.

To install the module, use the package manager npm:

npm install multi-geocoder

After the Node.js application module has been installed, the MultiGeocoder class will be available, which is initialized by an object with the following fields (all fields are optional):

  • provider – Geocoding provider. The supported providers are Yandex and Google (by default, it takes the value 'yandex').
  • coordorder – Preferred order of coordinates in the geocoder response. By default, coordinates are returned in the order: longitude, latitude ('longlat').
  • Pre-defined geocoding parameters available for the specified provider.
// Enabling the multi-geocoder module
var MultiGeocoder = require('multi-geocoder'),
    // Getting access to the geocoding service.
    geocoder = new MultiGeocoder({
        coordorder: 'latlong',
        lang: 'ru-RU'
    });

To form and send the request to the geocoder, the geocode function is used. It accepts the following input parameters:

  • Array of strings with addresses to geocode ('Moscow, Krilatskiye Holmi street, 28'), or an array of objects containing addresses and any other properties ({'address': 'Moscow, Krilatskiye Holmi street, 28', 'organization': 'school'}).

    Note. Before forming the request, the module extracts the addresses from the passed array using the getText method. By default it is assumed that addresses are specified as strings, so getText returns the contents of the array items in their entirety. If the addresses are set as objects with fields, the getText method needs to be redefined to that it returns the field values containing the addresses. For more information, see below.

  • Pre-defined geocoding parameters that will only be applied to the current request.

The following example shows geocoding addresses set as strings:

var MultiGeocoder = require('multi-geocoder'),
    geocoder = new MultiGeocoder({ coordorder: 'latlong', lang: 'ru-RU' });

geocoder.geocode([
    'Moscow, 1905 Street, 19',
    'Moscow, 1st Kvesisskaya street, 18',
    'Moscow, 1st Tverskoy-Yamskoy lane, 16'
    ], {
    // The description of objects in the response will be in English,
  // even though the lang parameter is also set in the MultiGeocoder constructor.
    lang: 'en-US'
})
    .then(function (res) {
        console.log(res);
    });
Note. Geocoding parameters that are set via the geocode function have higher priority than parameters that are set in the MultiGeocoder constructor.

In the next example, the geocode function gets passed an array of objects with address, name, and phone fields. To extract the addresses for geocoding from the specified objects, the getText method must be redefined:

var MultiGeocoder = require('multi-geocoder'),
    geocoder = new MultiGeocoder({ provider: 'yandex', coordorder: 'latlong' }),
    // Getting a provider instance.
    provider = geocoder.getProvider();

// Redefining the getText() method, which extracts the addresses
// to be geocoded from the passed array.
provider.getText = function (point) {
    var text = 'Moscow, ' + point.address;
    console.log(text);
    return text;
};
geocoder.geocode([
    {
        "address": "1905 street, 19",
        "name": "Ancient Healer",
        "phone": "8-499-253-52-61"
    }, {
        "address": "1st Kvesisskaya street, 18",
        "name": "A5 #2",
        "phone": "8-495-614-04-67"
    }, {
        "address": "1st Tverskoy-Yamskoy lane, 16",
        "name": "Samson Pharmacy #9",
        "phone": "8-495-251-22-27"
    }
])
    .then(function (res) {
        console.log(res);
    }); 

You can look at a more detailed example in the following files: index.js or source.json (input data), or geocoded.json (geocoding results).

The geocode function returns the promise object (vow.Promise), which executes the given handler function when the server returns the geocoding results.

The geocoding result is passed to the handler function in GeoJSON format. This format is intended for describing various geographical data structures. Objects represented in GeoJSON format can be added to the map.

Result of multiple geocoding using the multi-geocode module:


{ type
[no-highlight[

Description

Type of GeoJSON object.

  • FeatureCollection – Description of a collection of objects.
  • Feature – Description of the final object.

]no-highlight]
: 'FeatureCollection', features: [{ // Search results for 'Moscow, 1905 street, 19' type
[no-highlight[

Description

Type of GeoJSON object.

  • FeatureCollection – Description of a collection of objects.
  • Feature – Description of the final object.

]no-highlight]
: 'Feature', bbox
[no-highlight[

Description

Coordinates of the bounding area.

]no-highlight]
: [ [ 37.556586, 55.765554 ], [ 37.560682, 55.767863 ] ], geometry: { type
[no-highlight[

Description

Geometry type.

]no-highlight]
: 'Point', coordinates
[no-highlight[

Description

Coordinates of the found toponym.

]no-highlight]
: [ 37.558634, 55.766709 ] }, properties: { name
[no-highlight[

Description

Name of the object, or an incomplete address. This information is usually used for displaying on the placemark or balloon.

]no-highlight]
: '1905 street, 19', description
[no-highlight[

Description

Detailed address of the object.

]no-highlight]
: 'Moscow, Russia', metaDataProperty: { GeocoderMetaData: { kind
[no-highlight[

Description

Type of toponym found. List of acceptable values.

]no-highlight]
: 'house', text
[no-highlight[

Description

Full address of the toponym in a single line of text.

]no-highlight]
: 'Russia, Moscow, 1905 street, 19', precision
[no-highlight[

Description

How precisely the number of the found premise must match the building number from the request.

]no-highlight]
: 'exact', AddressDetails: { Country: { AddressLine
[no-highlight[

Description

Requested string in search.

]no-highlight]
: 'Moscow, 1905 street, 19', CountryNameCode
[no-highlight[

Description

Country code, according to the ISO 3166-1 standard.

]no-highlight]
: 'RU', CountryName
[no-highlight[

Description

Country name.

]no-highlight]
: 'Russia', AdministrativeArea: { AdministrativeAreaName
[no-highlight[

Description

Region, province, territory, republic, city — federation subjects.

]no-highlight]
: 'Moscow region', SubAdministrativeArea: { SubAdministrativeAreaName
[no-highlight[

Description

Area of a region, municipal district, township, or rural settlement.

]no-highlight]
: 'Moscow', Locality: { LocalityName
[no-highlight[

Description

Location: city, town, village, etc.

]no-highlight]
: 'Moscow', Thoroughfare: { ThoroughfareName
[no-highlight[

Description

Commonly recognized named territory according to the xAL format specification.

]no-highlight]
: '1905 street', Premise: { PremiseNumber
[no-highlight[

Description

Final unit in the administrative-territorial hierarchy. Building or house number, park, bridge name, and so on. For more information, see the xAL format specification.

]no-highlight]
: '19' } } } } } } } } } } } // Search results for 'Moscow, 1st Kvesisskaya street, 18' { type
[no-highlight[

Description

Type of GeoJSON object.

  • FeatureCollection – Description of a collection of objects.
  • Feature – Description of the final object.

]no-highlight]
: 'Feature', ... } // Search results for '1st Tverskoy-Yamskoy lane, 16' { type
[no-highlight[

Description

Type of GeoJSON object.

  • FeatureCollection – Description of a collection of objects.
  • Feature – Description of the final object.

]no-highlight]
: 'Feature', ... } ] }

A section of code is given below that demonstrates loading saved GeoJSON data and adding it to the map:

// Loading data from the server using jQuery.
jQuery.ajax({
    url: 'http://api.yandex.ru/maps/doc/jsapi/2.1/examples/geocoded.json',
    dataType: 'json'
}).then(function(res) {
      // Forming a selection based on loaded data.
      var objects = ymaps.geoQuery(res);
      objects.addToMap(myMap);
  });

The API currently allows manipulation of GeoJSON data only via the GeoQueryResult class. This means that a selection must first be formed based on the loaded data, and then various actions can be performed on it (add to the map, clusterize, and so on).

The “Search on map” control

The “Search on map” control gives users the ability to search for desired objects on the map. When a user enters a query in the search box, the API automatically performs a search and then displays the results on the map. Users can search for objects either by address or by geographical coordinates. In addition, this control can be used to search for businesses.

The “Search on map” control is implemented by the control.SearchControl class. The example below shows how to add this control to the map:

// Creating the “Search on map” control.
var searchControl = new ymaps.control.SearchControl({
        options: {
            // Search will be performed across toponyms and businesses.
            provider: 'yandex#search'
        }
    });

// Adding the control to the map.
myMap.controls.add(searchControl);

Note. To make it possible to search for businesses as well as toponyms, pass the provider: 'yandex#search' option to the control.SearchControl class.

To programmatically perform a search for some object, call the search() function. The search for objects will be performed within the current rectangular area.

searchControl.search('Starbucks');

The control.SearchControl class provides the following methods for working with search results:

getResult

A method that returns an object found at the specified index. The method works asynchronously. It returns a Promise object that is resolved by the found object or rejected with an error.

var searchControl = new ymaps.control.SearchControl({
        options: {
            // The search will be performed across toponyms and businesses.
            provider: 'yandex#search'
        }
    });

var result = searchControl.getResult(0);
result.then(function (res) {
    console.log("Results " + res );
}, function (err) {
    console.log("Error");
});
getResultsArray

Returns an array containing all current results.

var searchControl = new ymaps.control.SearchControl({
        options: {
            // The search will be performed across toponyms and businesses
            provider: 'yandex#search'
        }
    });

// Subscribing to the search result selection event.
searchControl.events.add('resultselect', function (e) {
    // Getting the results array.
    var results = searchControl.getResultsArray(),
        // Index of the selected object.
        selected = e.get('index'),
        // Getting the coordinates of the selected object.
        point = results[selected].geometry.getCoordinates();
})
getResponseMetaData

Returns the geo search metadata.

var searchControl = new ymaps.control.SearchControl({
        options: {
            // The search will be performed across toponyms and businesses.
            provider: 'yandex#search'
        }
    });

searchControl.search('Starbucks');

searchControl.events.add('resultselect', function (e) {
    var index = e.get('index'),
        results = searchControl.getResponseMetaData();
    console.log(results.SearchRequest.request); // Starbucks
    console.log(results.SearchRequest.results); // 20
})
getResultsCount

Returns the number of results found.

var searchControl = new ymaps.control.SearchControl({
        options: {
            // The search will be performed across toponyms and businesses.
            provider: 'yandex#search'
        }
    });

// Subscribing to the event of getting search results from the server.
searchControl.events.add('load', function (e) {
    var count = searchControl.getResultsCount();
    console.log("Number of search results found: " + count);
})
getSelectedIndex

Returns the index of the selected item.

var searchControl = new ymaps.control.SearchControl({
        options: {
            // The search will be performed across toponyms and businesses.
            provider: 'yandex#search'
        }
    });

// Subscribing to the event of getting search results from the server.
searchControl.events.add('resultselect', function (e) {
    var index = searchControl.getSelectedIndex(e);
    console.log("Index of the selected element: " + index);
})
showResult

Displays the result on the map.

// We want to always show the first result
// regardless of the number of objects
// found on the map (1 or more).
var searchControl = new ymaps.control.SearchControl({
   options: {
       noSelect: true
   }
});
searchControl.events.add('load', function (event) {
    // Checking that this event isn't just finishing loading results
    // and the query has at least one result found.
    if (!event.get('skip') && searchControl.getResultsCount()) {
        searchControl.showResult(0);
    }
});
hideResult

Hides the result shown on the map.

// If we displayed a result on the map using control.SearchControl.showResult
// or it was shown automatically when searching, we can hide it,
// for example, by clicking a button.
var myButton = new ymaps.control.Button("Hide results");
myButton.events.add('click', function () {
    searchControl.hideResult();
    }, this);

myMap.controls.add(myButton, {
    selectOnClick: false
});

All the available methods are listed in the reference guide.

You can look at the example of using control.SearchControl in the sandbox.