Использование слоя активных областей

Пример ниже демонстрирует создание слоя активных областей, на котором с помощью пиктограмм (см. ниже) отмечены города-герои СССР.

Для этого потребуется создать :

  • набор прозрачных PNG-тайлов с нанесенными пиктограммами городов-героев;
  • набор соответствующих им JavaScript-файлов с описанием городов.

PNG и JavaScript-файлы будут именоваться по принципу tile-x-y-z.png и tile-x-y-z.js и храниться в папке heroes на сервере. Ключи запроса будут иметь вид "heroes-x-y-z".

Например, в тайл с номером (19, 11) на 5-ом уровне масштаба попадают Новороссийск, Керчь и Сталинград целиком, а так же часть пиктограммы Севастополя.

PNG-тайл:

JavaScript-файл:

YMaps.Hotspots.Loader.onLoad(
    "heroes-19-11-5",
    {
        "objects":
        [
            {
                "data": { "name":"Сталинград" },
                "base": new YMaps.GeoPoint(44.514208,48.708898),
                "geometry": [
                    [-10,-5,10,33]
                ]
            },
            {
                "data" : { "name": "Севастополь" },
                "base": new YMaps.GeoPoint(33.558616,44.585098),
                "geometry":[
                    [-10,-5,10,33]
                ]
            },
            {
                "data": { "name": "Новороссийск" },
                "base": new YMaps.GeoPoint(37.7767,44.720479),
                "geometry": [
                    [-10,-5,10,33]
                ]
            },
            {
                "data": { "name":"Керчь" },
                "base": new YMaps.GeoPoint(36.464342,45.30667),
                "geometry": [
                    [-10,-5,10,33]
                ]
            }
        ]
    }
);

При описании геометрии активной области, точкой отсчета (base) выбраны координаты города. Пиктограмма города смещена на 10 пикселей влево и 5 пикселей вверх относительно положения самого города на карте.

Для того, чтобы добавить подготовленные слои на карту:

  1. Создадим слой с картиночными тайлами и добавим его на карту:

    // Создает источник данных для тайлов
    var ds = new YMaps.TileDataSource('heroes/', true, false);
    // Задает правило формирования URL тайлов
    ds.getTileUrl = function (tileNumber, zoom) {
        return this.getTileUrlTemplate() + 'tile-' + tileNumber.getX() + '-' + tileNumber.getY() + '-' + zoom + '.png';
    }
    
    // Создает слой и добавляет его на карту
    var imageLayer = new YMaps.Layer(ds);
    map.addLayer(imageLayer);
    
  2. Создадим слой активных областей и добавим его на карту:

    // Создает источник объектов
    var os = new YMaps.Hotspots.ObjectSource('heroes/', 'heroes-');
    // Определяет правила формирования URL JavaScript-файла с данными
    os.getTileUrl = function (tileNumber, zoom) {
        return this.getTileUrlTemplate() + 'tile-' + tileNumber.getX() + '-' + tileNumber.getY() + '-' + zoom + '.js';
    };
    // Определяет правила формирования ключа ответа сервера
    os.getKey = function (tileNumber, zoom) {
        return this.getKeyTemplate() + tileNumber.getX() + '-' + tileNumber.getY() + '-' + zoom;
    };
    
    // Создает и добавляет слой на карту
    var hsLayer = new YMaps.Hotspots.Layer(os);
    map.addLayer(hsLayer);
    

    Теперь при наведении курсора на пиктограмму будет показываться всплывающая подсказка, а по щелчку мыши - открываться балун с названием города.

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

    1. Определим функцию наследования:

      var extend = function (child, parent) {
          var c = function () {};
          c.prototype = parent.prototype;
          c.prototype.constructor = parent;
          return child.prototype = new c;
      };
      
    2. Создадим пользовательский класс myObject, унаследованный от стандартного класса YMaps.Hotspots.Object:

      var myObject = function () {
          YMaps.Hotspots.Object.apply(this, arguments);
      };
      var ptp = extend(myObject, YMaps.Hotspots.Object);
      
    3. Переопределим в прототипе объекта myObject функцию requestBalloonData, которая отвечает за построение содержимого балуна и выбор точки открытия балуна:

      ptp.requestBalloonData = function (callback, e, shape) {
              // В балуне в отдельном фрейме показывает страницу Википедии с информацией о городе
          var data = '<iframe style="width: 850px; height: 550px;" src="http://ru.wikipedia.org/wiki/' + this.getData().name + '"/>',
              // Вычисляет точку, в которой необходимо открыть балун.
              // Третий аргумент функции - геометрическая фигура shape,
              // над которой произошло событие.
              // Добавляет к верхнему левому углу фигуры смещение (10, 5).
              pixelCenter = new YMaps.Point(shape.getMinX() + 10, shape.getMinY() + 5),
              // Переводит тайловые координаты в географические
              geoCenter = map.coordSystem.toCoordPoint(map.tileCoordinates.scale(pixelCenter, map.getZoom(), map.coordSystem.getMaxZoom()));
          
          // Отдает функции-обработчику содержимое балуна и точку его привязки
          callback(data, geoCenter);    
      }
      
  4. В источнике объектов переопределим фабричную функцию создания объектов-активных областей так, чтобы создавался не стандартный объект YMaps.Hotspots.Object, а пользовательский myObject:

    os.createObject = function (layer, data, shapes, priority) {
        return new myObject(layer, data, shapes, priority);
    };
    

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