wikipoints/classes/Kml.php

173 lines
3.7 KiB
PHP

<?php
class Kml
{
private $kml = NULL;
private $waypoints = array();
private $tracks = array();
public function __construct($path)
{
$xml = substr($path, -4) == '.kmz' ? $this->getKmzContent($path) : file_get_contents($path);
$xml = str_replace(array('<gx:', '</gx:'), array('<gx', '</gx'), $xml);
$this->kml = new DOMDocument;
$this->kml->loadXML($xml);
foreach ($this->get($this->kml, 'Placemark') as $placemark) {
if ($this->has($placemark, 'Point')) {
$latlngs = $this->getCoords($placemark);
$this->waypoints[] = array(
'name' => trim($this->getValue($placemark, 'name')),
'description' => trim($this->getValue($placemark, 'description')),
'when' => date('c', strtotime($this->getValue($placemark, 'when'))),
'latlng' => $latlngs[0],
);
}
if ($this->has($placemark, 'LineString')) {
$this->tracks[] = array(
'name' => trim($this->getValue($placemark, 'name')),
'description' => trim($this->getValue($placemark, 'description')),
'latlng' => $this->getCoords($placemark),
);
}
if ($this->has($placemark, 'gxMultiTrack')) {
$this->tracks = $this->getTracksGX($placemark);
}
};
}
public function getName()
{
return $this->getValue($this->kml, 'name') ? strval($this->getValue($this->kml, 'name')) : 'Track KML';
}
public function getDescription()
{
return $this->getValue($this->kml, 'description') ? strval($this->getValue($this->kml, 'description')) : '';
}
public function getTime()
{
return $this->getValue($this->kml, 'when') ? date('c', strtotime($this->getValue($this->kml, 'when'))) : date('c');
}
public function getWaypoints()
{
return $this->waypoints;
}
public function getTracks()
{
return $this->tracks;
}
private function has($src, $tagName)
{
return $this->get($src, $tagName)->length > 0;
}
private function get($src, $tagName)
{
return $src->getElementsByTagName($tagName);
}
private function getValue($src, $tagName)
{
foreach ($src->getElementsByTagName($tagName) AS $value) {
return $value->nodeValue;
}
}
private function getCoords($src)
{
foreach ($src->getElementsByTagName('coordinates') AS $value) {
$result = array();
$coords = $value->nodeValue;
$coords = str_replace(array(" ", "\n", "\r", "\t"), ' ', $coords);
// multi-space
$pr = '(\s{2,})';
$rep = ' ';
$coords = preg_replace($pr, $rep, $coords);
$coords = explode(' ', trim($coords));
foreach ($coords as $coord) {
$tmp = explode(',', $coord);
$result[] = array(
'lat' => $tmp[1],
'lng' => $tmp[0],
'alt' => $tmp[2],
);
}
return $result;
}
return array();
}
private function getTracksGX($placemark)
{
$result = array();
foreach ($placemark->getElementsByTagName('gxTrack') AS $gxTrack) {
$track = array();
foreach ($gxTrack->getElementsByTagName('gxcoord') AS $value) {
$coords = $value->nodeValue;
$coords = str_replace(array(" ", "\n", "\r", "\t"), ' ', $coords);
// multi-space
$pr = '(\s{2,})';
$rep = ' ';
$coords = preg_replace($pr, $rep, $coords);
$tmp = explode(' ', trim($coords));
$track[] = array(
'lat' => $tmp[1],
'lng' => $tmp[0],
'alt' => $tmp[2],
);
}
$result[] = array(
'name' => '',
'description' => '',
'latlng' => $track,
);
}
return $result;
}
private function getKmzContent($path)
{
$zip = zip_open($path);
if (!$zip) {
App::error404();
}
$zip_entry = zip_read($zip);
if (zip_entry_name($zip_entry) != 'doc.kml') {
App::error404();
}
if (zip_entry_open($zip, $zip_entry, "r")) {
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
zip_entry_close($zip_entry);
zip_close($zip);
return $buf;
}
App::error404();
}
}