Разработка серверной части

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

RemoteObjectManager работает по такому же принципу, что и LoadingObjectManager. Он загружает на сторону клиента необходимые данные по URL, которые указаны при создании менеджера. Основное различие заключается в том, что RemoteObjectManager не кластеризует данные на стороне клиента, но он может отображать результаты серверной кластеризации. Разработчику необходимо самостоятельно выбрать, какой алгоритм кластеризации использовать.

Как и LoadingObjectManager, RemoteObjectManager поддерживает два режима загрузки данных: по всей области видимости и по отдельным тайлам. Режим загрузки данных учитывается при разработке серверной части. В разделе Режимы загрузки данных можно ознакомиться с режимами загрузки, а также с некоторыми рекомендациями по размещению данных на сервере.

Формат описания объектов

JSON-описание объектов должно иметь следующую структуру:

{
  "type": "FeatureCollection",
  "features": [
      ... 
  ]
}

Поле features – это массив объектов (меток, кластеров, линий и др.), которые попадают в запрашиваемую область. Каждый объект описывается следующими полями:

Поле Тип Описание
type* String Тип объекта. Доступные значения:
  • "Feature" – одиночный объект (метка, линия, круг или многоугольник);
  • "Cluster" – объект-кластер.
id* Number Уникальный идентификатор объекта. Разработчик должен сформировать идентификаторы объектов самостоятельно. Обратите внимание, идентификаторы одиночных объектов и объектов-кластеров не должны пересекаться.
"id": 0
geometry* Object
Геометрия объекта. Содержит поля:
  • type – тип геометрии объекта. Доступные значения: «Point» (метка или кластер), «LineString» (линия), «Cicrle» (круг), «Polygon» (многоугольник).
  • coordinates – координаты объекта. Следует задавать в той последовательности, которая указана в параметре coordorder (если параметр не задан, используется последовательность «широта, долгота»).
  • radius (только для объекта с типом «Circle») – радиус круга в метрах.
Примеры задания геометрии

Для метки:

"geometry": {
    "type": "Point",
    "coordinates": [55.780898, 37.642889]
}

Для линии:

"geometry": {
    "type": "LineString",
    "coordinates": [
        [55.780898, 37.642889],
        [55.780898, 37.642889]
    ]
}

Для многоугольника:

"geometry": { 
    "type": "Polygon",
    "coordinates": [
        [55.801280971180454, 37.552642822265625],
        [55.81285742969946, 37.518310546875],
        [55.8367712028016, 37.540283203125],
        [55.801280971180454, 37.552642822265625]
    ]
}

Для круга:

"geometry": {
    "type": "Circle",
    "coordinates": [55.780898, 37.642889],
    "radius": 1000
}

Для объекта-кластера:

"geometry": {
    "type": "Point",
    "coordinates": [55.780898, 37.642889]
}
bbox* Number[][]

Географические координаты прямоугольной области, которая охватывает все объекты данного кластера. Указываются координаты левого нижнего и правого верхнего углов области.

"bbox": [[35, 46], [46, 57]]

Поле используется только в описании объекта-кластера (поле type принимает значение "Cluster").

number* Number

Количество объектов в кластере.

"number": 50
Используется только в описании объекта-кластера (поле type принимает значение "Cluster").
features Object

Массив объектов в составе кластера.

Используется только в описании объекта-кластера (поле type принимает значение "Cluster").

Если в описании кластера данное поле отсутствует или оно пустое, на карте будет отображен пустой значок кластера.

properties Object

Свойства объекта (например, содержимое балуна или метки). Список доступных свойств объектов описан в классе GeoObject. Кроме того, в свойствах могут быть указаны произвольные поля.

Пример:
"properties": {
    "balloonContent": "Текст балуна",
    "clusterCaption": "Метка 1",
    "hintContent": "Текст подсказки",
    "myDescription": "Произвольное описание"
}
options Object

Опции одиночного объекта (например, стиль метки или цвет линии). Список доступных опций описан в классе GeoObject.

"options": {
    "preset": "islands#yellowIcon"
}

* Обязательное поле.

Пример JSON-описания объектов
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": 0,
      "geometry": {
        "type": "Point",
        "coordinates": [55.831903, 37.411961]
      },
      "properties": {
        "balloonContent": "Магазин на углу",
        "data": {
          "organization": "shop",
          "open": "9am - 9pm"
        }
      }
    },
     {
      "type": "Cluster",
      "id": 1,
      "bbox": [[35, 46], [46, 57]],
      "number": 34,
      "features": [...],            
      "geometry": {                         
        "type": "Point",                         
        "coordinates": [40.5, 51]                     
      },                     
      "properties": {                
        "iconContent": "Кластер"                     
      }
    }
    {
      "type": "Feature",
      "id": 1,
      "geometry": {
        "type": "Point",
        "coordinates": [55.763338, 37.565466]
      },
      "properties": {
        "balloonContent": "Аптека",
         "data": {
          "organization": "pharmacy",
          "open": "8am - 10pm"
        }
      }
    }
  ]
}
Внимание. Идентификатор однозначно определяет каждый объект менеджера. По идентификатору можно получить доступ к нужному объекту и, например, изменить его свойства или опции. Идентификаторы объектов являются обязательным полем, и разработчик должен сформировать их самостоятельно.

Оборачивание JSON-описания в callback

Менеджер и сервер обмениваются данными в формате JSONP. Это означает, что сервер должен возвращать менеджеру JSON-описание, обернутое в callback-функцию:

callback_function({
  "type": "FeatureCollection",
  "features": [
    ... 
  ]
})

Имя функции, в которую сервер должен обернуть ответ, менеджер будет формировать автоматически и передавать в запросе в GET-параметре callback:

/?callback=id_436554526&...
При создании менеджера можно задать шаблон, на основе которого менеджер будет формировать имена callback-функций. Для этого конструктору менеджера нужно указать параметр paddingTemplate. Например:
// Создание менеджера. Укажем шаблон для именования callback-функций.
var remoteObjectManager = new ymaps.RemoteObjectManager('https://server.ru/tile/?%с', {
    paddingTemplate: 'myCallback_%c'
});

Тогда для тайла с номером [1,2] и z=5 менеджер отправит запрос по URL:

https://server.com/tile/?x=1&y=2&z=5&callback=myCallback_x_1_y_2_z_5

Ответ необходимо обернуть следующим образом:

myCallback_x_1_y_2_z_5({
  "type": "FeatureCollection",
  "features": [
    ... 
  ]
})

Использование параметра paddingTemplate упростит реализацию серверной части, так как для каждого запроса серверу будут заранее известны названия callback-функции. Для каждого тайла JSON-описание можно формировать сразу обернутым в заданную callback-функцию и сохранять в статическом файле.