chevron-left chevron-right

[PHP][JS] Google Maps i znaczniki miejsc pobierane z bazy danych MySQL

Google Maps jest bardzo popularnym narzędziem do odnajdywania miejsc czy wyznaczania trasy. To wszyscy wiemy. Wiemy też, że bardzo wiele serwisów korzysta z Google Maps by wstawiać do nich znaczniki z lokalizacją różnych firm czy po prostu z lokacją swojej siedziby tylko po to, aby osoba korzystająca z serwisu wiedziała, gdzie takie miejsce się znajduje.
W tym artykule dowiesz się jak stworzyć mapę do której znaczniki będą wczytywane z bazy danych MySQL za pomocą PHP i AJAXa oraz Google Maps API.

1. Tworzymy bazę danych MySQL

Tworzymy tabelę o nazwie google_maps za pomocą takiego zapytania SQL:

CREATE TABLE IF NOT EXISTS `google_maps` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `nazwa` VARCHAR(255) NOT NULL,
  `adres` VARCHAR(255) NOT NULL,
  `lat` FLOAT(10,6) NOT NULL,
  `lng` FLOAT(10,6) NOT NULL,
  `typ` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`)
Teraz, gdy mamy już stworzoną strukturę tabeli to możemy przystąpić do dodawania własnych lokacji do tabeli lub wykorzystaj mój przykład:
INSERT INTO `google_maps` (`id`, `nazwa`, `adres`, `lat`, `lng`, `typ`) VALUES
(1, 'Szkoła Podstawowa nr 6', 'Wawel 13, Sosnowiec', 52.025459, 19.204102, 'szkoła'),
(2, 'Helios', 'Modrzejowska 32, Sosnowiec', 50.276367, 19.130651, 'kino'),
(3, 'Stadion Zimowy', 'Zamkowa 14, Sosnowiec', 50.282719, 19.144085, 'sport'),
(4, 'Pub Zakręcona', 'Małachowskiego 9, Sosnowiec', 50.276958, 19.131124, 'pub'),
(5, 'Pub Rubieże', 'Modrzejowska 39, Sosnowiec', 50.275600, 19.131746, 'pub'),
(6, 'IV Liceum Ogólnokształcące im. St. Staszica', 'Zillingera 1, Sosnowiec', 50.284199, 19.130030, 'szkoła'),
(7, 'Stadion Ludowy', 'Kresowa 1, Sosnowiec', 50.283031, 19.103456, 'sport');
To będzie wszystko jeśli chodzi o budowę i zapełnienie bazy danych

2. Połączenie z bazą danych - plik db.php

Następnym krokiem jest stworzenie pliku który będzie zawierał dane do połączenia się z bazą danych.
Kod takiego pliku wygląda następująco:

< ?php
$username="login do bazy";
$password="hasło do bazy";
$database="nazwa bazy danych";
?>
Tylko tyle i aż tyle. Myślę, że nie trzeba komentować tego pliku.

3. Generator pliku XML na podstawie danych z bazy MySQL - plik generatorXML.php

< ?php
//Pobiera dane do połączenia z bazą danych
require('db.php');
 
 
//Funkcja parsująca znaki do standardu ASCII, który jest potrzebny dla pliku XML. To też jest zabezpieczenie przed próbą wpisania kodu wykonującego.
function parseToXML($htmlStr) 
{ 
	$xmlStr=str_replace("<",'&lt;',$htmlStr); 
	$xmlStr=str_replace(">",'&gt;',$xmlStr); 
	$xmlStr=str_replace('"','&quot;',$xmlStr); 
	$xmlStr=str_replace("'",'&apos;',$xmlStr); 
	$xmlStr=str_replace("&",'&amp;',$xmlStr);
	$xmlStr=str_replace("$",'&#036;',$xmlStr);
	$xmlStr=str_replace("%",'&#037;',$xmlStr);
	$xmlStr=str_replace("(",'&#040;',$xmlStr);
	$xmlStr=str_replace(")",'&#041;',$xmlStr);
	$xmlStr=str_replace("[",'&#091;',$xmlStr);
	$xmlStr=str_replace("]",'&#093;',$xmlStr);
	$xmlStr=str_replace("{",'&#123;',$xmlStr);
	$xmlStr=str_replace("}",'&#125;',$xmlStr);
return $xmlStr; 
}
 
//Otwiera połączenie z serwerem baz danych MySQL
$connection=mysql_connect (localhost, $username, $password);
if (!$connection) {
	die ('Nie połączono z serwerem baz danych: '. mysql_error());
}
 
//Wybiera bazę danych z serwera
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
	die ('Nie można połączyć się z bazą danych: '. mysql_error());
}
 
//Pobieranie znacznika z tabeli. Dane są pobierane pojedynczo.
$query = "SELECT * FROM google_maps WHERE 1";
mysql_query('SET character_set_connection=utf8');
mysql_query('SET character_set_client=utf8');
mysql_query('SET character_set_results=utf8'); 
$result = mysql_query($query);
if (!$result) {
	die('Niepoprawne zapytanie do bazy: '. mysql_error());
}
 
//Tworzy plik XML
echo '<znaczniki>';
 
//Tworzy kolejne, pojedyncze wpisy do pliku XML
while ($row = @mysql_fetch_assoc($result)) {
	//Dodawanie atrybutów do znacznika
	echo '<znacznik ';
	echo 'nazwa="' . parseToXML($row['nazwa']) . '" ';
	echo 'adres="' . parseToXML($row['adres']) . '" ';
	echo 'lat="' . $row['lat'] . '" ';
	echo 'lng="' . $row['lng'] . '" ';
	echo 'typ="' . $row['typ'] . '" ';
	echo '/>';
}
 
//Zamyka plik XML
echo '</znaczniki>';
 
?>
Kod został opisany dość dokładnie. Dodam, że jeśli nie dodasz do kodu wpisów z mysql_query('SET ... ') to wtedy zaczynają się problemy z polskimi znakami odczytywanymi z bazy danych. Możliwe, że ten kod nie będzie Ci wogóle potrzebny, ale na potrzeby tego przykładu dodałem go, tak na wszelki wypadek.

4. Struktura HTML - plik index.html

<body onLoad="load()"> 	
	<div id="map">
    </div>
</body>
Jak to bywa w moich tutorialach, kod HTML nie jest jakiś wypasiony. To jest jego zaleta. Dzięki temu łatwo można zrozumieć mechanizmy.
W powyższym kodzie, mapa jest uruchamiana funkcją load() i będzie wczytywana do diva o nazwie map.

5. Kod generujący mapę i znaczniki - wstawiamy do sekcji HEAD.

//Baza ikonek do oznaczenia miejsc wedle typu
var ikonki = {
	pub: {
		icon: 'bar.png',
		shadow: 'shadow.png'
	},
	szkoła: {
		icon: 'school.png',
		shadow: 'shadow.png'
	},
	sport: {
		icon: 'stadium.png',
		shadow: 'shadow.png'
	},
	kino: {
		icon: 'cinema.png',
		shadow: 'shadow.png'
	}
};
//Ładuje znaczniki na mapę
function load() {
	//Ustawia środek mapy w wybranej pozycji, ustawia zoom mapy i jej typ -  w tym przypadku wskazuje na Sosnowiec
	var map = new google.maps.Map(document.getElementById("map"), {
		center: new google.maps.LatLng(50.286264, 19.104079),
		zoom: 13,
		mapTypeId: 'roadmap'
	});
	var dymekInfo = new google.maps.InfoWindow;
 
	//Pobiera nazwę pliku generującego XML
	pobierzAdres("generatorXML.php", function(data) {
		var xml = parseXml(data);
		//Zczytuje dane z pliku XML
		var znaczniki = xml.documentElement.getElementsByTagName("znacznik");
		for (var i = 0; i < znaczniki.length; i++) {
			var nazwa = znaczniki[i].getAttribute("nazwa");
			var adres = znaczniki[i].getAttribute("adres");
			var typ = znaczniki[i].getAttribute("typ");
			var wspolrzedne = new google.maps.LatLng(
			parseFloat(znaczniki[i].getAttribute("lat")),
			parseFloat(znaczniki[i].getAttribute("lng")));
			//Buduje strukturę wyświetlanego elementu
			var html = "<b>" + nazwa + " <br />" + adres;
			var ikona = ikonki[typ] || {};
			var znacznik = new google.maps.Marker({
				map: map,
				position: wspolrzedne,
				icon: ikona.icon,
				shadow: ikona.shadow
			});
			laczenieDanych(znacznik, map, dymekInfo, html);
		}
	});
}
 
//Funkcja wiążąca znaczniki z mapą
function laczenieDanych(znacznik, map, dymekInfo, html) {
	google.maps.event.addListener(znacznik, 'click', function() {
		dymekInfo.setContent(html);
		dymekInfo.open(map, znacznik);
	});
}
 
//Wywołanie połączenia za pomocą AJAXa
function pobierzAdres(url, callback) {
	var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest;
 
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			request.onreadystatechange = nicNieRob();
			callback(request.responseText, request.status);
		}
	};
 
	request.open('GET', url, true);
	request.send(null);
}
 
//Funkcja parsująca XML
function parseXml(str) {
	if (window.ActiveXObject) {
		var doc = new ActiveXObject('Microsoft.XMLDOM');
		doc.loadXML(str);
		return doc;
	}
	else if (window.DOMParser) {
		return (new DOMParser).parseFromString(str, 'text/xml');
	}
}
 
function nicNieRob() {}
Kod został objaśniony komentarzami. Ten kod wstawiamy do sekcji head jako kod javascript.
Należy pamiętać, aby wstawić do sekcji head API dla Google Maps jako kod javascript, co wygląda tak:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>

6. Style dla mapy - plik styl.css

body {
	width: 800px;
	margin: 50px auto;
	padding: 0;
	font-family: Arial, Helvetica, sans-serif;
}
h1 {
	font-size: 20px;
	text-align: center;
}
#map {
	width: 640px;
	height: 480px;
	margin: auto;
}

To byłoby na tyle. Mam nadzieję, że to wszystko się przyda Tobie 🙂