Объекты на карте

Как создать меню с помощью элемента управления

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

Чтобы создать "Путеводитель по офисам" выполните следующие шаги:

  1. Подготовьте объекты, которые будут отображаться на карте при выборе элемента управления и добавьте их на карту.
    // Создает группу меток, обозначающих положение офисов Яндекса на карте
    var group = new YMaps.GeoObjectCollection();
    group.add(createPlacemark(new YMaps.GeoPoint(37.678514, 55.758255), 'Москва (Самокатная)', 'Москва, ул. Самокатная, дом 1, строение 21'));
    // ...
    // остальные метки опущены для краткости (см. исходный код примера)
    
    // Добавляет группу меток на карту
    map.addOverlay(group);

    Функция createPlacemark отвечает за создание отдельной метки.

    // Создает метку
    function createPlacemark (geoPoint, name, description) {
        var placemark = new YMaps.Placemark(geoPoint);
        placemark.name = name;
        placemark.description = description;
    
        return placemark;
    }
  2. Создайте заготовку для будущего элемента согласно интерфейсу YMaps.IControl.
    // Управляющий элемент "Путеводитель по офисам"
    function OfficeNavigator (offices) {
    
        // Обработчик добавления элемента на карту
        this.onAddToMap = function (map, position) {
            // Действия при добавлении элемента на карту
        }
    
        // Обработчик удаления элемента с карты
        this.onRemoveFromMap = function () {
            // Действия при удалении элемента с карты
        };
    }
  3. Определите обработчики для двух методов класса YMaps.IControl: onAddToMap(), вызываемого при добавлении элемента управления на карту и onRemoveFromMap(), вызываемого при удалении элемента.

    В метод onAddToMap() передается указатель на карту и расположение элемента управления на карте (в примере - верхний правый угол). Для указания расположения элементов управления используйте класс YMaps.ControlPosition:

    // Действия при добавлении элемента на карту
    this.onAddToMap = function (map, position) {
            this.container = YMaps.jQuery("<ul></ul>")
            this.map = map;
            this.position = position || new YMaps.ControlPosition(YMaps.ControlPosition.TOP_RIGHT, new YMaps.Size(10, 10));
    
            // CSS-свойства, определяющие внешний вид элемента
            this.container.css({
                position: "absolute",
                zIndex: YMaps.ZIndex.CONTROL,
                background: '#fff',
                listStyle: 'none',
                padding: '10px',
                margin: 0
            });
            
            // Формирует список офисов
            this._generateList();
            
            // Располагает элемент управления в верхнем правом углу карты
            this.position.apply(this.container);
            
            // Добавляет элемент управления на карту
            this.container.appendTo(this.map.getContainer());
    }

    При вызове метода onRemoveFromMap() необходимо удалить созданный элемент управления с карты и обнулить значения созданных полей:

    // Обработчик удаления элемента управления с карты
    this.onRemoveFromMap = function () {
        if (this.container.parent()) {
            this.container.remove();
            this.container = null;
        }
        this.map = null;
    };
  4. Реализуйте внутреннюю логику работы элемента управления и создайте обработчики для всех связанных с ним событий.

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

    // Формирует выпадающий список офисов
    this._generateList = function () {
        var _this = this;
        
        // Вызывает функцию-обработчик для каждого объекта
        offices.forEach(function (obj) {
            // Создает ссылку на объект
            var li = YMaps.jQuery("<li><a href=\"#\">" + obj.name + "</li>"),
                a = li.find("a"); 
            
            // Создает обработчик щелчка мыши по ссылке
            li.bind("click", function () {
                _this.map.panTo(obj.getGeoPoint(), {
                    flying: 1,
                    callback: function () {
                        obj.openBalloon();
                    }
                });
                return false;
            });
            
            // Создает слушатели событий открытия и закрытия балуна объекта
            YMaps.Events.observe(obj, obj.Events.BalloonOpen, function () {
                a.css("text-decoration", "none");
            });
            
            YMaps.Events.observe(obj, obj.Events.BalloonClose, function () {
                a.css("text-decoration", "");
            });
            
            // Добавляет ссылку на объект в общий список
            li.appendTo(_this.container);
        });
    };
  5. Создайте и добавьте элемент управления на карту.
    // Создает элемент управления "Путеводитель по офисам"
    map.addControl(new OfficeNavigator(group));

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

Как изменить отображение ломаной

Пример ниже создает ломаную, отрезки которой имеют направление (ломаную-вектор). Направление отображается стрелками, что удобно при отображении маршрутов.

Класс ломаной-вектора наследуется от стандартного класса ломаной YMaps.Polyline и переопределяет только необходимые методы.

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

Острие стрелки располагается в центре каждого отрезка ломаной, а ее основание отстоит от центра отрезка на фиксированное количество пикселов (в зависимости от длины ломаной).

Чтобы создать ломаную-вектор, выполните следующие действия:

  1. Реализуйте функцию, производящую наследование без исполнения родительского конструктора.

    Например, с помощью функции extend():

    function extend (child, parent) {
        var c = function () {};
        c.prototype = parent.prototype;
        c.prototype.constructor = parent;
        return child.prototype = new c();
    };
  2. Переопределите следующие методы интерфейса YMaps.IOverlay: onAddToMap(), onRemoveFromMap() и onMapUpdate().
    Примечание. Чтобы сохранить функциональность ломаной, в переопределенных методах необходимо вызывать методы родительского класса.
    function PolylineWithArrows (points, options) {
        // Вызывает родительский конструктор
        YMaps.Polyline.call(this, points, options);
    
        // Вызывается при добавлении объекта на карту
        this.onAddToMap = function (map, mapContainer) {
            YMaps.Polyline.prototype.onAddToMap.call(this, map);
        }
    
        // Вызывается при удалении объекта с карты
        this.onRemoveFromMap = function () {
            YMaps.Polyline.prototype.onRemoveFromMap.call(this);
        }
    
        // Вызывается при обновлении карты
        this.onMapUpdate = function () {
            YMaps.Polyline.prototype.onMapUpdate.call(this);
        }
    }
    extend(PolylineWithArrows, YMaps.Polyline);
  3. Создайте группу для хранения стрелок (многоугольников) и добавьте обработчик события перерисовки ломаной.

    Все стрелки хранятся в группе. Для перерисовки стрелок после каждого обновления линии обрабатывается событие ломаной PositionChange. Указатель на это событие хранится в переменной listener.

    function PolylineWithArrows (points, options) {
        // Вызов родительского конструктора
        YMaps.Polyline.call(this, points, options);
    
        // Группа, в которой содержатся стрелки
        var arrows = new YMaps.GeoObjectCollection(this.getComputedStyle()),
        
            // Обработчик событий ломаной
            listener;
        ...
  4. Добавьте действия, необходимые для отрисовки стрелок при добавлении, обновлении или удалении ломаной с карты.

    При добавлении на карту создается обработчик события PositionChange, затем группа стрелок добавляется на карту и стрелки отрисовываются. При обновлении карты обновляются и стрелки. При удалении ломаной с карты удаляются и стрелки, и обработчик события PositionChange.

    ...
    // Вызывается при добавлении объекта на карту
    this.onAddToMap = function (map, mapContainer) {
        YMaps.Polyline.prototype.onAddToMap.call(this, map);
        
        // Перерисовывает стрелки при изменении позиции вершины ломаной
        listener = YMaps.Events.observe(this, this.Events.PositionChange, function () {
            this.updateArrows();
        }, this);
        
        // Добавляет группу стрелок на карту
        map.addOverlay(arrows);
    
        // Обновляет стрелки
        this.updateArrows();
    }
    
    // Вызывается при удалении ломаной с карты
    this.onRemoveFromMap = function () {
        // Удаляет стрелки с карты
        this.getMap().removeOverlay(arrows);
    
        // Удаляет ломаную с карты
        YMaps.Polyline.prototype.onRemoveFromMap.call(this);
    
        // Удаляет обработчик событий
        listener.cleanup();
    }
    
    // Вызывается при обновлении карты
    this.onMapUpdate = function () {
        // Обновляет ломаную на карте
        YMaps.Polyline.prototype.onMapUpdate.call(this);
    
        // Перерисовывает стрелки
        this.updateArrows();
    }
    ...

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

Управление группами объектов с помощью меню

Пример демонстрирует как создать элемент управления в виде меню, позволяющий добавлять и скрывать группы объектов с карты.

  1. Реализуйте две вспомогательные функции: для создания отдельной метки и группы меток.

    В функцию создания метки передаются координаты точки, к которой должна быть привязана метка, ее имя и описание:

    // Создает метку
    function createPlacemark (point, name, description) {
        var placemark = new YMaps.Placemark(point);
    
        placemark.name = name;
        placemark.description = description;
    
        return placemark
    }

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

    // Создает группу меток
    function createGroup (title, objects, style) {
        var group = new YMaps.GeoObjectCollection(style);
    
        group.title = title;
        group.add(objects);
        
        return group;
    };
  2. Создайте массив групп меток, на основе которого будет формироваться меню.
    // Создает группы меток
    var groups = [
        createGroup("Известные памятники", [
            createPlacemark(new YMaps.GeoPoint(30.563022,50.426472), "Монумент \"Родина-Мать\""),
            createPlacemark(new YMaps.GeoPoint(30.516489,50.45351), "Памятник \"Богдану Хмельницкому\""),
            createPlacemark(new YMaps.GeoPoint(30.529874,50.454433), "Арка Дружбы народов")
        ], "default#redPoint"),
        ...
    ];
  3. Реализуйте функцию addMenuItem, добавляющую отдельный пункт меню в список.
    // Добавляет отдельный пункт меню
    function addMenuItem (group, map, menuContainer) {
    
        // Показывает/скрывает группу меток на карте
        YMaps.jQuery("<a class=\"title\" href=\"#\">" + group.title + "</a>")
            .bind("click", function () {
                var link = YMaps.jQuery(this);
    
                // Если пункт меню активен, добавляет группу на карту,
                // иначе - удаляет с карты
                if (link.hasClass("active")) {
                    map.removeOverlay(group);
                } else {
                    map.addOverlay(group);
                }
    
                // Изменяет статус пункта меню (активен/не активен)
                link.toggleClass("active");
    
                return false;
            })
    
            // Добавляет новый пункт меню в список
            .appendTo(
                YMaps.jQuery("<li></li>").appendTo(menuContainer)
            )
    };
  4. Сформируйте меню.
    // Создает список групп
    for (var i = 0; i < groups.length; i++) {
        addMenuItem(groups[i], map, YMaps.jQuery("#menu"));
    }

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