---
metadata:
  - name: generator
    content: Diplodoc Platform v5.39.1
alternate:
  - https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/examples/cases/geolocation_api.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/llms.txt

# Определение местоположения с помощью Geolocation API

<iframe id="LIVE-EXAMPLE" style="width:100%;height: 400px;border-radius: 8px;border: 1px solid rgba(92, 94, 102, 0.14);" frameBorder="0" src="https://yastatic.net/s3/front-maps-static/maps-front-jsapi-v2-0/examples/1/out/s3-cases/ru/geolocation_api/index.html" allow="fullscreen"></iframe>

<a target="_blank" rel="noopener noreferrer" style="display: inline-block;margin-top: 10px;cursor: pointer;border-radius: 4px;padding: 9px 12px;background: #151515;color: white;text-decoration: none;font-weight: 500" href="https://codesandbox.io/p/sandbox/cymppl?file=index.html">Open in CodeSandbox</a>

<div id="doc">
<div id="references">
    <a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/ref/reference/ready">ready</a>, <a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/ref/reference/Map">Map</a>, <a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/ref/reference/geocode">geocode</a>, <a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/ref/reference/control.Button">control.Button</a>
</div>
<p>
    В связи с ростом популярности мобильных устройств часто возникает задача
    определения местоположения пользователя.
</p>
<p>
    API Яндекс.Карт умеет <a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/dg/concepts/geolocation">определять
    местоположение пользователя на основе его IP-адреса</a>
    (<a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/examples/cases/geolocation_ip">пример</a>),
    однако этот способ не такой точный, как при использовании
    <a href="http://www.w3.org/TR/geolocation-API/">Geolocation API</a>.
</p>
<p>
    В данном примере на карте размещается кнопка, при нажатии на которую
    производится обращение к Geolocation API устройства и получение его координат.
    Для полученных координат производится обратное
    <a href="https://yandex.ru/dev/maps/archive/doc/jsapi/2-0/ru/dg/concepts/geocoding">геокодирование</a> и определяется
    адрес.
</p>
<p>
    Обсуждение этого примера можно посмотреть
    в <a href="https://yandex.ru/blog/ymapsapi/438">клубе</a>.
</p>
</div>

{% list tabs %}

-   index.html

    ```html
    <!DOCTYPE html>

    <html>
        <head>
            <title>
                Примеры. Определение местоположения с помощью Geolocation API
            </title>
            <meta
                http-equiv="Content-Type"
                content="text/html; charset=utf-8"
            />
            <!--
            Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
            Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
        -->
            

            
        </head>

        <body>
            <div id="map" style="width:400px; height:300px"></div>
        </body>
    </html>
    ```

-   geolocation_api.js

    ```js
    var baseIconsURL = "icons/";

    function init() {
        /**
         * Класс кнопки определения местоположения пользователя.
         * с помощью Geolocation API.
         * @see http://www.w3.org/TR/geolocation-API/
         * @class
         * @name GeolocationButton
         * @param {Object} params Данные для кнопки и параметры к Geolocation API.
         */
        function GeolocationButton(params) {
            GeolocationButton.superclass.constructor.call(this, params);

            // Расширяем опции по умолчанию теми, что передали в конструкторе.
            this.geoLocationOptions = ymaps.util.extend(
                {
                    // Не центрировать карту.
                    noCentering: false,
                    // Не ставить метку.
                    noPlacemark: false,
                    // Не показывать точность определения местоположения.
                    noAccuracy: false,
                    // Режим получения наиболее точных данных.
                    enableHighAccuracy: true,
                    // Максимальное время ожидания ответа (в миллисекундах).
                    timeout: 10000,
                    // Максимальное время жизни полученных данных (в миллисекундах).
                    maximumAge: 1000,
                },
                params.options
            );
        }

        ymaps.util.augment(GeolocationButton, ymaps.control.Button, {
            /**
             * Метод будет вызван при добавлении кнопки на карту.
             * @function
             * @name GeolocationButton.onAddToMap
             * @param {ymaps.Map} map Карта на которую добавляется кнопка.
             */
            onAddToMap: function () {
                GeolocationButton.superclass.onAddToMap.apply(this, arguments);

                ymaps.option.presetStorage.add("geolocation#icon", {
                    iconImageHref: "man.svg",
                    iconImageSize: [27, 26],
                    iconImageOffset: [-10, -24],
                });

                this.hint = new GeolocationButtonHint(this);
                // Обрабатываем клик на кнопке.
                this.events.add("click", this.onGeolocationButtonClick, this);
            },
            /**
             * Метод будет вызван при удалении кнопки с карты.
             * @function
             * @name GeolocationButton.onRemoveFromMap
             * @param {ymaps.Map} map Карта с которой удаляется кнопка.
             */
            onRemoveFromMap: function () {
                this.events.remove(
                    "click",
                    this.onGeolocationButtonClick,
                    this
                );
                this.hint = null;
                ymaps.option.presetStorage.remove("geolocation#icon");

                GeolocationButton.superclass.onRemoveFromMap.apply(
                    this,
                    arguments
                );
            },
            /**
             * Обработчик клика на кнопке.
             * @function
             * @private
             * @name GeolocationButton.onGeolocationButtonClick
             * @param {ymaps.Event} e Объект события.
             */
            onGeolocationButtonClick: function (e) {
                // Меняем иконку кнопки на прелоадер.
                this.toggleIconImage("loader.svg");

                // Делаем кнопку ненажатой
                if (this.isSelected()) {
                    this.deselect();
                }

                if (navigator.geolocation) {
                    // Запрашиваем текущие координаты устройства.
                    navigator.geolocation.getCurrentPosition(
                        ymaps.util.bind(this._onGeolocationSuccess, this),
                        ymaps.util.bind(this._onGeolocationError, this),
                        this.geoLocationOptions
                    );
                } else {
                    this.handleGeolocationError(
                        "Ваш броузер не поддерживает GeolocationAPI."
                    );
                }
            },
            /**
             * Обработчик успешного завершения геолокации.
             * @function
             * @private
             * @name GeolocationButton._onGeolocationSuccess
             * @param {Object} position Объект, описывающий текущее местоположение.
             */
            _onGeolocationSuccess: function (position) {
                this.handleGeolocationResult(position);
                // Меняем иконку кнопки обратно
                this.toggleIconImage("wifi.svg");
            },
            /**
             * Обработчик ошибки геолокации.
             * @function
             * @name GeolocationButton._onGeolocationError
             * @param {Object} error Описание причины ошибки.
             */
            _onGeolocationError: function (error) {
                this.handleGeolocationError(
                    "Точное местоположение определить не удалось."
                );
                // Меняем иконку кнопки обратно.
                this.toggleIconImage("wifi.svg");

                if (console) {
                    console.warn(
                        "GeolocationError: " +
                            GeolocationButton.ERRORS[error.code - 1]
                    );
                }
            },
            /**
             * Обработка ошибки геолокации.
             * @function
             * @name GeolocationButton.handleGeolocationError
             * @param {Object|String} err Описание ошибки.
             */
            handleGeolocationError: function (err) {
                this.hint.show(err.toString()).hide(2000);
            },
            /**
             * Меняет иконку кнопки.
             * @function
             * @name GeolocationButton.toggleIconImage
             * @param {String} image Путь до изображения.
             */
            toggleIconImage: function (image) {
                this.data.set("image", baseIconsURL + image);
            },
            /**
             * Обработка результата геолокации.
             * @function
             * @name GeolocationButton.handleGeolocationResult
             * @param {Object} position Результат геолокации.
             */
            handleGeolocationResult: function (position) {
                var location = [
                        position.coords.latitude,
                        position.coords.longitude,
                    ],
                    accuracy = position.coords.accuracy,
                    map = this.getMap(),
                    options = this.geoLocationOptions,
                    placemark = this._placemark,
                    circle = this._circle;

                // Смена центра карты (если нужно)
                if (!options.noCentering) {
                    map.setCenter(location, 15);
                }

                // Установка метки по координатам местоположения (если нужно).
                if (!options.noPlacemark) {
                    // Удаляем старую метку.
                    if (placemark) {
                        map.geoObjects.remove(placemark);
                    }
                    this._placemark = placemark = new ymaps.Placemark(
                        location,
                        {},
                        { preset: "geolocation#icon" }
                    );
                    map.geoObjects.add(placemark);
                    // Показываем адрес местоположения в хинте метки.
                    this.getLocationInfo(placemark);
                }

                // Показываем точность определения местоположения (если нужно).
                if (!options.noAccuracy) {
                    // Удаляем старую точность.
                    if (circle) {
                        map.geoObjects.remove(circle);
                    }
                    this._circle = circle = new ymaps.Circle(
                        [location, accuracy],
                        {},
                        { opacity: 0.5 }
                    );
                    map.geoObjects.add(circle);
                }
            },
            /**
             * Получение адреса по координатам метки.
             * @function
             * @name GeolocationButton.getLocationInfo
             * @param {ymaps.Placemark} point Метка для которой ищем адрес.
             */
            getLocationInfo: function (point) {
                ymaps
                    .geocode(point.geometry.getCoordinates())
                    .then(function (res) {
                        var result = res.geoObjects.get(0);

                        if (result) {
                            point.properties.set(
                                "hintContent",
                                result.properties.get("name")
                            );
                        }
                    });
            },
        });

        /**
         * Человекопонятное описание кодов ошибок.
         * @static
         */
        GeolocationButton.ERRORS = [
            "permission denied",
            "position unavailable",
            "timeout",
        ];

        /**
         * Класс хинта кнопки геолокации, будем использовать для отображения ошибок.
         * @class
         * @name GeolocationButtonHint
         * @param {GeolocationButton} btn Экземпляр класса кнопки.
         */
        function GeolocationButtonHint(btn) {
            var map = btn.getMap(),
                // Позиция кнопки.
                position = btn.options.get("position");

            this._map = map;
            // Отодвинем от кнопки на 35px.
            this._position = [position.left + 35, position.top];
        }

        /**
         * Отображает хинт справа от кнопки.
         * @function
         * @name GeolocationButtonHint.show
         * @param {String} text
         * @returns {GeolocationButtonHint}
         */
        GeolocationButtonHint.prototype.show = function (text) {
            var map = this._map,
                globalPixels = map.converter.pageToGlobal(this._position),
                position = map.options
                    .get("projection")
                    .fromGlobalPixels(globalPixels, map.getZoom());

            this._hint = map.hint.show(position, text);

            return this;
        };
        /**
         * Прячет хинт с нужной задержкой.
         * @function
         * @name GeolocationButtonHint.hide
         * @param {Number} timeout Задержка в миллисекундах.
         * @returns {GeolocationButtonHint}
         */
        GeolocationButtonHint.prototype.hide = function (timeout) {
            var hint = this._hint;

            if (hint) {
                setTimeout(function () {
                    hint.hide();
                }, timeout);
            }

            return this;
        };

        var myMap = new ymaps.Map("map", {
                center: [55.755768, 37.617671],
                zoom: 10,
                behaviors: ["default", "scrollZoom"],
            }),
            myButton = new GeolocationButton({
                data: {
                    image: baseIconsURL + "wifi.svg",
                    title: "Определить местоположение",
                },
                options: {
                    // Режим получения наиболее точных данных.
                    enableHighAccuracy: true,
                },
            });

        myMap.controls.add(myButton, { top: 5, left: 5 });
    }

    ymaps.ready(init);
    ```

{% endlist %}
