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.

Dodawanie markerów przez użytkownika

Ten artykuł dotyczy API w wersji 2

« powrót do listy poradników

W poradniku Edycja danych na mapie i zapis do bazy opisany został sposób na edycję markerów przez użytkownika. Niemożliwe było jednak dodanie nowego markera. W tym poradniku zaprezentowany zostanie sposób na osiągnięcie takiej funkcjonalności.

Założenia

Użytkownik będzie mógł dodać na mapę jeden marker naraz. Będzie mógł dowolnie zdefiniować jego położenia (wizualnie, przeciągając marker po mapie lub klikając w wybranym punkcie) a także nazwę markera, jego opis czy wreszcie ikonę:

Formularz

Wszystkie informacje będą przechowywane w bazie danych. Cała aplikacja składać się będzie z trzech modułów:

  • modułu, pozwalającego na wyświetlanie markerów
  • modułu z formularzem dodawania markera
  • modułu weryfikującego i dodającego dane do bazy

W tym poradniku (dla zachowania wygody) zaczniemy od skonstruowania tabeli w bazie danych, następnie opracujemy formularz dodawania markera, następnie moduł dopisujący dane w bazie danych, a na końcu stworzymy część prezentacyjną.

Baza danych

Dane o markerach będą przechowywane w bazie danych. Stosowana w tym poradniku tabela została stworzona za pomocą następujących instrukcji języka SQL:

CREATE TABLE IF NOT EXISTS `PoznajGoogleMaps_073` (
  `id` int(11) NOT NULL auto_increment,
  `nazwa` varchar(55) collate utf8_polish_ci NOT NULL,
  `opis` varchar(255) collate utf8_polish_ci NOT NULL,
  `ikona` varchar(100) collate utf8_polish_ci NOT NULL,
  `lat` float(10,7) NOT NULL,
  `lng` float(10,7) NOT NULL,
  `data` datetime NOT NULL,
  `ip` varchar(25) character set latin1 NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ;

W tabeli będą przechowywane następujące dane o markerach:

  • nazwa (do 55 znaków)
  • opis markera (do 255 znaków)
  • adres url ikonki
  • współrzędne geograficzne
  • data dodania markera do bazy
  • IP dodającego

Formularz

Tworzenie aplikacji, pozwalającej na dodawanie markerów przez użytkowników zaczniemy od stworzenia formularza. Będzie się składał on z kilku pól oraz mapy, pozwalającej na wybór położenia markera i podgląd danych. Oto niezbędny kod HTML:

<div id="mapka" style="float: left; width: 400px; height: 400px; border: 1px solid black; background: gray;">
<!-- tu będzie mapa -->
</div>
<form action="/przyklad/073/02.html" method="post" id="formularz" style="display: block; width: 250px; margin-left: 420px;">
	<fieldset>
		<legend>współrzędne</legend>
		<input type="text" class="disabled" readonly="readonly" id="lat" name="lat" /><br /><span class="opis">długość geograficzna</span><br /><br />
		<input type="text" class="disabled" readonly="readonly" id="lng" name="lng" /><br /><span class="opis">szerokość geograficzna</span><br />
		Kliknij w wybranym punkcie mapy lub przeciągnij marker w żądane miejsce.
	</fieldset>
	<fieldset>
		<legend>dane markera</legend>
		<input onkeyup="uaktualnijDymek()" type="text" id="nazwa" name="nazwa" value="nazwa markera" /><br /><span class="opis">nazwa markera</span><br /><br />
		<textarea onkeyup="uaktualnijDymek()" id="opis" name="opis">opis markera</textarea><br /><span class="opis">opis markera</span><br /><br />
		<input onclick="uaktualnijIkone()" type="radio" name="ikona" id="ikona1" value="http://maps.google.com/mapfiles/kml/pal2/icon10.png" checked="checked" /><img style="border: 0;" alt="ikona1" src="http://maps.google.com/mapfiles/kml/pal2/icon10.png" /> 
		<input onclick="uaktualnijIkone()" type="radio" name="ikona" id="ikona2" value="http://maps.google.com/mapfiles/kml/pal2/icon11.png" /><img style="border: 0;" alt="ikona2" src="http://maps.google.com/mapfiles/kml/pal2/icon11.png" /> 
		<input onclick="uaktualnijIkone()" type="radio" name="ikona" id="ikona3" value="http://maps.google.com/mapfiles/kml/pal2/icon12.png"/><img style="border: 0;" alt="ikona3" src="http://maps.google.com/mapfiles/kml/pal2/icon12.png" /> <br />
		<input onclick="uaktualnijIkone()" type="radio" name="ikona" id="ikona4" value="http://maps.google.com/mapfiles/kml/pal2/icon13.png"/><img style="border: 0;" alt="ikona4" src="http://maps.google.com/mapfiles/kml/pal2/icon13.png" /> 
		<input onclick="uaktualnijIkone()" type="radio" name="ikona" id="ikona5"value="http://maps.google.com/mapfiles/kml/pal2/icon14.png"/><img style="border: 0;" alt="ikona5" src="http://maps.google.com/mapfiles/kml/pal2/icon14.png" /> <br />
		<span class="opis">ikona</span>
	</fieldset>
	<input type="submit" value="DODAJ MARKER!" />
</fom>
<br style="clear: left" />
<p id="info">Formularz, pozwalający na dodawanie markerów.</p>

Formularz składa się z dwóch pól tekstowych w trybie readonly, w których będą zawarte współrzędne markera. Współrzędnych nie będzie można zmieniać poprzez wpisywanie wartości. Następnie mamy pole tekstowe na nazwę, pole textarea na opis oraz zestaw przycisków radio, dzięki którym możliwy będzie wybór ikony. Zwróć uwagę, że do każdego z powyższych pól przypisana jest funkcja, wykonywana w przypadku albo kliknięcia (onclick) albo wciśnięcia klawisza (onkeyup). Te funkcje zostaną omówione później.

Programowanie zaczniemy od paru rzeczy wstępnych, a najistotniejszą z nich jest deklaracja ikony startowej:

var mapa;		
var marker;

var ikona = new GIcon();  
ikona.image = "http://maps.google.com/mapfiles/kml/pal2/icon10.png";  
ikona.iconAnchor = new GPoint(16, 16);
ikona.shadow = "";  
ikona.infoWindowAnchor = new GPoint(16,16);  
ikona.iconSize = new GSize(32, 32);  

Adres URL ikony jest dokładnie taki sam, jak wartość pierwszego przycisku radio w formularzu (będzie on domyślnie zaznaczony na starcie, toteż konieczne jest zadbanie o zgodność ikony markera z początkową wartością formularza).

Potrzebna będzie również funkcja do pobierania wartości z przycisków radio, dzięki której będziemy mogli sprawdzać aktualnie wybraną ikonę:

function pobierzWartosc(obiektRadio)
{
	if(!obiektRadio)
		return null;
	var ilosc = obiektRadio.length;
	if(ilosc == undefined)
		if(obiektRadio.checked)
			return obiektRadio.value;
	else
		return null;
	for(var i=0; i<ilosc; i++)
	{
		if(obiektRadio[i].checked)
		{
			return obiektRadio[i].value;
		}
	}
	return null;
}				

Kod inicjujący mapę wygląda podobnie jak w większości przykładów:

mapa = new GMap2(document.getElementById("mapka"));

mapa.setCenter(new GLatLng(52.348763181988076, 18.61083984375), 6, G_HYBRID_MAP);
mapa.addControl(new GLargeMapControl());  
mapa.addControl(new GMapTypeControl()); 

marker = new GMarker(mapa.getCenter(),{icon: ikona, draggable: true});
marker.opis = 'bez opisu';
mapa.addOverlay(marker);

Ostatnie trzy linijki odpowiedzialne są za dodanie markera, którego pozycję będzie można zmieniać za pomocą metody przeciągnij i upuść (draggable: true). Marker zostanie dodany na środku mapy (mapa.getCenter()). Zwróć uwagę, że zarówno marker jak i mapa są obiektami globalnymi, co ułatwia odwoływanie się do nich z zewnątrz.

Po kliknięciu na marker ma zostać wyświetlone okno infoWindow z jego danymi. Zakładając, że dane przechowywane są we własności opis, kod będzie wyglądał tak:

GEvent.addListener(marker,'click',function()
{
	marker.openInfoWindowHtml(marker.opis);
});

Zdarzenia

Teraz zajmiemy się sposobem komunikacji pomiędzy mapą a formularzem. Na początku funkcja, która uaktualnia współrzędne geograficzne w polach formularza na podstawie aktualnej pozycji markera:

function uaktualnijWspolrzedne()
{
	var input_lat = document.getElementById('lat');
	var input_lng = document.getElementById('lng');
	var punkt = marker.getLatLng();
	
	input_lat.value = punkt.lat();
	input_lng.value = punkt.lng();
}

Teraz funkcja, która uaktualnia ikonę markera na podstawie wyboru z formularza:

function uaktualnijIkone()
{
	var url = pobierzWartosc(document.forms['formularz'].elements['ikona']);
	marker.setImage(url);
	uaktualnijDymek()
}

Wcześniej zwróciłem uwagę, że dla każdego przycisku radio ustalono w kodzie HTML, że po kliknięciu ma zostać wywołana funkcja uaktualnijIkone(). Teraz możesz się przekonać, co ona właściwie robi - pobiera wartość aktualnie zaznaczonego przycisku, zmienia ikonę markera, a następnie uaktualnia dymek. Uaktualnienie dymka polega na podmianie opisu, przechowywanego jako własność opis. Robi się to tak:

function uaktualnijDymek()
{
	var url = pobierzWartosc(document.forms['formularz'].elements['ikona']);
	var tytul = document.getElementById('nazwa').value;
	var opis = document.getElementById('opis').value;
	
	var html = '<img src="'+url+'" alt="" style="float: right; border: 0;" /><h3 class="marker">'+tytul+'</h3><p class="marker">'+opis+'</p>';
	marker.opis = html;
	if(mapa.getInfoWindow() && !mapa.getInfoWindow().isHidden())
		GEvent.trigger(marker,'click');
}

W liniach 3-5 pobieramy aktualne wartości z formularza, następnie tworzymy sformatowany napis w HTML, i ustawiamy odpowiednią własność opis markera. Na końcu sprawdzamy, czy aktualnie otwarte jest okienko infoWindow, a jeśli tak to je odświeżamy (symulując kliknięcie na markerze)

Co jeszcze pozostało? W gruncie rzeczy niewiele. W czasie przeciągania markera chcemy uaktualniać na bieżąco współrzędne w formularzu. Korzystając z zaprogramowanej funkcji uaktualnijWspolrzedne(), definiujemy zdarzenia:

GEvent.addListener(marker,'drag',uaktualnijWspolrzedne);
GEvent.trigger(marker,'drag');
uaktualnijDymek();

W drugiej linii symulujemy wystąpienie zdarzenia drag po to, by a starcie wstawić odpowiednie współrzędne do formularza. Następnie uaktualniamy treść opisu markera na podstawie startowych wartości (nazwa, opis, ikona).

Ostatnim elementem jest zaprogramowanie zdarzenia kliknięcia na dowolny punkt mapy celem ustawienia nowych współrzędnych markera. W linii 3 sprawdzamy, czy kliknięto na punkt (a nie np. na istniejący marker):

GEvent.addListener(mapa,'click',function(o,p)
{
	if(p)
	{
		marker.setPoint(p);
		uaktualnijWspolrzedne();
	}
});

Gotowy formularz jest dostępny jako przykład: przykład 1pokaż kod przykładu

Zwróć uwagę, że jest to sam formularz - docelowy plik do którego odwołuje się skrypt jeszcze nie istnieje, stworzymy go w następnym kroku. W przykładzie 1 zaprezentowano natomiast możliwości edycyjne i graficzny interfejs dodawania markera.

Weryfikacja i dodanie danych do bazy

Formularz stworzony wcześniej będzie przesyłał dane do pliku, w którym musi nastąpić weryfikacja i dodanie danych do bazy. Po połączenu z bazą MySql, następuje:

$nazwa	= mysql_real_escape_string(strip_tags($_POST['nazwa']));
$opis	= mysql_real_escape_string(strip_tags($_POST['opis']));
$ikona	= mysql_real_escape_string(strip_tags($_POST['ikona']));
$lat	= $_POST['lat'];
$lng	= $_POST['lng'];
$ip 	= $_SERVER['REMOTE_ADDR'];

if($nazwa && $opis && $ikona && $lat && $lng)
{
	$query = sprintf('INSERT INTO PoznajGoogleMaps_073 (id,nazwa,opis,ikona,lat,lng,data,ip) VALUES ("","%s","%s","%s",%f,%f,now(),"%s")',$nazwa,$opis,$ikona,$lat,$lng,$ip);
	mysql_query($query);
	header("Location: http://gmapsapi.com/przyklad/073/03.html?dodano=1");
}
else
{
	header("Location: http://gmapsapi.com/przyklad/073/03.html?dodano=0");
}

W liniach 1-3 usuwamy slashe (dla bezpieczeństwa bazy) oraz tagi HTML (nieobowiązkowe, ale dla większości zastosowań niezbędne dla zapewnienia bezpieczeństwa i porządku wyświetlania danych na mapie). Później zwyczajnie dodajemy dane do stworzonej wcześniej tabeli w bazie danych. Jeśli operacja zakończyła się sukcesem, przeniesiemy użytkownika do strony http://gmapsapi.com/przyklad/073/03.html?dodano=1, a jeśli nie to do strony http://gmapsapi.com/przyklad/073/03.html?dodano=0. W pliku 03.html zawarta będzie mapa, przedstawiająca dodane do bazy markery. Należy je oczywiście pobrać AJAXem np. w postaci pliku JSON, oraz oczywiście pozostawić link do formularza. Oto gotowa strona, przedstawiająca markery z bazy: przykład 3pokaż kod przykładu

Strona z przykładu numer 3 powinna być tą, którą widzi na starcie odwiedzający. Jeśli chce dodać marker, klika na odpowiedni przycisk i zostaje przeniesiony do strony 01.html. Po dodaniu markera automatycznie powróci na stronę startową, przy czym parametr dodano w adresie będzie mówił o tym, czy marker dodano czy nie (bo np. nie zostały podane wszystkie pola).

Przetestuj aplikację

Stworzona aplikacja jest funkcjonalna i działa zgodnie z oczekiwaniami. Przekonaj się sam - włącz przykład numer 3, kliknij na link do dodawania markera, ustaw pozycję i dane markera. Po kliknięciu na przycisk ZAPISZ marker zostanie dodany do bazy i będzie wyświetlany w części prezentacyjnej. W celach demonstracyjnych, skrypt na moim serwerze ogranicza liczbę wpisów do 10, kasując nadmiarowe starsze wpisy.

Pełna zawartość skryptów PHP

Dalsze możliwości

  • Przy wykorzystaniu modułu geolokalizacji (zobacz poradnik Centrowanie mapy na podstawie IP) możesz przekształcić ten skrypt w interaktywną księgę gości, połączoną z mapą.
  • Jeśli dostęp do dodawania markerów ma być możliwy tylko dla osób z uprawnieniami, musisz we własnym zakresie zaprojektować formularz do logowania i za pomocą mechanizmu sesji weryfikować na poziomie PHP, czy dana osoba ma prawo dodawać markery.
  • Aby ograniczyć spam od botów internetowych, możesz zaimplementować mechanizm CAPTCHA.

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)


Popularne, darmowe ikony dla markerów

API v2

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


Wczytywanie danych z pliku XML

API v2

Kurs podstaw cz. X: Omówienie wczytywania danych z pliku XML za pomocą AJAXa


Kategorie markerów i polilinii

API v2

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