www.gmapsapi.com

Kompleksowy kurs podstaw API, po którym mapowianie nie będzie miało przed Tobą żadnych tajemnic!

Setki przykładów, kursów i poradników z kodem gotowym do skopiowania i korzystania.

Największa strona o Google Maps API w Polsce, największe źródło informacji w języku polskim.

Wyświetlanie listy widocznych markerow

Ten artykuł dotyczy API w wersji 2

« powrót do listy poradników

W poprzednich poradnikach (np. Dodanie funkcjonalnego paska bocznego) przedstawiono tworzenie paska bocznego z listą markerów. W tym poradniku stworzymy podobną aplikację - różnica polegać będzie jedynie na tym, że na liście widoczne będą jedynie markery, które w danym momencie są widoczne na mapie (przy danym poziomie przybliżenia i wycentrowaniu). Efekt działania ma być następujący:

Lista markerów na mapie Google Maps

Pierwsze podejście

W pierwszym przykładzie stworzymy aplikację, która wyświetlać będzie widoczne markery na pasku bocznym, ale dla uproszczenia nie będzie umieszczać na liście ikonek - tym zajmiemy się później.

Zacznijmy od szkieletu HTML, umiejscawiając kontener mapy oraz paska bocznego:

<table style="width: 700px; border: 0; border-collapse: collapse;">
	<tr>
		<td valign="top" style="width: 510px;">
			<div id='mapka' style='width: 500px; height: 400px; border: 1px solid black; background: gray;'>
			<!-- tu będzie mapa -->
			</div>
		</td>
		<td valign="top" id="pasek">
			<div id="licznik"></div>
			<ul id="lista"></div>
		</td>
	</tr>
</table>

W tym przykładzie do mapy dodamy kilkanaście markerów, których dane przechowywane są w tablicy w następującej notacji:

var markery_dane = [
	["Białystok", new GLatLng(53.12040528310657, 23.258056640625)],
	["Bydgoszcz", new GLatLng(53.09402405506325, 18.0010986328125)],
	["Gdańsk", new GLatLng(54.348552775876065, 18.66302490234375)],
	["Katowice", new GLatLng(50.28231945008157, 18.6712646484375)],
	["Kielce", new GLatLng(50.85450904781293, 20.6597900390625)],
	["Koszalin", new GLatLng(54.20101023973888, 16.1663818359375)],
	["Kraków", new GLatLng(50.06066538593667, 19.96490478515625)],
	["Łódź", new GLatLng(51.74743863117572, 19.4403076171875)],
	["Olsztyn", new GLatLng(53.76170183021049, 20.5059814453125)],
	["Poznań", new GLatLng(52.395715477302076, 16.9354248046875)],
	["Rzeszów", new GLatLng(50.0289165635219, 22.0220947265625)],
	["Szczecin", new GLatLng(53.42262754609993, 14.55413818359375)],
	["Warszawa", new GLatLng(52.217704193421454, 21.00311279296875)],
	["Wrocław", new GLatLng(51.09662294502995, 17.0343017578125)],
	["Zielona góra", new GLatLng(51.9781134854881, 15.5181884765625)],
];

Funkcja tworząca markery wygląda tak:

function stworzMarker(numer,nazwa,punkt)
{
	var marker = new GMarker(punkt, {title: nazwa});
	marker.nazwa = nazwa;
	marker.numer = numer;
	return marker;
}

i jest używana następująco:

for(var i=0; i<markery_dane.length; i++)
{
	var nazwa = markery_dane[i][0];
	var punkt = markery_dane[i][1];
	var marker = stworzMarker(i,nazwa,punkt);
	mapa.addOverlay(marker);
	markery.push(marker);
}

Wszytkie markery, jakie dodajemy na mapie musimy pamiętać w dowolnej tablicowej zmiennej globalnej, by móc się do nich odwoływać - do tablicy markery dodawane są kolejne markery (patrz linia 7)

Funkcja, która będzie generować (i odświeżać kod paska bocznego) wygląda następująco:

function odswiezPasek()
{
	var html = '';
	var licznik = 0;
	var obszar = mapa.getBounds();
	for(var i=0; i<markery.length; i++)
	{
		if(obszar.containsLatLng(markery[i].getLatLng()))
		{
			html+='<li class="'+(licznik%2==0 ? 'parzysty' : 'nieparzysty')+'"><a href="#" onclick="pokaz('+i+'); return false;">'+markery[i].nazwa+'</a><br /><span>'+formatujWspolrzedne(markery[i].getLatLng())+'</span></li>';
			licznik++;
		}
	}
	document.getElementById('lista').innerHTML = html;
	document.getElementById('licznik').innerHTML = 'Widocznych jest '+licznik+' markerów';
}

W wewnętrznej pętli następuje sprawdzenie, czy marker ma się pojawić w tablicy. Obszarem, który porównujemy, jest widoczny obszar określony czterema narożnikami mapy (pobieramy go za pomocą wbudowanej metody getBounds() mapy (linia 5). Obiekty typu GLatLngBounds posiadają metodę containsLatLng(), przyjmującą jeden argument (współrzędne geograficzne) i zwracającą true, jeżeli sprawdzany punkt zawiera się w obszarze, lub false jeśli się nie zawiera. Korzystamy z tego, sprawdzając w linii 8 czy widoczny obszar mapy zawiera punkt zaczepienia markera (tutaj właśnie potrzebne jest odwołanie do niego z globalnej tablicy markery. Później następuje formatowanie listy, parzyste rekordy mają nazwę klasy parzysty, nieparzyste nieparzysty. Po kliknięciu na marker wywoływana będzie funkcja pokaz(), a współrzędne będą formatowane za pomocą funkcji formatujWspolrzedne(). Funkcje o których mowa wyglądają następująco:

function formatujWspolrzedne(punkt)
{
	var lat = punkt.lat().toFixed(6);
	var lng = punkt.lng().toFixed(6);
	return lat+','+lng;
}
function pokaz(numer)
{
	GEvent.trigger(markery[numer],'click');
}

Funkcja pokaz() symuluje kliknięcie na markerze, dzięki czemu będzie można otworzyć okno z informacjami o nim. Przyjmuje ona jeden argument - nr markera, liczony od zera.

Co ma się stać po kliknięciu? To już zostaje zdefiniowane, gdy określona jest mapa GMap2:

mapa = new GMap2(document.getElementById("mapka"));
mapa.setCenter(new GLatLng(52,16), 7, G_NORMAL_MAP);
		
GEvent.addListener(mapa,'click',function(obiekt,punkt)
{
	if(obiekt && obiekt.nazwa)
		obiekt.openInfoWindowHtml('<div class="marker"><h3>'+obiekt.nazwa+'</h3><p>współrzędne: '+formatujWspolrzedne(obiekt.getLatLng())+'</p></div>');
});

Funkcja odswiezPasek() została już napisana, ale nadal skrypt nie wie, kiedy ma ją wywołać. Pierwsze wygenerowanie musi nastąpić przy starcie mapy (by pasek pokazywał markery widoczne od początku), a kolejne w momencie, kiedy zakończy się przesuwanie mapy (np. użytkownik przeciąga mapę za pomocą myszy, puszcza lewy przycisk -> następuje przeładowanie paska). Obie te rzeczy należy zdefiniować za deklaracją obiektu mapy w sposób następujący:

GEvent.addListener(mapa,'moveend',odswiezPasek);				
odswiezPasek();

Zdarzeniem odpowiadającym za zakończenie przesuwania jest - jak wynika z powyższego kodu - moveend.

Teraz jeszcze tylko odrobina kodu CSS:

table
{
	font-family: Arial;
	font-size: 12px;
	color: #333;
}

#lista
{
	height: 380px;
	width: 190px;
	overflow: auto;
	display: block;
	list-style: none;
	padding: 0;
	margin: 0;
}

#licznik
{
	width: 190px;
	height: 15px;
	background: #ddd;
}

#lista li
{
	display: block;
	margin: 0;
	padding: 2px;
}

#lista li.parzysty
{
	background: #f0f0f0;
}

#lista li a
{
	font-weight: bold;
	color: black;
	text-decoration: none;
}

#lista li a:hover
{
	color: red;
}

#lista li span
{
	font-size: 10px; 
	color: #888;
	font-style: italic;
}

.marker h3
{
	border-bottom: 2px solid orange;
	color: black;
	padding: 1px 0;
	margin: 0 0 3px 0;
	display: block;
}

.marker
{
	font-size: 12px;
	color: #444;
}

i już można odpalić skrypt: przykład 1pokaż kod przykładu

Modyfikacja - odświeżanie w czasie rzeczywistym

Przykład 1 działa zgodnie z oczekiwaniami, choć odświeżanie dopiero po zakończeniu przesuwania jest nieco mylące dla użytkownika. Dlatego lepszym rozwiązaniem jest odświeżanie w czasie rzeczywistym, co można osiągnąć poprzez użycie zdarzenia drag oprócz zdarzenia moveend. Zamiast:

GEvent.addListener(mapa,'moveend',odswiezPasek);				
odswiezPasek();

powinno być:

GEvent.addListener(mapa,'moveend',odswiezPasek);				
GEvent.addListener(mapa,'drag',odswiezPasek);				
odswiezPasek();

Efekt: przykład 2pokaż kod przykładu

Czas na ikonki

Aby skonstruować aplikację z obrazka:

Lista markerów w Google Maps API

należy wpierw zdefiniować różne ikonki dla każdego markera. Ponieważ w danych z tablicy dane_markery nie ma informacji o ikonie, to w przykładzie 3 każdy z markerów otrzyma losową ikonę z jednej z paczek z listy Wyświetlanie informacji na mapie - oto wygląd funkcji stworzMarker() po modyfikacji:

function stworzMarker(numer,nazwa,punkt)
{
	var ikona = new GIcon(ikona_domyslna); // dodane
	var losowa = parseInt(Math.random()*21); // dodane
	ikona.image = 'http://maps.google.com/mapfiles/kml/pal2/icon'+losowa+'.png'; // dodane
	var marker = new GMarker(punkt, {title: nazwa, icon: ikona}); // zmienione
	marker.nazwa = nazwa;
	marker.numer = numer;
	return marker;
}

Wcześniej trzeba jeszcze utworzyć globalną ikonę domyślną:

var ikona_domyslna = new GIcon();
ikona_domyslna.image = 'http://maps.google.com/mapfiles/kml/pal2/icon0.png';
ikona_domyslna.shadow = '';
ikona_domyslna.iconSize = new GSize(32,32);
ikona_domyslna.shadowSize = new GSize(0,0);
ikona_domyslna.iconAnchor = new GPoint(16,32);
ikona_domyslna.infoWindowAnchor = new GPoint(16,32);	

W kodzie CSS należy dokonać małych poprawek. Trzeba dodać definicję stylu dla obrazka (ikonki) w pasku bocznym:

#lista li img
{
	float: left;
	margin-right: 5px;
}

(dzięki której ikonka będzie wyrównana do lewej strony i będzie miała margines od otaczającego tekstu), oraz zmienić style dla elementu listy na:

#lista li
{
	display: block;
	margin: 0;
	padding: 2px;
	clear: left; /* dodane */
}

dzięki czemu lista będzie poprawnie wyświetlana, nawet, gdy markery będą miały duże wymiary.

Funkcja generująca pasek boczny lekko się zmieni - oto, jak ma wyglądać pętla for:

for(var i=0; i<markery.length; i++)
{
	if(obszar.containsLatLng(markery[i].getLatLng()))
	{
		html+='<li class="'+(licznik%2==0 ? 'parzysty' : 'nieparzysty')+'"><img src="'+markery[i].getIcon().image +'" alt="" /><a href="#" onclick="pokaz('+i+'); return false;">'+markery[i].nazwa+'</a><br /><span>'+formatujWspolrzedne(markery[i].getLatLng())+'</span></li>';
		licznik++;
	}
}

Jak widać, jedyną zmianą jest dodanie obrazka w tagu IMG, oraz ustawienie jego źródła na adres ikonki, którą pobiera się tak, jak pokazano w listingu powyżej.

Po wprowadzeniu tych zmian, aplikacja działać będzie następująco: przykład 3pokaż kod przykładu

Polecane artykuły

Dodaj stronę do ulubionego serwisu społecznościowego

Oto, co najczęściej czytają internauci, którzy przeczytali ten artykuł:

Dodawanie znaczników na mapę

API v2

Kurs podstaw cz. II: Podstawowe informacje na temat wstawiania markerów (znaczników)


Dodawanie markerów przez użytkownika

API v2

Poradnik pokazuje, w jaki sposób stworzyć formularz, pozwalający na dodawanie markerów


Popularne, darmowe ikony dla markerów

API v2

Kurs podstaw cz. IV: Lista darmowych ikon do wykorzystania w Twojej aplikacji mapowej


Kategorie markerów i polilinii

API v2

Stwórz markery/polilinie w kilku kategoriach, a następnie ukrywaj i pokazuj wybrane kategorie