Разработка серверной части
LoadingObjectManager производит все операции с объектами на стороне клиента. К таким операциям относятся: создание оверлеев, их отрисовка, кластеризация объектов и т. д. Однако информация об объектах хранится на сервере, и менеджер будет обращаться к нему для получения нужных данных.
Для работы с LoadingObjectManager
разработчику необходимо самостоятельно спроектировать архитектуру серверной части:
Размещение данных на сервере
Для хранения информации о географических объектах целесообразно использовать пространственные базы данных. Для многих СУБД существуют расширения, позволяющие организовывать доступ к пространственным объектам. Например, для MySQL — это SPATIAL, для PostgreSQL — PostGIS. Также пространственные индексы поддерживают и другие стандартные базы данных, например, Oracle, MongoDB.
Структура размещения данных зависит от выбранного режима загрузки данных. Ниже рассмотрены запросы, которые менеджер будет отправлять на сервер при разных режимах, а также приведены рекомендации по организации структуры хранения данных.
Обработка запросов менеджера
В зависимости от того, каким способом менеджер будет запрашивать данные (для всей видимой области сразу или по тайлам, по географическим координатам или по номерам тайлов), на сервер будут отправляться GET-запросы с разными параметрами. Ниже рассмотрены форматы запросов, которые менеджер будет отправлять на сервер при разных способах загрузки данных:
1. Данные запрашиваются сразу для всей видимой области по ее географическим координатам
Пример запроса, который отправит менеджер:
GET https://my-server.ru/?bbox=55.3589,36.2109,56.1519,39.0234&callback=myCallback_55_3589_36_2109_56_1519_39_0234
где:
bbox
– координаты левого нижнего и правого верхнего углов области;callback
– имя функции, в которую сервер должен обернуть ответ. Подробнее см. в разделе Формат ответа сервера.
Чтобы менеджер запрашивал данные таким способом, необходимо при создании менеджера:
- в параметре urlTemplate использовать подстановку
%b
.
Например:
// Создадим менеджер и передадим ему шаблон URL данных.
// В шаблоне будем использовать подстановку %b, которая
// заменяется на массив географических координат области (подробнее о подстановках).
var loadingObjectManager = new ymaps.LoadingObjectManager('https://server.ru/?bbox=%b', {
// Шаблон названия callback-функции, в которую сервер должен обернуть ответ.
paddingTepmlate: "myCallback_%b"
});
Рекомендации по размещению данных на сервере
При таком формате запроса рекомендуется размещать данные в пространственной базе данных. В качестве пространственного индекса можно установить поле, содержащее широту и долготу углов области. По такому индексу легко получить выборку объектов, входящих в нужную область.
2. Данные запрашиваются сразу для всей видимой области по номерам угловых тайлов
Пример запроса, который отправит менеджер за данными:
GET https://server.ru/?tileBounds=615,319,622,322&z=10&callback=myCallback_615_319_622_322_10
где:
tileBounds
– номера левого верхнего и правого нижнего тайлов;z
— коэффициент масштабирования;callback
– имя функции, в которую сервер должен обернуть ответ. Подробнее см. в разделе Формат ответа сервера.
Чтобы менеджер запрашивал данные таким способом, необходимо:
- в параметре urlTemplate использовать любые из подстановок:
%t
,%c
,%x
,%y
,%z
(подробнее о подстановках).
Например:
// Создадим менеджер и передадим шаблон URL с подстановками %t и %z (подробнее о подстановках).
// %t – заменяется на последовательность номеров угловых тайлов области. Номера перечисляются через запятую.
// %z – заменяется на уровень масштабирования.
var loadingObjectManager = new ymaps.LoadingObjectManager('https://server.ru/?tileBounds=%t&z=%z', {
// Шаблон названия callback-функции, в которую сервер должен обернуть ответ.
paddingTemplate: 'myCallback_%t_%z'
});
Рекомендации по размещению данных на сервере
При таком формате запроса можно настроить в базе составной индекс с ключами x, y и z, где x – номер тайла по X, y – номер тайла по Y и z – коэффициент масштабирования (подробнее о составных индексах). Тогда можно получить выборку из базы, опираясь на сформированный ключ, аналогично работе с географическими координатами.
Рекомендации по кэшированию ответа
В зависимости от действий пользователя на карте размеры запрашиваемых областей будут разными. По этой причине оптимальнее кэшировать выборку из базы потайлово. Поскольку серверу передается параметр tileBounds, содержащий номера первого и последнего тайлов области, нетрудно определить номера остальных тайлов, входящих в эту область. Тогда при запросе данных для некоторой тайловой области нужно «склеить» ответ из данных по каждому тайлу в составе области и отправить ответ на клиент.
Существует множество инструментов, позволяющих реализовать кэширование данных на сервере (например memcached или redis). В качестве ключа кэширования можно использовать параметры x
, y
, z
.
3. Данные запрашиваются по тайлам по географическим координатам
Примеры запросов, которые менеджер будет отправлять на сервер:
GET https://server.ru/?bbox=55.5587,36.2109,55.7574,36.5625&callback=myCallback_55_5587_36_2109_55_7574_36_5625
GET https://server.ru/?bbox=55.7574,36.2109,55.9552,36.5625&callback=myCallback_55_7574_36_2109_55_9552_36_5625
GET https://server.ru/?bbox=55.3589,36.2109,55.5587,36.5625&callback=myCallback_55_3589_36_2109_55_5587_36_5625
...
где:
bbox
– координаты левого нижнего и правого верхнего углов тайла;callback
– имя функции, в которую сервер должен обернуть ответ. Подробнее см. в разделе Формат ответа сервера.
Чтобы менеджер запрашивал данные таким способом, необходимо:
- в параметре urlTemplate использовать подстановку
%b
(подробнее о подстановках); - выставить параметр splitRequests в
true
.
Например:
// Создадим менеджер, который будет запрашивать данные отдельно по тайлам.
var loadingObjectManager = new ymaps.LoadingObjectManager('https://server.ru/?bbox=%b', {
splitRequests: true,
paddingTemplate: myCallback_%b
});
Рекомендации по размещению данных на сервере
В качестве пространственного индекса базы можно установить поле, содержащее географические координаты углов тайла.
Рекомендации по кэшированию
Карта состоит из конечного числа тайлов, и углы каждого тайла на определенном масштабе привязаны всегда к одним и тем же географическим координатам. Поэтому можно кэшировать данные отдельно для каждого тайла, указав в качестве ключа кэширования географические координаты левого нижнего и правого верхнего углов тайла.
4. Данные запрашиваются по тайлам по номерам этих тайлов
Пример запросов, которые будет формировать менеджер:
GET https://server.ru/?x=622&y=319&z=10&callback=myCallback_x_622_y_319_z_10
GET https://server.ru/?x=622&y=321&z=10&callback=myCallback_x_622_y_321_z_10
GET https://server.ru/?x=622&y=322&z=10&callback=myCallback_x_622_y_322_z_10
...
x
– номера тайла по оси X;y
– номер тайла по оси Y;z
– коэффициент масштабирования;callback
– имя функции, в которую сервер должен обернуть ответ. Подробнее см. в разделе Формат ответа сервера.
Чтобы менеджер запрашивал данные таким способом, необходимо:
- в параметре urlTemplate использовать любые из подстановок:
%t
,%c
,%x
,%y
,%z
(подробнее о подстановках); - выставить параметр splitRequests в
true
.
Например:
// Создадим менеджер, который будет запрашивать данные отдельно по тайлам.
var loadingObjectManager = new ymaps.LoadingObjectManager('http://server.ru/?%c', {
splitRequests: true,
// Такой шаблон доступен только при splitRequests=true.
paddingTemplate: myCallback_%c
});
Примечание
Обратите внимание, подстановка '%c' доступна только при splitRequests=true
.
Рекомендации по размещению данных на сервере
При таком формате запроса можно настроить в базе составной индекс с ключами x, y и z (подробнее о составных индексах).
Рекомендации по кэшированию
Когда клиент запрашивает данные потайлово, он формирует конечное число запросов к серверу (карта состоит из конечного числа тайлов). Чтобы при поступлении нового запроса каждый раз не обращаться к базе данных, для каждого запроса можно кэшировать ответ. В качестве ключей кэширования можно установить параметры запроса: x
, y
, z
. Для реализации серверного кэширования можно использовать memcached или, например, redis.
Формат ответа сервера
При получении запроса со стороны клиента на сервере необходимо:
- сформировать JSON-описание объектов для запрашиваемой области;
- обернуть JSON-описание в callback-функцию;
- отправить ответ клиенту.
Структура JSON-описания объектов
Описание объектов должно представлять собой GeoJSON-подобную структуру:
{
"type": "FeatureCollection",
"features": [
...
]
}
Поле features
– это массив объектов (меток, кругов, линий и пр.), которые входят в запрашиваемую область. Каждый объект описывается следующими полями:
Поле |
Тип |
Описание |
|
String |
Поле должно всегда иметь значение "Feature". |
|
Number |
Уникальный идентификатор объекта. Разработчик должен сформировать идентификаторы объектов самостоятельно.
|
|
Object |
Геометрия объекта. Содержит поля:
Примеры задания геометрииДля метки:
Для линии:
Для многоугольника:
Для круга:
Для кластера:
|
|
Object |
Свойства объекта (например, содержимое балуна или метки). Список доступных свойств описан в классе GeoObject. Кроме того, в свойствах могут быть указаны произвольные поля. Пример:
|
|
Object |
Опции объекта (например, стиль метки или цвет линии). Список доступных опций описан в классе GeoObject.
|
* Обязательное поле.
Пример JSON-описания объектов
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 0,
"geometry": {
"type": "Point",
"coordinates": [55.831903, 37.411961]
},
"properties": {
"balloonContent": "Содержимое балуна",
"clusterCaption": "Метка 1",
"hintContent": "Текст подсказки"
}
},
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "Point",
"coordinates": [55.763338, 37.565466]
},
"properties": {
"balloonContent": "Содержимое балуна",
"clusterCaption": "Метка 2",
"hintContent": "Текст подсказки"
}
}
]
}
Внимание
Идентификатор однозначно определяет каждый объект менеджера. По идентификатору можно получить доступ к нужному объекту и, например, изменить его свойства или опции. Идентификаторы объектов являются обязательным полем, и разработчик должен сформировать их самостоятельно.
Оборачивание JSON-описания в callback
Менеджер и сервер обмениваются данными в формате JSONP.
Это означает, что сервер должен возвращать менеджеру JSON-описание, обернутое в
callback-функцию:
callback_function({
"type": "FeatureCollection",
"features": [
...
]
})
Имя функции, в которую сервер должен обернуть ответ, менеджер будет формировать
автоматически и передавать в запросе в GET-параметре callback
:
/?callback=id_436554526&...
При создании менеджера можно задать шаблон, на основе которого менеджер будет формировать
имена callback-функций. Для этого предназначена опция paddingTemplate:
// Создание менеджера.
var loadingObjectManager = new ymaps.LoadingObjectManager('https://server.ru/tile/?%c', {
// Укажем шаблон для именования callback-функций.
paddingTemplate: 'myCallback_%c',
splitRequests: true
});
Тогда для тайла с номером [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-функцию и сохранять это описание в статическом файле.
Обязательное поле.