как я могу повернуть маркер на карте, если на ленте / лонге более одного маркера - PullRequest
2 голосов
/ 29 декабря 2011

У меня есть набор из 4 точек маркера с одинаковыми широтами и долгами.(разные офисы в пределах одного и того же адреса).

Я использую google maps api v3, и есть несколько случаев, когда мне приходится наносить несколько маркеров на одном широте / длине (IE: разные компании, норазличные наборы в одном здании).

Как мне повернуть значок маркера для каждого из них в направлении N / S / E / W.(Север является значением по умолчанию для всех маркеров, когда их масштабирование превышает уровень увеличения x.

При необходимости я могу опубликовать JS для построения карты.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2012

Я могу придумать, как решить эту проблему так, как вы ее излагаете.Я могу подумать о двух других способах решения проблемы более высокого уровня: как сделать видимыми несколько маркеров, которые имеют очень близкие широтные / длинные местоположения.

«Вращающиеся» маркеры

Допустим, вы начинаете со списка данных маркера: значения широты / долготы и некоторых других данных (здесь 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 
    )
);

Это немного сложнее!

Опять же, это только псевдокод, вам придется полировать его перед использованием. Возможно, один из этих трех подходов подойдет вам и будущим читателям.

0 голосов
/ 06 февраля 2012

Я нашел два расширения для Google MAP V3: infobox.js и markerwithlabel.js Оба могут обрабатывать элемент изображения DOM как контент, который, в свою очередь, я могу поворачивать с помощьюjQuery плагин поворота изображения .

Это работает даже без повторной установки изображения маркера после поворота.

Или

Лучший кросс-браузерный способ будетсоздать спрайт с маркером под разными углами и варьировать атрибут размера маркера в зависимости от угла.

Другим способом без использования кроссбраузера будет использование CSS3-преобразований, и вы, вероятно, захотите создатьпользовательское наложение, чтобы сделать это.Или нарисуйте на карте холст.Тем не менее, вы не получите элемент dom для захвата событий клика.

...