Product | Technical support | Version | Video exhibits | Manuals | Job Search | Contact
English   menu-arrow-gray-horizontal.gif
Home > About the Product > License comparison
Related information
Search


Video demonstration
Drag&drop in the Visual PHP™ Environment

Latest video samples:
Job Search
Company
E-VISION International s.r.o.

is looking for PHP 5 and JavaScript programmers for long-term cooperation.




More information ...
Wrote about Visual PHP™
News by e-mail
Your e-mail

Visual PHP Recommends
For Visual PHP™
(for work in both the developer and the administration interface), we recommend using the Mozilla Firefox web browser, on the basis of which the whole software is developed because of stability, complying with the W3C standards and protecting elements of the browser.

Importing KML/KMZ and Displaying in Google Map

The KML format is an XML file containing GPS data that can be imported with ease into Google Earth. These files are exported from many programs that support GPS. Its extension is then the KMZ format that is de facto a ZIP file that contains multi-medium content in addition to a KML file and can be seen in case of new cameras with GPS, for example. In these instructions we will show you how to import KML and KMZ into Visual PHP™ and display the information by means of the Google Map component.

File Formats

First we will look at the KML file format. This file contains marks, paths and styles in which they are to be displayed.

A camera output KML file
<?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>
An output KML file from the Run.GPS mobile application
<?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>
A KMZ file is in effect a ZIP file, with a different extension only. This file contains icons for marks and, if necessary, photographs or videos. The structure looks as follows:
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
The icon directory contains icons for marks on a map and the photo directory photographs from such places. Where these images are to be displayed is defined in the track.kml file.

Database Tables

The database design looks as follows:

kmz Table

The kmz table will contain individual imports. The name will be saved in the name field and the centre coordinates for initial map displaying in the latitude and longitude fields.

kmz_placemarks Table 

Every map for individual exports will have a list of places that are displayed on the map by means of marks. There will be more marks; therefore, they will be saved in the kmz_placemarks table that is a detail table of the kmz table. The name field will contain the name of a place, the icon field will contain the icon for this mark imported into it and finally the latitude and longitude fields will contain coordinates. The relation to the master table is ensured by the parent field.

kmz_placemark_images Table 

As each place may contain more photographs, the kmz_placemark_images table will be a detail table of the kmz_placemarks table. The image field will then contain a photograph. The relation to the master table is also ensured by the parent field.

kmz_paths Table

Any import may also contain a path defined by a GPS coordinate list. So we save this data to the kmz_paths table. Every import and consequently a display on 1 map can contain more paths and that is why this table is a detail table of the kmz table. The relation to the master table is ensured by the parent field.

Importing a KMZ/KML File

The script we will show you can be used both in administration and for common visitors to the web front end. We will create a new script in the Presentation -> Scripts section and set tid=kmz_import for it. The script itself will then look as follows:
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"];
			
		// I’m extracting the latitude and longitude (we do not make use of altitudes in Google Maps – the file is intended for the Google Earth 3D application)
		$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"];
		
		// I will save to the database
		$kmzPlacemarkRecord = getTable("kmz_placemarks")->insertRecord($kmzPlacemarkRecord);

		// I will get all images from the description (they are stored as an HTML code there)
		$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];
				
					// I will save to the database
					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")
	{
		// I will create a working directory
		$tmpDir = PROJECTPATH."repository/temp/kmz_".createUUID()."/";
		_mkdir($tmpDir);

		// I will extract KMZ (this is de facto a ZIP archive)
		$Zip = createObject("Zip");
		$Zip->open($kmzFile);
		$Zip->extractTo($tmpDir);
	
		// I will open an XML file 
		$XML = createObject("XML");
		$XML->open($tmpDir."/track.kml");
	}
	else
	{
		// I will open an XML file 
		$XML = createObject("XML");
		$XML->open($kmzFile);
	}
	$XMLDocument = $XML->documentElement->getChildNodeByName("Document");

	// I will create a new master record in the database 
	$kmzRecord = array(
		"name" => $kmzName,
	);
	$kmzRecord = getTable("kmz")->insertRecord($kmzRecord);

	// I will upload all styles 
 	$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");
			// Colour is in the AABBGGRR format (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);
		}	
	}
	
	// I will calculate the centre of the map    
	$kmzRecord["latitude"] = $minLatitude+($maxLatitude-$minLatitude)/2;
	$kmzRecord["longitude"] = $minLongitude+($maxLongitude-$minLongitude)/2;
	
	getTable("kmz")->updateRecord($kmzRecord);
	
	echo "Import byl dokončen";
}
Zip objects to expand a file with the kmz extension and an XML object to open and read a KML file are used in the script.

Running an Import Script

To be able to call this script in administration, we will add to the Presentation -> Admin Menu a new item with a direct link:
scripts.php?tid=kmz_import
The list of imports can then be seen on the following URL at the front end:
http://www.vase-domena.cz/kmz.php

Source Codes

To implement this tutorial very quickly, you have available XML files that you can import into your presentation

Sample KMZ and KML Files

We have added sample KMZ files for testing and I have even gone jogging to get KML files :).

Examples of Map Outputs on WWW

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


Related Articles



NOTICE

Some properties published in this article can only be functional with the latest core version. If you have any older core version, we recommend you to update to the latest version.

Login
Free trial

for 30 days
Latest core version
Single Developer 1.7.9.680
january 20, 2012

Professional 1.7.9.680
january 20, 2012

Enterprise 1.7.9.680
january 20, 2012


Latest developer guide
Developer Guide 1.0.5
july 10, 2009 9:36:42 AM

Latest user guide
Administrator Guide 1.0.24
august 27, 2010 11:58:08 AM

Latest install script
install.php 1.9.22
april 12, 2012 6:02:40 PM

Comming up in next version
more ...

rss.gif
Support

Fotogalerie 5/10/2012
Section: Tvorba prezentací
Chyba v hromadné korespondenci, nelze odeslat příloha (nová verze 4/6/2012
Section: Bug reporty
AntiSpam obrázek 4/6/2012
Section: Programování
Chyba při opravách textů 4/4/2012
Section: Bug reporty
Admin může smazat Developera, je to ok? 3/27/2012
Section: Bug reporty
Mapa webu 3/19/2012
Section: Tvorba prezentací


rss.gif
News

Weather Component Update
november 18, 2011
Server weather.com decided to stop providing weather information for free and passed to the paid version (about $ 60 per month). For this reason, we were forced to modify the Weather component to pulling weather information from another data source, namely from the server www.worldweatheronline.com . This site also provides information about weather all around the world, but the amount of information is smaller than the original source.

For proper functionality of the Weather component please update core to version 1.7.9.638.
Added new tutorials
october 4, 2011
He added new instructions Using another HTML editor
Powered by Visual PHP ™
© 2008 - 2010 E-VISION International, s.r.o.
Product | Technical support | Version | Video exhibits | Manuals | Job Search | Contact