Я могу придумать, как решить эту проблему так, как вы ее излагаете.Я могу подумать о двух других способах решения проблемы более высокого уровня: как сделать видимыми несколько маркеров, которые имеют очень близкие широтные / длинные местоположения.
«Вращающиеся» маркеры
Допустим, вы начинаете со списка данных маркера: значения широты / долготы и некоторых других данных (здесь text
).Некоторые из значений lat / long одинаковы или достаточно близки, что не имеет значения.
markerLatLngs = [
{lat: 49.010, lng: -133.00, text: "123 Main St #101"},
{lat: 49.010, lng: -133.00, text: "123 Main St #105"},
{lat: 49.020, lng: -133.13, text: "246 Cambie St"}
];
У вас есть собственный маркер, давайте назовем его значок и тень myIcon
и myShadow
.
myIcon = google.maps.MarkerImage(...);
myShadow = google.maps.MarkerImage(...);
Создайте три измененные версии значка и теневой графики, поворачивая их на 90 °, 180 ° и 270 ° соответственно.Объедините четыре набора изображений маркеров в два четырехэлементных массива:
myIcon90 = google.maps.MarkerImage(...);
myShadow90 = google.maps.MarkerImage(...);
myIcon180 = google.maps.MarkerImage(...);
myShadow180 = google.maps.MarkerImage(...);
myIcon270 = google.maps.MarkerImage(...);
myShadow270 = google.maps.MarkerImage(...);
myIcons = [myIcon, myIcon90, myIcon180, myIcon270];
myShadows = [myShadow, myShadow90, myShadow180, myShadow270];
Теперь обработайте список данных маркеров, чтобы назначить каждому из них поле ориентации.Вы можете сделать это в JavaScript на странице, но было бы лучше сделать это в коде, который в первую очередь генерирует список маркеров.Первая запись в данном lat / long получает значение ориентации 0. Следующая получает 1, следующая после этого получает 2, и так далее.Запись на другом lat / long получает значение ориентации 0.
Есть много способов сделать это назначение.Вы можете отсортировать список по широте и долготе, чтобы идентичные значения объединялись.Вы можете выполнить квадратный поиск методом грубой силы, сравнивая каждую запись с каждой записью, которая идет после.Вы можете выполнить сложный кластерный анализ (см. Теги вопросов SO кластерный анализ и группировка ).Имейте в виду, что, как правило, склонны к ошибкам при сравнении действительных чисел для точного равенства.
В любом случае результатом является модифицированный список данных маркера с добавленной ориентацией.
markerLatLngs = [
{lat: 49.010, lng: -133.00, text: "123 Main St #101", orientation: 0},
{lat: 49.010, lng: -133.00, text: "123 Main St #105", orientation: 1},
{lat: 49.020, lng: -133.13, text: "246 Cambie St", orientation: 0}
];
В том месте кода, где вы создаете маркер для каждой записи в списке, у вас, вероятно, есть вызов:
...
m = new google.maps.Marker({
position: google.maps.LatLng(
markerLatLngs[i].lat, markerLatLngs[i].lng
),
icon: myIcon,
shadow: myShadow,
...});
...
Измените этот код, чтобы использовать поле orientation
, чтобы выбрать соответствующий значок иshadow:
...
m = new google.maps.Marker({
position: google.maps.LatLng(
markerLatLngs[i].lat, markerLatLngs[i].lng
),
icon: myIcons[markerLatLngs[i].orientation],
shadow: myShadows[markerLatLngs[i].orientation],
...});
...
Выше приведен псевдокод, поэтому вам придется полировать его перед использованием, но, надеюсь, это поможет.
Marker Clusterer
Второй подход не вращает значки маркеров, но дает способ решить проблему более высокого уровня, как сделать видимыми несколько маркеров, которые имеют очень близкие широтные / длинные местоположения.
Для использования служебной библиотеки MarkerClusterer .Это позволяет отображать групповой маркер для наборов маркеров, которые находятся очень близко друг к другу (например, маркер с информационным окном, в котором перечисляются данные для всех включенных маркеров).См. Расширенный пример MarkerCluster , чтобы получить представление.
Смещение местоположения
Третий подход к решению проблемы более высокого уровня - это ввести небольшойШирота и долгота смещаются относительно положения маркеров, которые находятся слишком близко друг к другу.Результатом будет несколько близко расположенных маркеров вместо нескольких маркеров в одном месте.
Насколько велико "маленькое смещение"?Это функция вашего уровня масштабирования.Чтобы получить смещение, скажем, четырех пикселей, потребуется вдвое большее смещение широты на уровне масштабирования 8, чем на уровне масштабирования 9. Вы можете проигнорировать это и просто сгенерировать свой список маркеров со смещением широт / долгот, которое будет иметь видимое разделение, когдадостаточно увеличено:
markerLatLngs = [
{lat: 49.010, lng: -133.00, text: "123 Main St #101"},
{lat: 49.010, lng: -132.95, text: "123 Main St #105"},
/* ^^^^^^ longitude offset +0.05 */
{lat: 49.020, lng: -133.13, text: "246 Cambie St"}
];
Или вы можете сгенерировать значения latOffset и lngOffset для каждой записи списка в виде целочисленных единиц и рассчитать корректировку широты и долготы для одной единицы в терминах уровня масштабирования.Вам необходимо сохранить смещения в словаре MarkerOptions
(см. SO " Данные маркера Google Maps ").
/* list of marker data, with latitude and longitude offset */
/* in integer units */
markerLatLngs = [
{lat: 49.010, lng: -133.00, text: "123 Main St #101",
latOffset: 0, lngOffset: 0},
{lat: 49.010, lng: -133.00, text: "123 Main St #105",
latOffset: 0, lngOffset: 1},
{lat: 49.020, lng: -133.13, text: "246 Cambie St",
latOffset: 0, lngOffset: 0}
];
/* Store original position, and offsets, using marker options */
...
m = new google.maps.Marker({
icon: myIcon,
shadow: myShadow,
original: google.maps.LatLng(
markerLatLngs[i].lat, markerLatLngs[i].lng
),
latOffset: markerLatLngs[i].latOffset,
lngOffset: markerLatLngs[i].lngOffset
...});
...
Затем при каждом изменении уровня масштабирования (которое требует обновления настроек широты и долготы) выполняйте итерацию по каждому маркеру. Вычислить новую позицию на основе исходных смещений, умноженных на поправочные коэффициенты, которые являются функцией уровня масштабирования.
/* update marker positions on each change of zoom level */
adjustLat = fComputeAdjustmentLat(zoomlevel);
adjustLng = fComputeAdjustmentLng(zoomlevel);
/* iterate through markers. For each marker m: */
m.setPosition(
google.maps.LatLng(
m.original.lat() + m.latOffset*adjustLat,
m.original.lng() + m.latOffset*adjustLng
)
);
Это немного сложнее!
Опять же, это только псевдокод, вам придется полировать его перед использованием. Возможно, один из этих трех подходов подойдет вам и будущим читателям.