O produktu | Technická podpora | Verze | Videoukázky | Manuály | Nabídka práce | Kontakt
Česky   menu-arrow-gray-horizontal.gif
Domů > O produktu > Srovnání licencí
Další informace
Hledat


Video ukázky
Drag&drop v prostředí Visual PHP™

Nejnovější video ukázky:
Nabídka práce
Společnost
E-VISION International s.r.o.

příjme na dlouhodobou spolupráci PHP5 a JavaScript programátory
pro vývoj produktu Visual PHP™




Více informací ...
Napsali o Visual PHP™
Novinky na e-mail
Váš e-mail

Visual PHP™ Doporučuje!
Pro práci jak v developerském, tak v administrátorském rozhraní doporučujeme používat internetový prohlížeč Mozilla Firefox, na jehož základě je vzhledem ke stabilitě, dodržování standardů konzorcia W3C a ochranným prvkům prohlížeče celý software vyvíjen.

Import KML/KMZ a zobrazení v Google Map

Formát KML je XML soubor obsahující GPS data, která lze lehce importovat do aplikace Google Earth. Tyto soubory jsou exportovány ze spousty programů podporujících GPS. Rozšířením je pak formát KMZ, který je defacto ZIP soubor, ve kterém je kromě KML souboru i multimediální obsah a setkat se s ním můžete například u nových fotoaparátů s GPS. V tomto návodu si ukážeme, jak lze KML a KMZ importovat do Visual PHP™ a zobrazit informace pomocí komponenty Google Map.

Formát souborů

Nejprve se podíváme na formát souboru KML. Tento soubor obsahuje značky, cesty a styly, kterými se mají zobrazit.

Výstupní soubor KML z fotoaparátu
<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
    <Style id="Line_11_37">
        <LineStyle>
            <color>ffff0055</color>
            <width>5</width>
        </LineStyle>
    </Style>
    <Style id="POI_27_38">
        <IconStyle>
            <scale>0.7</scale>
            <Icon>
                <href>icon/push_to_log.png</href>
            </Icon>
        </IconStyle>
    </Style>
    <Placemark>
        <name>Lat:50.505997, Lon:13.653536, Ele:259.422607</name>
        <description>
            <![CDATA[ 2010/6/24 15:52:9 <br /><br /><img src="photo/p2.jpg" /><br /><br /><img src="photo/p3.jpg" /><br /><br /><img src="photo/p1.jpg" /><br /> ]]>
        </description>
        <styleUrl>#POI_27_38</styleUrl>
        <LookAt>
            <longitude>13.653536</longitude>
            <latitude>50.505997</latitude>
            <range>6000</range>
            <tilt>45</tilt>
            <heading>0</heading>
        </LookAt>
        <Point>
            <coordinates>13.653536,50.505997,259.422607</coordinates>
        </Point>
    </Placemark>
    <Folder>
        <name>Tracks</name>
        <Placemark>
            <name>Holux2010/06/24_15:51</name>
            <styleUrl>#Line_11_37</styleUrl>
            <LineString>
                <tessellate>1</tessellate>
                <coordinates>13.653077,50.505863,264.000732 13.653094,50.505905,259.977295 13.653111,50.505947,261.289795 13.653087,50.505978,259.211670 13.653051,50.505981,257.078857 13.653046,50.505981,256.430420 13.653073,50.505989,256.891357 13.653146,50.506035,257.289795 13.653211,50.506084,256.899170 13.653281,50.506130,256.633545 13.653361,50.506104,257.000732 13.653444,50.506069,258.789795 13.653514,50.506027,259.633545 13.653528,50.505993,259.430420 13.653525,50.506001,259.571045 13.653531,50.505993,259.797607</coordinates>
            </LineString>
        </Placemark>
    </Folder>
</Document>
</kml>
Výstupní soubor KML z mobilní aplikace Run.GPS
<?xml version="1.0" encoding="UTF-8"?>
<kml creator="Run.GPS" xmlns="http://earth.google.com/kml/2.1">
<Document>
    <name>run</name>
    <Style id="trackStyle">
        <LineStyle>
            <color>d38b3a1b</color>
            <width>4</width>
        </LineStyle>
    </Style>
    <Placemark>
        <name>run</name>
        <styleUrl>#trackStyle</styleUrl>
        <LineString>
            <tessellate>1</tessellate>
            <coordinates>17.279413400,49.596376250,0.000000000 17.279422950,49.596364380,0.000000000 17.279430870,49.596398140,225.400004069 17.279400510,49.596390110,225.400004069 17.279409890,49.596403420,225.400004069 17.279422300,49.596401470,225.400004069 17.279446860,49.596418060,225.400004069 17.279502120,49.596442810,225.400004069 17.279505460,49.596458220,225.400004069 17.281490580,49.596821600,223.429515901
17.281523230,49.596823730,223.417749220 17.281546530,49.596831010,223.396781675 17.281582200,49.596826640,223.367749122 17.281606810,49.596804400,223.346781085 17.281647230,49.596798890,223.341942080 17.281681330,49.596785290,223.345167591 17.281700700,49.596773380,223.369361139 17.281717000,49.596783890,223.392069983 17.281748470,49.596761640,223.450800336 17.281792450,49.596747190,223.433339921
            </coordinates>
        </LineString>
    </Placemark>
</Document>
</kml>
Soubor KMZ je vlastně ZIP soubor, pouze s jinou příponou. Tento soubor obsahuje ikonky pro značky a případně fotky nebo videa. Struktura vypadá takto:
file.kmz
- [ icon ]
   - agriculture.png
   - airport.png
   - arrow.png
   - attraction.png
   - bar.png
   - ...
- [ photo ]
   - p1.jpg
   - p2.jpg
   - p3.jpg
   - p4.jpg
   - p5.jpg
   - ...
- track.kml
Adresář icon obsahuje ikonky pro značky na mapě a adresář photo potom fotografie z těchto míst. Kde se mají tyto obrázky zobrazit je definováno v souboru track.kml.

Tabulky databáze

Návrh tabulek databáze vypadá takto:

Tabulka kmz

V tabulce kmz budou jednotlivé importy. V poli name bude uložen název a v polích latitude a longitude pak souřadnice středu pro výchozí zobrazení mapy.

Tabulka kmz_placemarks

V každé mapě pro jednotlivé importy bude seznam míst, které se v mapě zobrazí pomocí značek. Těchto značek bude více, proto budou uloženy v tabulce kmz_placemarks, která je detail tabulkou tabulky kmz.  Pole name bude obsahovat název místa, v poli icon bude importována ikonka pro tuto značku a konečně v polích latitude a longitude budou souřadnice. Vazba na master tabulku je realizována polem parent.

Tabulka kmz_placemark_images

Protože každé místo může obsahovat více fotografií, bude tabulka kmz_placemark_images detail tabulkou tabulky kmz_placemarks. Pole image pak bude obsahovat fotografii. Vazba na master tabulku je opět realizována polem parent.

Tabulka kmz_paths

Import také může obsahovat trasu určenou seznamem GPS souřadnic. Proto tato data uložíme do tabulky kmz_paths. Každý import a tedy zobrazení na 1 mapě může obsahovat více cest, proto je tato tabulka detail tabulkou tabulky kmz. Vazba na master tabulku je realizována polem parent.

Import souboru KMZ / KML

Skript, který si ukážeme, můžeme použít jak v administraci, tak i pro běžné návštěvníky na frondendu webu. Vytvoříme nový skript v sekci Prezentace -> Skripty a nastavíme mu tid=kmz_import. Samotný skript pak bude vypadat následovně:
echo "<h1>Import KMZ/KML</h1>";	

function importPlacemark($PlacemarkNode)
{
	global $kmzRecord, $styles, $tmpDir;
	global $minLatitude, $maxLatitude, $minLongitude, $maxLongitude;

	$styleId = $PlacemarkNode->getChildNodeByName("styleUrl")->getValue();
	$styleId = substr($styleId, 1, strlen($styleId));

	$LineStringNode = $PlacemarkNode->getChildNodeByName("LineString");
	if ($LineStringNode)
	{
		$kmzPathRecord = array();
		$kmzPathRecord["parent"] = $kmzRecord["id"];
		$kmzPathRecord["name"] = $PlacemarkNode->getChildNodeByName("name")->getValue();

		$kmzPathRecord["color"] = $styles[$styleId]["color"];
		$kmzPathRecord["width"] = $styles[$styleId]["width"];
			
		// extrahuji latitude a longitude (výšky v Google Map nevyužijeme - soubor je totiž určený pro 3D aplikaci Google Earth)
		$coords = array();

		$coordinates = $LineStringNode->getChildNodeByName("coordinates")->getValue();
		$coordinates = explode(" ", $coordinates);
		foreach($coordinates as $coordinate)
		{
			$coordinate = explode(",", $coordinate);
				
			if ($coordinate[0] && $coordinate[1])
			{
				$latitude = trim($coordinate[1]);
				$longitude = trim($coordinate[0]);

				$minLatitude = min($minLatitude, $latitude);
				$maxLatitude = max($maxLatitude, $latitude);
				$minLongitude = min($minLongitude, $longitude);
				$maxLongitude = max($maxLongitude, $longitude);

				$coordinate = array(
					"latitude"  => $latitude,
					"longitude" => $longitude,
				);
				$coords[] = $latitude.":".$longitude;						
			}
		}
		$kmzPathRecord["coordinates"] = implode("|", $coords);
		getTable("kmz_paths")->insertRecord($kmzPathRecord);
	}
	else
	{
		$kmzPlacemarkRecord = array();
		$kmzPlacemarkRecord["parent"] = $kmzRecord["id"];
		$kmzPlacemarkRecord["name"] = $PlacemarkNode->getChildNodeByName("name")->getValue();
		
		$LookAtNode = $PlacemarkNode->getChildNodeByName("LookAt");
		if ($LookAtNode)
		{
			$kmzPlacemarkRecord["latitude"] = $LookAtNode->getChildNodeByName("latitude")->getValue();
			$kmzPlacemarkRecord["longitude"] = $LookAtNode->getChildNodeByName("longitude")->getValue();
		}

		if ($styles[$styleId]["icon"])
			$kmzPlacemarkRecord["icon"] = "file://".$tmpDir."/".$styles[$styleId]["icon"];
		
		// uložím do databáze
		$kmzPlacemarkRecord = getTable("kmz_placemarks")->insertRecord($kmzPlacemarkRecord);

		// ziskam vsechny obrazky z popisu (jsou tam uloženy jako HTML kód)
		$DescriptionNode = $PlacemarkNode->getChildNodeByName("description");
		$description = $DescriptionNode->getValue();
		if ($description)
		{
			if (preg_match_all("|src=\"([^\"]+)\"|ims", $description, $matches, PREG_SET_ORDER))
			{
				foreach($matches as $match)
				{
					$kmzPlacemarkImageRecord = array();
					$kmzPlacemarkImageRecord["parent"] = $kmzPlacemarkRecord["id"];
					$kmzPlacemarkImageRecord["image"] = "file://".$tmpDir."/".$match[1];
				
					// uložím do databáze
					getTable("kmz_placemark_images")->insertRecord($kmzPlacemarkImageRecord);
				}
			}
		}
	}
}

if ($formSent != "true")
{
	echo "<form method='post'>";

	echo "Název:<br />";
	echo "<input type='text' name='kmzName' value='' /><br />";

	echo "Soubor KMZ/KML:<br />";
	$Component = getComponent("FILE", "kmzFile");
	$Component->setParams("progress=true");
	echo $Component->getCode()."<br />";

	echo "<input type='submit' value='Importovat' />";
	echo "<input type='hidden' name='formSent' value='true' />";
	echo "</form>";
}
else
{
	$minLatitude = 1000000;
	$maxLatitude = 0;
	$minLongitude = 1000000;
	$maxLongitude = 0;

	if (strtolower(getFileExt($kmzFile)) == "kmz")
	{
		// vytvořím pracovni adresář
		$tmpDir = PROJECTPATH."repository/temp/kmz_".createUUID()."/";
		_mkdir($tmpDir);

		// rozbalím KMZ (je to de facto ZIP archív)
		$Zip = createObject("Zip");
		$Zip->open($kmzFile);
		$Zip->extractTo($tmpDir);
	
		// otevřu XML soubor
		$XML = createObject("XML");
		$XML->open($tmpDir."/track.kml");
	}
	else
	{
		// otevřu XML soubor
		$XML = createObject("XML");
		$XML->open($kmzFile);
	}
	$XMLDocument = $XML->documentElement->getChildNodeByName("Document");

	// vytvořím nový master záznam v databázi
	$kmzRecord = array(
		"name" => $kmzName,
	);
	$kmzRecord = getTable("kmz")->insertRecord($kmzRecord);

	// načtu všechny styly
	$styles = array();
	foreach($XMLDocument->getChildNodesByName("Style") as $ChildNode)
	{
		$style = array();
		$styleId = $ChildNode->getAttribute("id");
		$IconStyleNode = $ChildNode->getChildNodeByName("IconStyle");
		if ($IconStyleNode)
		{
			$IconNode = $IconStyleNode->getChildNodeByName("Icon");
			if ($IconNode)
			{
				$HrefNode = $IconNode->getChildNodeByName("href");
				$style["icon"] = $HrefNode->getValue();
			}
		}
		$LineStyleNode = $ChildNode->getChildNodeByName("LineStyle");
		if ($LineStyleNode)
		{
			$ColorNode = $LineStyleNode->getChildNodeByName("color");
			// barva je ve formatu AABBGGRR (alpha,blue,green,red)
			$color = $ColorNode->getValue();
			$style["color"] = "#".$color[6].$color[7].$color[4].$color[5].$color[2].$color[3];
			$WidthNode = $LineStyleNode->getChildNodeByName("width");
			$style["width"] = $WidthNode->getValue();
		}

		$styles[$styleId] = $style;
	}
	foreach($XMLDocument->getChildNodesByName("Placemark") as $PlacemarkNode)
	{
		importPlacemark($PlacemarkNode);
	}
	foreach($XMLDocument->getChildNodesByName("Folder") as $FolderNode)
	{
		foreach($FolderNode->getChildNodesByName("Placemark") as $PlacemarkNode)
		{
			importPlacemark($PlacemarkNode);
		}	
	}
	
	// spočítám střed mapy
	$kmzRecord["latitude"] = $minLatitude+($maxLatitude-$minLatitude)/2;
	$kmzRecord["longitude"] = $minLongitude+($maxLongitude-$minLongitude)/2;
	
	getTable("kmz")->updateRecord($kmzRecord);
	
	echo "Import byl dokončen";
}
Ve skriptu jsou použity objekty Zip pro rozbalení souboru s příponou kmz a objektu XML pro otevření a čtení KML souboru.

Spuštění importního skriptu

Abychom mohli tento skript v administraci vyvolat, přidáme do Prezentace -> Admin Menu novou položku s přímým odkazem:
scripts.php?tid=kmz_import
Na frondentu pak přehled importů uvidíte na této URL:
http://www.vase-domena.cz/kmz.php

Zdrojové kódy

Pro velmi rychlou implentaci tohoto tutoriálu máte k dispozici XML soubory, které můžete importovat do Vaší prezentace

Ukázkové KMZ a KML soubory

Pro odzkoušení jsme přidali ukázkové KMZ soubory a dokonce jsem si byl i zaběhat pro získání KML souborů :)

Ukázky výstupu map na www

run.gps.kml run.gps.2.kml knihovna.kmz
 
trasa1.kmz trasa2.kmz  


Související články



UPOZORNĚNÍ

Některé vlastnosti publikované v tomto článku mohou být funkční pouze s nejnovější verzí jádra. Pokud máte starší verzi jádra, doporučujeme provést aktualizaci na nejnovější verzi.

Přihlášení
Vyzkoušejte zdarma

na dobu 30 dní
Aktuální verze jádra
Single Developer 1.7.9.680
20.leden 2012

Professional 1.7.9.680
20.leden 2012

Enterprise 1.7.9.680
20.leden 2012


Příručka pro vývojáře
Developer Guide 1.0.5
10.červenec 2009 09:36:42

Příručka pro administrátory
Administrator Guide 1.0.24
27.srpen 2010 11:58:08

Instalační skript
install.php 1.9.22
12.duben 2012 18:02:40

Novinky v příští verzi
nová událost onGetFilterSQL() pro pole tabulky umožňující nastavit vlastní SQL filtrace
Více ...

rss.gif
Podpora

Fotogalerie 10.5.2012
Sekce: Tvorba prezentací
Chyba v hromadné korespondenci, nelze odeslat příloha (nová verze 6.4.2012
Sekce: Bug reporty
AntiSpam obrázek 6.4.2012
Sekce: Programování
Chyba při opravách textů 4.4.2012
Sekce: Bug reporty
Admin může smazat Developera, je to ok? 27.3.2012
Sekce: Bug reporty
Mapa webu 19.3.2012
Sekce: Tvorba prezentací


rss.gif
Aktuality

Update komponenty Weather
18.listopad 2011
Server weather.com se rozhodl ukončit poskytování informací o počasí zdarma a přešel na placenou variantu (cca 60$ měsíčně). Z tohoto důvodu jsme byli nuceni upravit komponentu Weather tak, aby stahovala informace o počasí z jiného zdroje dat a to konkrétně ze serveru www.worldweatheronline.com. Tento server také poskytuje informace o počasí z celého světa, nicméně množství informací je oproti původnímu zdroji menší.

Ke správné funkčnosti komponenty počasí aktualizujte jádro na verzi 1.7.9.638.
Přidány nové návody
4.říjen 2011
Byl přidán nový návod "Použití jiného HTML editoru"
Powered by Visual PHP ™
© 2008 - 2010 E-VISION International, s.r.o.
O produktu | Technická podpora | Verze | Videoukázky | Manuály | Nabídka práce | Kontakt