Работа с картой

Как разместить несколько карт на одной странице

На одной странице можно разместить неограниченное количество экземпляров карт. Для того чтобы добавить на страницу более одной карты, выполните следующие шаги:

  1. Cоздайте html-контейнер для каждого экземпляра карты.
    Примечание. Для того, чтобы затем обращаться к контейнерам по id, контейнеры должны иметь уникальные идентификаторы.

    Например, для размещения на одной странице карт Москвы и Санкт-Петербурга, создайте два контейнера с уникальными id:

    <p>Москва</p>
    <div id="ymaps-msc" style="width:500px;height:500px"></div>
    
    <p>Санкт-Петербург</p>
    <div id="ymaps-spb" style="width:500px;height:500px"></div>
  2. Создайте объект YMaps.Map для каждого экземпляра карты и присвойте каждый объект переменной с уникальным именем.
    Примечание. Имена переменных, также как и id контейнеров, в которых размещаются карты, должны быть уникальными.

    Например, присвойте переменной mapMsc объект карты Москвы, а mapSpb — Санкт-Петербурга:

    // Создает объект карты Москвы
    var mapMsc = new YMaps.Map(YMaps.jQuery("#ymaps-msc")[0]);
    
    // Создает объект карты Санкт-Петербурга
    var mapSpb = new YMaps.Map(YMaps.jQuery("#ymaps-spb")[0]);
  3. Задайте начальные параметры отображения для каждой созданной карты.

    Например, для карты Москвы установите центр на Красной площади, а для Санкт-Петербурга — на Дворцовой. Уровень масштаба задайте равным 10:

    // Инициализирует карту Москвы
    mapMsc.setCenter(new YMaps.GeoPoint(37.609,55.753), 10);
    
    // Инициализирует карту Санкт-Петербурга
    mapSpb.setCenter(new YMaps.GeoPoint(30.313,59.938), 10);

Открыть пример в новом окне

Как показать карту по требованию

Если требуется показать карту, когда пользователь щелкнет по ссылке (или другому DOM-объекту), применяйте метод загрузки API по требованию. Начальные параметры отображения карты выставьте после того, как контейнер карты станет видимым.

Выполните следующие шаги:

  1. Добавьте на HTML-страницу ссылку, по которой будет вызываться функция инициализации и показа карты, например, showMap():
    <a href="#" onclick="showMap();return false;">Показать карту</a>
    <div id="YMapsID" style="width:500px;height:500px;display:none"></div>
  2. Реализуйте внутри функции загрузку API по требованию, инициализацию и показ карты, например:
    function showMap () {
        YMaps.load(function() {
            var mapContainer = YMaps.jQuery("#YMapsID"),
                map = new YMaps.Map(mapContainer[0]);
    
            mapContainer.css("display", "");
            map.setCenter(new YMaps.GeoPoint(37.64, 55.76));
        });
    }

Открыть пример в новом окне

Как показать карту из скрытого контейнера

Если невозможно использовать метод отображения карты по требованию, задайте начальные параметры отображения карты в скрытом HTML-элементе. Для этого выполните следующие шаги:

  1. Добавьте на страницу элемент управления (например, ссылку, кнопку, изображение), при щелчке по которому будет отображаться элемент-контейнер для карты и сама карта.

    Например, создайте ссылку "Показать/Скрыть карту", при щелчке на которой будет отображаться/скрываться карта Москвы:

    <a id="change-map-visibility" href="#">Показать/Скрыть карту</a>
    <div id="YMapsID" style="width:600px;height:400px;display:none"></div>
  2. Создайте экземпляр карты и задайте начальные параметры ее отображения.

    Например, создайте экземпляр карты Москвы с центром на Красной площади:

    var container = YMaps.jQuery("#YMapsID"),
        map = new YMaps.Map(container[0]);
    map.setCenter(new YMaps.GeoPoint(37.64, 55.76), 10);
  3. Создайте обработчик события щелчка мыши по ссылке, который будет скрывать/показывать контейнер карты. Прикрепите обработчик к созданному ранее элементу управления.
    // Показывает/скрывает контейнер карты по щелчку по ссылке "Показать/Скрыть карту"
    YMaps.jQuery("#change-map-visibility").bind('click', function () {
        container.css('display', (container.css('display') == 'none') ? '' : 'none');
        map.redraw(); // Перерисовывает карту
        return false;
    });
    Примечание. Перерисовка карты с помощью метода redraw() требуется для того, чтобы избежать возможной "потери" тайлов.

Открыть пример в новом окне

Как использовать плавное перемещение карты

Для плавного перемещения центра карты в заданную географическую точку используйте метод карты panTo().

Если расстояние между текущим центром карты и заданной точкой превосходит размер карты более чем в три раза, метод panTo() работает как setCenter(). Если установлена опция flying, то перемещение карты имитирует перелет из одной точки в другую.

Пример ниже демонстрирует, как использовать метод panTo() для просмотра нескольких городов.

  1. Создайте контейнеры для карты и списка городов.

    Список городов формируется динамически с помощью JavaScript.

    <ul id="mapMenu"></ul>
    <div id="YMapsID" style="width:600px;height:400px"></div>
  2. Создайте список городов с привязкой к географическим координатами. По щелчку на элементе списка карта будет плавно перемещаться в центр выбранного города.

    Список городов и их координат представлен в виде JavaScript-объекта:

    var destinations = {
            'Москва' : new YMaps.GeoPoint(37.609218,55.753559),
            'Санкт-Петербург' : new YMaps.GeoPoint(30.313497,59.938531),
            'Екатеринбург' : new YMaps.GeoPoint(60.617435,56.829748),
            'Одесса' : new YMaps.GeoPoint(30.7058,46.466444)
        };
    
    // Устанавливает центр карты на первом городе из списка
    map.setCenter(destinations['Москва'], 10);
  3. Создает список городов и записывает его в контейнер с идентификатором mapMenu

    Список ссылок формируется исходя из объекта destinations. К каждой ссылке прикрепляется обработчик щелчка мыши, в котором с помощью метода panTo() производится изменение координат центра карты.

    var menuContainer = YMaps.jQuery('#mapMenu');
    
    // Создает список городов
    for (var item in destinations) {
        // Использует замыкание, чтобы работать с конкретным свойством объекта
        (function (title, geoPoint) {
            // Создает ссылку, обернутую в тег <p> для лучшей читаемости
            YMaps.jQuery("<li><a href=\"#\">" + item + "</'a></li>")
                .find('a')
                    // По щелчку на ссылке создает обработчик
                    .bind('click', function () {
                        
                        // Подчеркивает все ссылки
                        menuContainer.find('a').css('text-decoration', 'underline');
                        
                        // Кроме той, что была выбрана пользователем
                        YMaps.jQuery(this).css('text-decoration', 'none');
                        
                        // Перемещает карту
                        map.panTo(geoPoint, {flying: 1});
                        return false;
                    })
                    .end()
    
                // Записывает созданный элемент списка в список
                .appendTo(menuContainer);
        })(item, destinations[item])
    }

Открыть пример в новом окне

Как создать ссылку на фрагмент карты

В примере показано как сформировать HTML-ссылку на фрагмент карты. Подобные ссылки можно использовать, например, для организации обмена ссылками на объекты карты между пользователями картографического приложения.

Пример добавляет к URL страницы в адресной строке браузера параметры, задающие текущее положение центра карты, ее тип и область показа. Полученный адрес можно отправить другим пользователям для того, чтобы они смогли увидеть тот же самый фрагмент карты.

Для изменения HTTP-адреса страницы в браузере средствами JavaScript используется глобальный объект браузера document.location, который содержит информацию об адресе текущей загруженной страницы (свойство document.location.href).

Адрес текущего фрагмента карты сохраняется в атрибуте href HTML-элемента <a/> («ссылка»). Код для создания ссылки выглядит следующим образом:

<a id="YMapsLink" href="#">Получить ссылку на карту</a>

Чтобы сформировать адрес фрагмента карты в ссылке потребуется сохранять кординаты центра карты, линейный размер видимой области и тип карты.

  1. Создайте класс для перевода типа карты в строковое представление и обратно (TypeConverter).
    Для перевода остальных параметров используйте стандартные методы toString() и fromString()
    // Преобразует тип карты в строковое представление и обратно
    // Если тип карты не был определен, то по умолчанию возвращается тип карты YMaps.MapType.MAP (или имя "map")
    function TypeConverter () {
            // Типы карты
        var types = [YMaps.MapType.MAP, YMaps.MapType.SATELLITE, YMaps.MapType.HYBRID],
     
            // Имена карт
            names = ["map", "sat", "hyb"];
     
        // Возвращает имя карты по ее типу
        this.typeToName = function (type) {
            return names[valid(types.indexOf(type))];
        };
    
        // Возвращает тип карты по имени
        this.nameToType = function (name) {
            return types[valid(names.indexOf(name))];
        };
     
        // Проверяет правильность полученного индекса
        function valid (index) {
            return (index == -1) ? 0 : index;
        }
    };
    .
  2. Создайте и подключите обработчик событий карты BoundsChange и TypeChange, в которых будет формироваться адрес ссылки на фрагмент карты.
    // Динамически формирует URL ссылки
    YMaps.Events.observe(map, [map.Events.BoundsChange, map.Events.TypeChange],  function () {
        YMaps.jQuery("#YMapsLink")
            .attr("href", "?l=" + typeConverter.typeToName(map.getType()) +
                          "&ll=" + map.getCenter().toString() +
                          "&spn=" + map.getBounds().getSpan().toString(6)
            );
    });

    Итоговая ссылка будет иметь следующий вид:

    ?l=hyb&ll=37.664725,55.842762&spn=0.823971,0.309084
  3. Создайте вспомогательную функцию, которая будет по имени параметра возвращать его значение.
    // Возвращает значение параметра URL по его имени
    function getParam (name, location) {
        location = location || window.location.hash;
        var res = location.match(new RegExp('[#&]' + name + '=([^&]*)', 'i'));
        return (res && res[1] ? res[1] : '');
    }
  4. Создайте объект, который будет содержать все параметры, обнаруженные в сформированном URL.
    // Объект, содержащий URL-параметры
    var params = {
          ll : getParam("ll"),    // Центр карты
          spn : getParam("spn"),  // Линейный размер области
          t : getParam("t")       // Тип карты
        };
  5. Отобразите заданную область на карте.

    Для этого передайте в метод карты setBounds() объект класса YMaps.GeoBounds. С помощью метода fromCenterAndSpan() создайте область по значениям центра карты и линейному размеру области в градусах. Объекты классов YMaps.GeoPoint и YMaps.Size создайте из строкового представления с помощью метода fromString():

    // Область карты, которую необходимо показать
    var bounds = YMaps.GeoBounds.fromCenterAndSpan(
        YMaps.GeoPoint.fromString(params.ll),   // Центр карты
        YMaps.Size.fromString(params.spn)       // Линейный размер области в градусах
    );
  6. Переведите тип карты из строкового вида в объект с помощью вспомогательного класса TypeConverter:
    // Устанавливает требуемый тип карты
    map.setType(typeConverter.nameToType(params.l));

Открыть пример в новом окне

Кроме описанного выше способа параметры карты можно сохранить в ссылке-якоре. Преимущество этого способа в том, что такие ссылки можно формировать и отображать динамически без перезагрузки страницы.

Открыть пример в новом окне