Wczytywanie danych z pliku XML
Jeśli zawartość Twojej mapy (markery, opisy) mają być generowane dynamicznie (np. z bazy MySql), lub też zwyczajnie lubisz mieć porządek w kodzie, warta uwagi będzie możliwość asynchronicznego pobierania specjalnie przygotowanego pliku, a następnie wyświetlenie zawartości mapy w opaciu o jego treść. Jakie są korzyści z zastosowania tej technologi?
- Oddzielenie warstwy skryptowej od danych
- Dodawanie setek czy tysięcy markerów nie powiększa pliku skryptowego
- Jest to rozwiązanie eleganckie, nie spowalniające mapy przy jej wczytaniu
- Wczytywanie danych z pliku XML pozwala zrobić pasek postępu
Podstawy
Naszym zadaniem będzie pobranie pliku (np. dane1.xml), przeparsowanie go funkcją GXml, a następnie wykonanie funkcji wyświetlającej markery z danych, pobranych z pliku.
W API2, dostępna była wbudowana funkcja GDownloadUrl, pozwalająca na pobieranie XML. API w wersji 3 nie posiada jej odpowiednika, trzeba zatem napisać własną funkcję lub skorzystać z gotowych bibliotek. W tym poradniku, zastosowano niewielką bibliotekę jxs. Należy dołączyć skrypt, na przykład w sposób następujący (w tym przykładzie linkujemy do lokalnej kopii skryptu):
<script src="/examples/109/jxs.js" type="text/javascript"></script>
Na oficjalnej stronie można znaleźć szerszą dokumentację działania, w przykładach na tej stronie stosuje się następującą konstrukcję:
jx.load('ADRES_PLIKU_XML', function(xml)
{
/* parsowanie pliku XML */
},'xml','get');
Pozwala ona pobrać plik XML za pomocą metody GET. Po pobraniu pliku wywoływana jest nienazwana funkcja, określona drugim argumentem. Trzeci argument jest informacją, w jaki sposób przetwarzać pobrane dane.
Przygotowałem plik XML, zawierający dane o 11 markerach - wybranych państwach Europy:
<dane> <marker lat="62.098297000000000" lon="17.3847860000" ikona="http://gmapsapi.com/ikony/szwecja.png" nazwa="Szwecja"/> <marker lat="61.438767493682825" lon="7.91015625000" ikona="http://gmapsapi.com/ikony/norwegia.png" nazwa="Norwegia"/> <marker lat="63.704722429433225" lon="26.9824218750" ikona="http://gmapsapi.com/ikony/finlandia.png" nazwa="Finlandia"/> <marker lat="51.919438000000000" lon="19.1451360000" ikona="http://gmapsapi.com/ikony/polska.png" nazwa="Polska"/> <marker lat="51.163475000000000" lon="10.4542390000" ikona="http://gmapsapi.com/ikony/niemcy.png" nazwa="Niemcy"/> <marker lat="55.012934000000000" lon="-3.4468680000" ikona="http://gmapsapi.com/ikony/uk.png" nazwa="Wielka Brytania"/> <marker lat="46.226699000000000" lon="2.20911900000" ikona="http://gmapsapi.com/ikony/francja.png" nazwa="Francja"/> <marker lat="39.707186656826540" lon="-6.0644531250" ikona="http://gmapsapi.com/ikony/hiszpania.png" nazwa="Hiszpania"/> <marker lat="41.292666000000000" lon="12.5735000000" ikona="http://gmapsapi.com/ikony/wlochy.png" nazwa="Włochy"/> <marker lat="48.382802000000000" lon="31.1746100000" ikona="http://gmapsapi.com/ikony/ukraina.png" nazwa="Ukraina"/> <marker lat="56.656226493502220" lon="33.6621093750" ikona="http://gmapsapi.com/ikony/rosja.png" nazwa="Rosja"/> </dane>
Krótka analiza:
- Między znacznikami <dane> i </dane> zawarte są tagi markerów
- Każdy marker opisany jest przez jeden tag <marker/>
- Każdy tag marker zawiera atrybuty: lat, lon, ikona i nazwa, odpowiadające kolejno za: szerokość, długość geograficzną, adres URL ikony oraz nazwę państwa
Znając strukturę pliku XML, możemy przejść do zbudowania funkcji, która przetworzy plik i doda markery na mapę
Pobieranie pliku
Funkcja, służąca do pobierania i parsowania pliku:
function wczytajMarkery()
{
jx.load('/examples/109/dane1.xml', function(xml)
{
/* tutaj będzie kod parsowania */
alert('Wczytano '+markery.length+' markerów z pliku dane1.xml');
},'xml','get');
}
Przeglądarka zacznie pobierać plik dane1.xml w tle. Kiedy pobieranie się skończy, zostanie wywołana nienazwana funkcja z jednym argumentem - xml, odpowiadającym zawartości pliku XML.
Parsowanie pliku
Parsowanie to przetwarzanie łańcuchu tekstowego na instrukcje dla komputera. Przeglądarka pobrała plik dane1.xml, teraz musimy jej powiedzieć, co ma z nim zrobić. Poniższy kod musi się znaleźć w linii 5. poprzedniego listingu.
var markery = xml.getElementsByTagName("marker");
for(var i=0; i<markery.length; i++)
{
var lat = parseFloat(markery[i].attributes.getNamedItem("lat").nodeValue);
var lon = parseFloat(markery[i].attributes.getNamedItem("lon").nodeValue);
var ikona_url = markery[i].attributes.getNamedItem("ikona").nodeValue;
var nazwa = markery[i].attributes.getNamedItem("nazwa").nodeValue;
var marker = dodajMarker(lat,lon,ikona_url,nazwa);
}
- W linii 1. tworzymy zmienną markery, i przypisujemy do niej wszystkie obiekty z tagiem marker (patrz przykład dane1.xml)
- W liniach 4-6 znajduje się instrukcja, która wykonuje pewne operacje dla każdego znalezionego w pliku dane1.xml markera
- W liniach 4-5 pobieramy zawartość atrybutu lat i lon, konwertujemy je do liczby zmiennoprzecinkowej, a następnie przypisujemy odpowiedniej zmiennej
- W liniach 6-7 wykonujemy analogiczne operacje dla adresu URL ikony i dla nazwy, przy czym nie robimy konwersji, bo dane są już w postaci stringa
- W linii 8 wywołujemy funkcję dodającą marker na mapę z odpowiednimi argumentami
Pozostaje tylko napisać funkcję dodającą marker, oraz przygotować odpowiednie pliki graficzne, zgodne ze ścieżkami, które są w pliku dane1.xml
Po zapoznaniu się z poprzednimi częściami kursu, własna funkcja nie powinna stanowić problemu:
function dodajMarker(lat,lon,ikona_url,nazwa)
{
var rozmiar = new google.maps.Size(30,23);
var punkt_startowy = new google.maps.Point(0,0);
var punkt_zaczepienia = new google.maps.Point(15,12);
var ikona = new google.maps.MarkerImage(ikona_url, rozmiar, punkt_startowy, punkt_zaczepienia);
var marker = new google.maps.Marker(
{
position: new google.maps.LatLng(lat,lon),
title: nazwa,
icon: ikona,
map: mapa
}
);
marker.txt = 'Wybrane państwo:<br /><strong>'+nazwa+'</strong>';
google.maps.event.addListener(marker,"click",function()
{
dymek.setPosition(marker.getPosition());
dymek.setContent(marker.txt);
dymek.open(mapa);
});
return marker;
}
Pełny kod wraz z dzialającym przykładem dostępny jest tutaj: przykład 1pokaż kod przykładu
Rysowanie polilinii z pliku XML
Analogicznie, z pliku XML można pobrać dane punktowe polilinii, by następnie je narysować. Napiszemy aplikację, która wczyta z zewnętrznego pliku dane polilini i ją narysuje. Punkty będą identyczne jak w tym przykładzie. Przyjmijmy następujący format pliku:
<dane> <polilinia> <punkt lat="53.748711" lon="14.238281"/> <punkt lat="53.258641" lon="14.425049"/> <punkt lat="53.067627" lon="14.304199"/> <punkt lat="52.975108" lon="14.161377"/> <punkt lat="52.882391" lon="14.161377"/> <punkt lat="52.716331" lon="14.425049"/> <!-- i tak dalej i tak dalej --> </polilinia> </dane>
Tag polilinia nie posiada atrybutów, ale ma za to kilka elementów-dzieci. Każdy z nich to jeden punkt polilinii, opisany współrzędnymi z atrybutów lat i lon.
Funkcja parsująca zmieni się:
function wczytajPolilinie()
{
jx.load('/examples/109/dane2.xml', function(xml)
{
var polilinie = xml.getElementsByTagName("polilinia");
for(var i=0; i<polilinie.length; i++)
{
var punkty = polilinie[i].getElementsByTagName("punkt");
var wierzcholki = [];
for(var j=0; j<punkty.length; j++)
{
var lat = parseFloat(punkty[j].attributes.getNamedItem("lat").nodeValue);
var lon = parseFloat(punkty[j].attributes.getNamedItem("lon").nodeValue);
var latlng = new google.maps.LatLng(lat,lon);
wierzcholki.push(latlng);
}
dodajPolilinie(wierzcholki);
}
alert('Wczytano '+polilinie.length+' polilinii z pliku dane2.xml');
},'xml','get');
}
Dodanie polilinii na mapę to już formalność:
function dodajPolilinie(wierzcholki)
{
var polilinia = new google.maps.Polygon(
{
paths: [wierzcholki],
strokeColor: '#ff0000',
strokeOpacity: 0.5,
strokeWeight: 3,
fillColor: '#ff0000',
fillOpacity: 0.21,
map: mapa
}
);
return polilinia;
}
Zobacz działający przykład: przykład 2pokaż kod przykładu
Uwagi
- Plik xml musi być poprawnym plikiem XML. Jego poprawność możesz sprawdzić pod tym adresem.
- Plik xml musi być na tym samym serwerze co plik, zawierający instrukcję pobierania. Jest to zabezpieczenie przed atakiem typu XSS.
- W pliku XML musi być dokładnie jeden nadrzędny tag (w tym przykładzie jest to <dane></dane>)
Przejdź do kolejnej części kursu
Tytuł następnej części kursu to Geokodowanie adresów






