2010-02-04 5 views
4

У меня есть карта Google, в которой отображается ряд маркеров. Когда пользователь перемещает карту, маркеры перерисованы для новых границ, используя код ниже:Карты Google: помните идентификатор маркера с открытым информационным окном

GEvent.addListener(map, "moveend", function() { 
    var newBounds = map.getBounds(); 
    for(var i = 0; i < places_json.places.length ; i++) { 
     // if marker is within the new bounds then do... 
     var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon); 
     var html = "blah"; 
     var marker = createMarker(latlng, html); 
     map.addOverlay(marker); 
    } 
}); 

Мой вопрос прост. Если пользователь нажал на маркер, чтобы он показывал открытое информационное окно, в настоящее время, когда границы перерисовываются, информационное окно закрывается, поскольку маркер добавляется снова с нуля. Как я могу это предотвратить?

Это не идеально, потому что часто границы перерисовывается, когда пользователь нажимает на маркер и карта перемещается, чтобы отобразить информационное окно - так появляется информационное окно, а затем снова исчезает :)

Я думаю, пара из возможных способов:

  • помнит, какой маркер имеет открытое информационное окно, и открыть его снова, когда маркеры перерисовываются
  • фактически не повторно добавить маркер с открытым информационным окном, просто оставьте его там

Однако оба требуют, чтобы маркер с открытым окном имел какой-то идентификационный номер, и я не знаю, что это действительно так в API Карт Google. Кто угодно?

---------- UPDATE ------------------

Я попытался сделать это путем загрузки маркеров в начальный массив, как было предложено. Это загружается нормально, но страница вылетает после перетаскивания карты.

<script type="text/javascript" src="{{ MEDIA_URL }}js/markerclusterer.js"></script> 
<script type='text/javascript'> 

function createMarker(point,html, hideMarker) { 
    //alert('createMarker'); 
    var icon = new GIcon(G_DEFAULT_ICON); 
    icon.image = "http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png"; 
    var tmpMarker = new GMarker(point, {icon: icon, hide: hideMarker}); 
    GEvent.addListener(tmpMarker, "click", function() { 
    tmpMarker.openInfoWindowHtml(html); 
    }); 
    return tmpMarker; 
} 

var map = new GMap2(document.getElementById("map_canvas")); 
map.addControl(new GSmallMapControl()); 
var mapLatLng = new GLatLng({{ place.lat }}, {{ place.lon }}); 
map.setCenter(mapLatLng, 12); 
map.addOverlay(new GMarker(mapLatLng)); 

// load initial markers from json array 

var markers = []; 
var initialBounds = map.getBounds(); 

for(var i = 0; i < places_json.places.length ; i++) { 
     var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon); 
     var html = "<strong><a href='/place/" + places_json.places[i].placesidx + "/" + places_json.places[i].area + "'>" + places_json.places[i].area + "</a></strong><br/>" + places_json.places[i].county; 
     var hideMarker = true; 
     if((initialBounds.getSouthWest().lat() < places_json.places[i].lat) && (places_json.places[i].lat < initialBounds.getNorthEast().lat()) && (initialBounds.getSouthWest().lng() < places_json.places[i].lon) && (places_json.places[i].lon < initialBounds.getNorthEast().lng()) && (places_json.places[i].placesidx != {{ place.placesidx }})) { 
      hideMarker = false; 
     } 
     var marker = createMarker(latlng, html, hideMarker); 
     markers.push(marker); 
} 

var markerCluster = new MarkerClusterer(map, markers, {maxZoom: 11}); 

</script> 

ответ

2

Вы должны, вероятно, создать все маркеры на начальной стадии с методом createMarker() и хранить возвращенные GMarker объекты внутри массива. Не забудьте установить свойство hide: true в GMarkerOptions при создании своих маркеров, чтобы они были созданы как скрытые по умолчанию.

Затем вместо повторения через places_json.places вы можете выполнить итерацию через ваш новый массив GMarker. Вы могли бы получить координаты каждого маркера с помощью метода GMarker.getLatLng(), с помощью которого можно проверить, находится ли каждый маркер в пределах границ.

Наконец, просто позвоните GMarker.show() для маркеров, которые лежат в пределах, или GMarker.hide(), чтобы скрыть их.

Вы бы устранили дорогостоящее разрушение/создание маркеров на каждом движении карты. Как положительный эффект, это также решит вашу проблему GInfoWindow.

+0

Возможно, - хотя у меня есть что-то вроде 2000 маркеров, в общей сложности, поэтому я избегал делать это таким образом, в первую очередь. Как вы думаете, я могу сделать это так, как вы предлагаете, без сбоев браузера? – AP257

+0

(Я предполагаю, что другой способ задать вопрос: если бы я показал 2000 маркеров на карте, это, безусловно, повредило бы браузер, но если я создам 2000 маркеров в javascript и покажу только 20 или 30 из них за раз, произойдет ли это сбой или создавать проблемы производительности?) – AP257

+0

Нет, 2000 скрытых маркеров должны быть приемлемыми. Им потребуется некоторое время для загрузки, но оно должно быть намного более плавным, чем уничтожать все маркеры при каждом перемещении мыши и воссоздавать видимые. (Если вы не уничтожаете свои маркеры, у вас будет утечка памяти.) ... Вы можете проверить эту статью для некоторых тестов с большим количеством маркеров: http://www.svennerberg.com/ 2009/01/handling-large-amount-of-markers-in-google-maps/ –

1

Если вы используете много маркеров, убедитесь, что вы используете GMarkerManager. Он разработан для многих маркеров, и только несколько видимых одновременно.

http://mapki.com/wiki/Marker_Optimization_Tips

Смежные вопросы