ADD импорт KML-файлов. ура
This commit is contained in:
parent
9684d17103
commit
775f405ea5
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Kml
|
||||||
|
{
|
||||||
|
|
||||||
|
private $kml = NULL;
|
||||||
|
private $waypoints = array();
|
||||||
|
private $tracks = array();
|
||||||
|
|
||||||
|
public function __construct($path)
|
||||||
|
{
|
||||||
|
$this->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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,78 +3,6 @@
|
||||||
class IndexController extends Controller
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Действие по умолчанию
|
* Действие по умолчанию
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,9 @@ class TracksController extends Controller
|
||||||
$extension = strtolower($temp['extension']);
|
$extension = strtolower($temp['extension']);
|
||||||
$uploaddir = App::getBasedir() . 'tracks/';
|
$uploaddir = App::getBasedir() . 'tracks/';
|
||||||
|
|
||||||
if ($extension !== 'gpx') {
|
$supportedExtensions = array(TrackFiles::FORMAT_GPX, TrackFiles::FORMAT_KML);
|
||||||
|
|
||||||
|
if (!in_array(strtoupper($extension), $supportedExtensions)) {
|
||||||
App::error404('Неизвестный тип');
|
App::error404('Неизвестный тип');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,6 +54,7 @@ class TracksController extends Controller
|
||||||
'owner' => App::$user->id,
|
'owner' => App::$user->id,
|
||||||
'name' => 'Трек ' . date('d-m-Y H:i:s'),
|
'name' => 'Трек ' . date('d-m-Y H:i:s'),
|
||||||
'filename' => $filename,
|
'filename' => $filename,
|
||||||
|
'format' => strtoupper($extension),
|
||||||
'createdAt' => date('c'),
|
'createdAt' => date('c'),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
@ -60,7 +63,7 @@ class TracksController extends Controller
|
||||||
App::error404();
|
App::error404();
|
||||||
}
|
}
|
||||||
|
|
||||||
App::redirect('/tracks/importgpx/id/'.$tmp->id);
|
App::redirect('/tracks/import/id/' . $tmp->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function actionGetFile()
|
function actionGetFile()
|
||||||
|
|
@ -77,16 +80,13 @@ class TracksController extends Controller
|
||||||
App::error404();
|
App::error404();
|
||||||
}
|
}
|
||||||
|
|
||||||
$temp = pathinfo($trackFile->filename);
|
|
||||||
$extension = strtolower($temp['extension']);
|
|
||||||
|
|
||||||
self::renderPartial('file.php', array(
|
self::renderPartial('file.php', array(
|
||||||
'filePath' => App::getBasedir(). 'tracks/track' . $id . '.' . $extension,
|
'filePath' => App::getBasedir() . 'tracks/track' . $id . '.' . strtolower($trackFile->format),
|
||||||
'fileName' => $trackFile->filename,
|
'fileName' => $trackFile->filename,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function actionImportgpx()
|
function actionImport()
|
||||||
{
|
{
|
||||||
$id = (int) App::getParam('id');
|
$id = (int) App::getParam('id');
|
||||||
|
|
||||||
|
|
@ -100,7 +100,24 @@ class TracksController extends Controller
|
||||||
App::error404();
|
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(
|
$trip = Trips::model()->add(
|
||||||
array(
|
array(
|
||||||
|
|
@ -202,8 +219,99 @@ class TracksController extends Controller
|
||||||
$trackFile->wptCount = $wptCount;
|
$trackFile->wptCount = $wptCount;
|
||||||
$trackFile->distance = $distance;
|
$trackFile->distance = $distance;
|
||||||
$trackFile->save();
|
$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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
class TrackFiles extends Model
|
class TrackFiles extends Model
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const FORMAT_GPX = 'GPX';
|
||||||
|
const FORMAT_KML = 'KML';
|
||||||
|
const FORMAT_KMZ = 'KMZ';
|
||||||
|
|
||||||
function __construct($fromArray = array())
|
function __construct($fromArray = array())
|
||||||
{
|
{
|
||||||
$this->_tableName_ = 'trackFiles';
|
$this->_tableName_ = 'trackFiles';
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ if ($files) {
|
||||||
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/tracks/importgpx/id/<?= $file->id ?>" title="Импортировать ещё раз">
|
<a href="/tracks/import/id/<?= $file->id ?>" title="Импортировать ещё раз">
|
||||||
<span class="glyphicon glyphicon-retweet" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-retweet" aria-hidden="true"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<form method="POST" action="/tracks/uploadfile/" enctype="multipart/form-data" class="form-inline">
|
<form method="POST" action="/tracks/uploadfile/" enctype="multipart/form-data" class="form-inline">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="uploadfile">Загрузить новый файл</label>
|
<label for="uploadfile">Загрузить новый файл</label>
|
||||||
<input type="file" name="file" id="uploadfile" class="form-control" accept=".gpx"/>
|
<input type="file" name="file" id="uploadfile" class="form-control" accept=".gpx, .kml"/>
|
||||||
<button type="submit" class="btn btn-success" title="Загрузить выбранный файл"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span></button>
|
<button type="submit" class="btn btn-success" title="Загрузить выбранный файл"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span></button>
|
||||||
|
|
||||||
<a href="/tracks/files" class="btn btn-default" title="Раздел с файлами треков"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a>
|
<a href="/tracks/files" class="btn btn-default" title="Раздел с файлами треков"><span class="glyphicon glyphicon-download" aria-hidden="true"></span></a>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue