diff --git a/classes/Kml.php b/classes/Kml.php new file mode 100644 index 0000000..83e888e --- /dev/null +++ b/classes/Kml.php @@ -0,0 +1,108 @@ +kml = new DOMDocument; + $this->kml->loadXML(file_get_contents($path)); + + foreach ($this->get($this->kml, 'Placemark') as $placemark) { + if ($this->has($placemark, 'Point')) { + $this->waypoints[] = array( + 'name' => trim($this->getValue($placemark, 'name')), + 'description' => trim($this->getValue($placemark, 'description')), + 'when' => date('c', strtotime($this->getValue($placemark, 'when'))), + 'latlng' => $this->getCoords($placemark)[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), + ); + } + }; + } + + 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(); + } + + +} diff --git a/controllers/IndexController.php b/controllers/IndexController.php index 1d81ce5..6e19e0e 100644 --- a/controllers/IndexController.php +++ b/controllers/IndexController.php @@ -3,78 +3,6 @@ class IndexController extends Controller { - static function actionTest() - { - $gpxObject = simplexml_load_file('/tmp/2.gpx'); -// $gpxObject = simplexml_load_file('/tmp/doc(gpsvisualizer.com).gpx'); -// $gpxObject = simplexml_load_file('/tmp/1100.gpx'); - - $trip = array( - 'name' => isset($gpxObject->metadata->name) ? (string) $gpxObject->metadata->name : 'Track', - 'time' => isset($gpxObject->metadata->time) ? strtotime($gpxObject->metadata->time) : '', - ); - - $wayPoints = array(); - $tracks = array(); - $latlngs = array(); - - foreach ($gpxObject as $key => $block) { - if ($key == 'wpt') { - if (empty($block)) { - continue; - } - - $wayPoints[] = array( - 'lat' => floatval($block['lat']), - 'lng' => floatval($block['lon']), - 'time' => strtotime($block->time), - 'name' => (string) $block->name, - 'desc' => (string) $block->desc, - ); - } - - if ($key == 'trk') { -// print_r($block);die; - if (empty($block->trkseg)) { - continue; - } - - foreach ($block->trkseg as $trkpt) { - if ($trkpt) { - $trackPoints = array(); - $latlngs = array(); - foreach ($trkpt as $tpt) { -// $trackPoints[] = array( -// 'lat' => floatval($tpt['lat']), -// 'lng' => floatval($tpt['lon']), -// 'time' => isset($tpt->time) ? strtotime($tpt->time) : 0, -// 'ele' => isset($tpt->ele) ? floatval($tpt->ele) : 0, -// ); - $latlngs[] = array( - 'lat' => floatval($tpt['lat']), - 'lng' => floatval($tpt['lon']), - ); - } - } - } -// $tracks[] = $trackPoints; - $tracks[] = array( - 'name' => (string)$block->name, - 'length' => 0, - 'latlngs' => $latlngs - ); - } - } - - $trip['tracks'] = $tracks; -// $trip['latlngs'] = $latlngs; - - $trip['wayPoints'] = $wayPoints; - - - self::renderPartial('json.php', $trip); - } - /** * Действие по умолчанию */ diff --git a/controllers/TracksController.php b/controllers/TracksController.php index a1939d0..9db6286 100644 --- a/controllers/TracksController.php +++ b/controllers/TracksController.php @@ -44,7 +44,9 @@ class TracksController extends Controller $extension = strtolower($temp['extension']); $uploaddir = App::getBasedir() . 'tracks/'; - if ($extension !== 'gpx') { + $supportedExtensions = array(TrackFiles::FORMAT_GPX, TrackFiles::FORMAT_KML); + + if (!in_array(strtoupper($extension), $supportedExtensions)) { App::error404('Неизвестный тип'); } @@ -52,6 +54,7 @@ class TracksController extends Controller 'owner' => App::$user->id, 'name' => 'Трек ' . date('d-m-Y H:i:s'), 'filename' => $filename, + 'format' => strtoupper($extension), 'createdAt' => date('c'), )); @@ -60,7 +63,7 @@ class TracksController extends Controller App::error404(); } - App::redirect('/tracks/importgpx/id/'.$tmp->id); + App::redirect('/tracks/import/id/' . $tmp->id); } function actionGetFile() @@ -77,16 +80,13 @@ class TracksController extends Controller App::error404(); } - $temp = pathinfo($trackFile->filename); - $extension = strtolower($temp['extension']); - self::renderPartial('file.php', array( - 'filePath' => App::getBasedir(). 'tracks/track' . $id . '.' . $extension, + 'filePath' => App::getBasedir() . 'tracks/track' . $id . '.' . strtolower($trackFile->format), 'fileName' => $trackFile->filename, )); } - function actionImportgpx() + function actionImport() { $id = (int) App::getParam('id'); @@ -100,7 +100,24 @@ class TracksController extends Controller App::error404(); } - $gpxObject = simplexml_load_file(App::getBasedir() . 'tracks/track' . $trackFile->id . '.gpx'); + switch ($trackFile->format) { + case TrackFiles::FORMAT_GPX: + self::importGpx($trackFile); + break; + case TrackFiles::FORMAT_KML: + self::importKml($trackFile); + break; + default: + App::error404(); + break; + } + + App::redirect('/tracks'); + } + + private static function importGpx($trackFile) + { + $gpxObject = simplexml_load_file(App::getBasedir() . 'tracks/track' . $trackFile->id . '.' . strtolower($trackFile->format)); $trip = Trips::model()->add( array( @@ -202,8 +219,99 @@ class TracksController extends Controller $trackFile->wptCount = $wptCount; $trackFile->distance = $distance; $trackFile->save(); + } - App::redirect('/tracks'); + private static function importKml($trackFile) + { + $kml = new Kml(App::getBasedir() . 'tracks/track' . $trackFile->id . '.' . strtolower($trackFile->format)); + + + $trip = Trips::model()->add( + array( + 'name' => $kml->getName(), + 'createdAt' => $kml->getTime(), + 'owner' => App::$user->id, + 'distance' => 0, + 'description' => 'Трек сздан ' . date('d-m-Y H:i') . ' из файла ' . $trackFile->filename, + 'status' => Trips::STATUS_PRIVATE, + ) + ); + + $distance = 0; + $tracksCounter = 1; + $tracksCount = $tptCount = $wptCount = 0; + + foreach ($kml->getWaypoints() as $wpt) { + $wayPoint = WayPoints::model()->add( + array( + 'tripId' => $trip->id, + 'lat' => floatval($wpt['latlng']['lat']), + 'lng' => floatval($wpt['latlng']['lng']), + 'alt' => floatval($wpt['latlng']['alt']), + 'speed' => 0, + 'createdAt' => $wpt['when'], + 'name' => (string) $wpt['name'], + 'description' => (string) $wpt['description'], + ) + ); + + $wptCount++; + } + + foreach ($kml->getTracks() as $trackPart) { + if ($trackPart) { + $track = Tracks::model()->add( + array( + 'tripId' => $trip->id, + 'name' => $trackPart['name'] ? $trackPart['name'] : 'Фрагмент трека №' . $tracksCounter, + 'distance' => 0, + 'description' => $trackPart['description'], + ) + ); + + $distanceTmp = 0; + $prevPoint = array(); + $tracksCounter++; + $trackPoints = array(); + + foreach ($trackPart['latlng'] as $tpt) { + $trackPoint = TrackPoints::model()->add( + array( + 'trackId' => $track->id, + 'lat' => floatval($tpt['lat']), + 'lng' => floatval($tpt['lng']), + 'alt' => floatval($tpt['alt']), + 'createdAt' => 0, + 'speed' => 0, + ) + ); + + if ($prevPoint) { + $distanceTmp += Geo::distance($prevPoint, array('lat' => floatval($tpt['lat']), 'lng' => floatval($tpt['lng']))); + } + + $prevPoint = array( + 'lat' => floatval($tpt['lat']), + 'lng' => floatval($tpt['lng']), + ); + $tptCount++; + } + + $distance += $distanceTmp; + $track->distance = $distanceTmp; + $track->save(); + } + } + + + $trip->distance = $distance; + $trip->save(); + + $trackFile->tracksCount = count($kml->getTracks()); + $trackFile->tptCount = $tptCount; + $trackFile->wptCount = $wptCount; + $trackFile->distance = $distance; + $trackFile->save(); } } diff --git a/models/TrackFiles.php b/models/TrackFiles.php index 3cbf8e6..889520b 100644 --- a/models/TrackFiles.php +++ b/models/TrackFiles.php @@ -3,6 +3,10 @@ class TrackFiles extends Model { + const FORMAT_GPX = 'GPX'; + const FORMAT_KML = 'KML'; + const FORMAT_KMZ = 'KMZ'; + function __construct($fromArray = array()) { $this->_tableName_ = 'trackFiles'; diff --git a/views/tracks/files.php b/views/tracks/files.php index bdb4b63..c8a1d5f 100644 --- a/views/tracks/files.php +++ b/views/tracks/files.php @@ -12,7 +12,7 @@ if ($files) { - + diff --git a/views/tracks/index.php b/views/tracks/index.php index 6414ced..3bc7512 100644 --- a/views/tracks/index.php +++ b/views/tracks/index.php @@ -7,7 +7,7 @@