Кластеризация в API Рамблер-Карт

в 11:20, , рубрики: Блог компании «Афиша» и «Рамблер», карты, Рамблер, рамблер-карты, метки: , ,

Продолжим знакомство с API «Рамблер-Карт», и на этот раз разберёмся с кластеризацией меток.

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

Кластеризация в API Рамблер Карт

Бороться с этой проблемой можно при помощи метода makeCluster, который объединяет метки в кластеры и оставляет на карте лишь кластерные метки, на которых указано количество объединённых точек.

Для примера рассмотрим метки московских аптек на карте до кластеризации и после.

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

var pharmacies = map.search("аптека", function(err, data, transport){
	//объявляем массив координат
	var coordArray = []; 
	//объявляем массив меток
	var markerArray = [];
        //и заполняем эти массивы
	var items = data.res[0].matches //массив результатов
	for ( var i=0, item; item=items[i]; i++){
		//извлекаем координаты из найденных результатов
                coordArray[i] = {
			lon: item.x,
			lat: item.y
		};
		//создаём метки
		markerArray[i] =  map.geometry.create("marker", {
			coord: coordArray[i]
			})
		}

Теперь дело за малым. Массив меток найденных аптек разбиваем на кластеры.

	//кластеризуем массив координат (если передать в качестве аргумента массив меток markerArray, получим в точности то же самое)
	var cl = map.makeCluster(coordArray, {
		area: "hull" // устанавливаем выделение площади кластера — в виде оболочки
		//и используем CSS, чтобы изменить внешний вид кластерных меток, заданный по умолчанию
		clusterMarker: { 
			"class": "",
			html: '<div style= "background:#9B2D30; border:1px solid #FFF; color:#FFF; padding:5px ">${quantity}</div>' 
		} 
	});
	console.log(cl);
});

Готово

Кластеризация в API Рамблер Карт
Исходный код примера доступен по ссылке: maps.rambler.ru/api/examples/TutorialClusterize.html

P.S.

Несколько слов об алгоритме кластеризации. Мы используем Quadtree: карта на самом маленьком масштабе (уровень масштабирования = 1) делится на 4 квадрата, каждому из которых присваивается номер: 0, 1, 2, 3. На следующем уровне масштабирования каждый из этих квадратов вновь делится на 4 квадрата. 16 новых квадратов нумеруются в соответствии с принадлежностью к большим: 00, 01, 02, 03, 10, 11, …, 44. Операция деления квадратов на 4 более мелких повторяется до некоего уровня масштабирования n, на котором, соответственно, уже будет 4^n квадратов, каждый из которых имеет уникальный n-значный номер.
Зная номер квадрата, можно определить, где он находится на карте и на каком масштабе. Метки, оказывающиеся на одном таком квадрате, образуют кластер.
Передавая в аргументах метода параметр maxZoom, мы указываем, на каком масштабе следует прекратить объединять метки в кластеры и начать показывать их раздельно (то есть каждую на своём месте). Фактически, maxZoom и есть выше упомянутое число n.

Автор: 127

Поделиться

* - обязательные к заполнению поля