Merge branch 'tracks'
This commit is contained in:
commit
d3d638831f
|
|
@ -23,5 +23,9 @@ public/photos/big/*.jpeg
|
||||||
public/photos/big/*.png
|
public/photos/big/*.png
|
||||||
public/photos/big/*.gif
|
public/photos/big/*.gif
|
||||||
|
|
||||||
|
tracks/*.gpx
|
||||||
|
tracks/*.kml
|
||||||
|
tracks/*.kmz
|
||||||
|
|
||||||
logs/*
|
logs/*
|
||||||
.idea
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Geo
|
||||||
|
{
|
||||||
|
|
||||||
|
static function distance($latlng1, $latlng2)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Convert degrees to radians.
|
||||||
|
$lat1 = deg2rad($latlng1['lat']);
|
||||||
|
$lng1 = deg2rad($latlng1['lng']);
|
||||||
|
$lat2 = deg2rad($latlng2['lat']);
|
||||||
|
$lng2 = deg2rad($latlng2['lng']);
|
||||||
|
|
||||||
|
// Calculate delta longitude and latitude.
|
||||||
|
$delta_lat = ($lat2 - $lat1);
|
||||||
|
$delta_lng = ($lng2 - $lng1);
|
||||||
|
|
||||||
|
return (6378137 * acos(cos($lat1) * cos($lat2) * cos($lng1 - $lng2) + sin($lat1) * sin($lat2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static function formatedDistance($distance)
|
||||||
|
{
|
||||||
|
return $distance > 1000 ? round($distance/1000, 2).'км' : round($distance).'м';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
<?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')) {
|
||||||
|
$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),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -204,30 +204,9 @@ abstract class Model
|
||||||
* @param array $values - ассоциативный массив соо значениями.
|
* @param array $values - ассоциативный массив соо значениями.
|
||||||
* @return object - id добавленной записи или false.
|
* @return object - id добавленной записи или false.
|
||||||
*/
|
*/
|
||||||
function add2($values)
|
|
||||||
{
|
|
||||||
$values = $this->_vals_;
|
|
||||||
unset($values[$this->_primaryKey_]);
|
|
||||||
|
|
||||||
$q = array();
|
|
||||||
foreach ($values as $val) {
|
|
||||||
$q[] = '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
var_dump('INSERT INTO `' . $this->_tableName_ . '` (`' . implode('`, `', array_keys($values)) . '`) VALUES (' . implode(', ', array_values($q)) . ') ');
|
|
||||||
die;
|
|
||||||
$res = App::DB()->prepare_query('INSERT INTO `' . $this->_tableName_ . '` (`' . implode('`, `', array_keys($values)) . '`) VALUES (' . implode(', ', array_values($q)) . ') ', self::arrayWithTypes($values));
|
|
||||||
|
|
||||||
if ($res) {
|
|
||||||
throw new Exception('MySQL error #' . $res->errno . ' - ' . $res->error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getByPK(App::DB()->insert_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function add($values)
|
function add($values)
|
||||||
{
|
{
|
||||||
$request = App::DB()->prepare('INSERT INTO ' . $this->_tableName_ . ' (' . implode(',', array_keys($values)) . ') values (:' . implode(', :', array_keys($values)) . ')');
|
$request = App::DB()->prepare('INSERT INTO `' . $this->_tableName_ . '` (`' . implode('`, `', array_keys($values)) . '`) values (:' . implode(', :', array_keys($values)) . ')');
|
||||||
if ($request->execute((array) $values)) {
|
if ($request->execute((array) $values)) {
|
||||||
return $this->getByPK(App::DB()->lastInsertId());
|
return $this->getByPK(App::DB()->lastInsertId());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class EdittrackController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
if (!App::$user->id) {
|
||||||
|
App::redirect('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionTrip()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
$trip = Trips::model()->getByPK($id);
|
||||||
|
|
||||||
|
if (empty($_POST['name']) || $trip->isEmpty() || $trip->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip->name = trim($_POST['name']);
|
||||||
|
$trip->description = trim($_POST['description']);
|
||||||
|
$trip->status = ($_POST['isPublic'] == 'true') ? Trips::STATUS_PUBLIC : Trips::STATUS_PRIVATE;
|
||||||
|
$trip->json = '';
|
||||||
|
$trip->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionTrack()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
$track = Tracks::model()->getByPK($id);
|
||||||
|
if (empty($_POST['name']) || $track->isEmpty()) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($track->tripId);
|
||||||
|
if ($trip->isEmpty() || $trip->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$track->name = trim($_POST['name']);
|
||||||
|
$track->description = trim($_POST['description']);
|
||||||
|
$track->save();
|
||||||
|
|
||||||
|
$trip->json = '';
|
||||||
|
$trip->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionDeletetrack()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
$track = Tracks::model()->getByPK($id);
|
||||||
|
if ($track->isEmpty()) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($track->tripId);
|
||||||
|
if ($trip->isEmpty() || $trip->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$track->delete($id);
|
||||||
|
|
||||||
|
$trip->json = '';
|
||||||
|
$trip->save();
|
||||||
|
|
||||||
|
App::redirect('/tracks/edit/id/'.$trip->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionWaypoint()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
$waypoint = WayPoints::model()->getByPK($id);
|
||||||
|
if (empty($_POST['name']) || $waypoint->isEmpty()) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($waypoint->tripId);
|
||||||
|
if ($trip->isEmpty() || $trip->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$waypoint->name = trim($_POST['name']);
|
||||||
|
$waypoint->description = trim($_POST['description']);
|
||||||
|
$waypoint->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionDeletewaypoint()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
$waypoint = WayPoints::model()->getByPK($id);
|
||||||
|
if ($waypoint->isEmpty()) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($waypoint->tripId);
|
||||||
|
if ($trip->isEmpty() || $trip->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$waypoint->delete($id);
|
||||||
|
|
||||||
|
$trip->json = '';
|
||||||
|
$trip->save();
|
||||||
|
|
||||||
|
App::redirect('/tracks/edit/id/'.$trip->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@ class IndexController extends Controller
|
||||||
self::addScript('/js/navigation.js?ver=' . App::getConfig('version'));
|
self::addScript('/js/navigation.js?ver=' . App::getConfig('version'));
|
||||||
self::addScript('/js/map.js?ver=' . App::getConfig('version'));
|
self::addScript('/js/map.js?ver=' . App::getConfig('version'));
|
||||||
self::addScript('/js/fotorama.js');
|
self::addScript('/js/fotorama.js');
|
||||||
|
self::addScript('/js/tracks.js?ver=' . App::getConfig('version'));
|
||||||
|
|
||||||
// self::addStyle('/css/style.css?ver=' . App::getConfig('version'));
|
// self::addStyle('/css/style.css?ver=' . App::getConfig('version'));
|
||||||
self::addStyle('/css/leaflet.css');
|
self::addStyle('/css/leaflet.css');
|
||||||
|
|
@ -40,12 +41,12 @@ class IndexController extends Controller
|
||||||
$category = Category::model()->getAll(array('order' => 'ord ASC'));
|
$category = Category::model()->getAll(array('order' => 'ord ASC'));
|
||||||
$categoryArray = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
|
$categoryArray = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
|
||||||
|
|
||||||
$routes = array();
|
$routes = $favorites = $tracks = array();
|
||||||
$favorites = array();
|
|
||||||
if (App::$user && App::$user->id) {
|
if (App::$user && App::$user->id) {
|
||||||
self::addVar('user', App::$user->id);
|
self::addVar('user', App::$user->id);
|
||||||
$routes = Route::model()->getByAuthor(App::$user->id);
|
$routes = Route::model()->getByAuthor(App::$user->id);
|
||||||
$favorites = Favorite::model()->getAllMy();
|
$favorites = Favorite::model()->getAllMy();
|
||||||
|
$tracks = Trips::model()->getAll(array('where' => '`owner` = ?'), array(App::$user->id));
|
||||||
} else {
|
} else {
|
||||||
self::addVar('user', '0');
|
self::addVar('user', '0');
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +94,7 @@ class IndexController extends Controller
|
||||||
'user' => App::$user,
|
'user' => App::$user,
|
||||||
'routes' => $routes,
|
'routes' => $routes,
|
||||||
'favorites' => $favorites,
|
'favorites' => $favorites,
|
||||||
|
'tracks' => $tracks,
|
||||||
'og' => $og,
|
'og' => $og,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -577,4 +577,200 @@ class JsonController extends Controller
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function actionTrack()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($id);
|
||||||
|
|
||||||
|
if ($trip->isEmpty() || ($trip->status != Trips::STATUS_PUBLIC && $trip->owner != App::$user->id)) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($trip->json) {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
print $trip->json;
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = array(
|
||||||
|
'name' => $trip->name,
|
||||||
|
'time' => $trip->createdAt,
|
||||||
|
);
|
||||||
|
|
||||||
|
$resWayPoints = array();
|
||||||
|
$resTracks = array();
|
||||||
|
$resLatlngs = array();
|
||||||
|
|
||||||
|
|
||||||
|
$wayPoints = WayPoints::model()->getAll(array('where' => '`tripId` = ?'), array($trip->id));
|
||||||
|
if ($wayPoints) {
|
||||||
|
foreach ($wayPoints as $block) {
|
||||||
|
$resWayPoints[] = array(
|
||||||
|
'lat' => floatval($block->lat),
|
||||||
|
'lng' => floatval($block->lng),
|
||||||
|
'time' => strtotime($block->createdAt),
|
||||||
|
'name' => (string) $block->name,
|
||||||
|
'description' => nl2br($block->description),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$tracks = Tracks::model()->getAll(array('where' => '`tripId` = ?'), array($trip->id));
|
||||||
|
if ($tracks) {
|
||||||
|
foreach ($tracks as $track) {
|
||||||
|
$resLatlngs = array();
|
||||||
|
$trackPoints = TrackPoints::model()->getAll(array('where' => '`trackId` = ?'), array($track->id));
|
||||||
|
if ($trackPoints) {
|
||||||
|
foreach ($trackPoints as $trackPoint) {
|
||||||
|
$resLatlngs[] = array(
|
||||||
|
'lat' => $trackPoint->lat,
|
||||||
|
'lng' => $trackPoint->lng,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$resTracks[] = array(
|
||||||
|
'name' => (string) $track->name,
|
||||||
|
'length' => 0,
|
||||||
|
'latlngs' => $resLatlngs,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$res['wayPoints'] = $resWayPoints;
|
||||||
|
$res['tracks'] = $resTracks;
|
||||||
|
|
||||||
|
|
||||||
|
$json = self::renderPartial('json.php', $res, TRUE);
|
||||||
|
|
||||||
|
$trip->json = $json;
|
||||||
|
$trip->save();
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
print $json;
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static function actionSimpletrack()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($id);
|
||||||
|
|
||||||
|
if ($trip->isEmpty() || ($trip->status != Trips::STATUS_PUBLIC && $trip->owner != App::$user->id)) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = array(
|
||||||
|
'name' => $trip->name,
|
||||||
|
'time' => $trip->createdAt,
|
||||||
|
);
|
||||||
|
|
||||||
|
$resWayPoints = array();
|
||||||
|
$resTracks = array();
|
||||||
|
$resLatlngs = array();
|
||||||
|
$totCnt = 0;
|
||||||
|
|
||||||
|
|
||||||
|
$wayPoints = WayPoints::model()->getAll(array('where' => '`tripId` = ?'), array($trip->id));
|
||||||
|
if ($wayPoints) {
|
||||||
|
foreach ($wayPoints as $block) {
|
||||||
|
$resWayPoints[] = array(
|
||||||
|
'lat' => floatval($block->lat),
|
||||||
|
'lng' => floatval($block->lng),
|
||||||
|
'time' => strtotime($block->createdAt),
|
||||||
|
'name' => (string) $block->name,
|
||||||
|
'description' => nl2br($block->description),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$tracks = Tracks::model()->getAll(array('where' => '`tripId` = ?'), array($trip->id));
|
||||||
|
if ($tracks) {
|
||||||
|
foreach ($tracks as $track) {
|
||||||
|
$resLatlngs = array();
|
||||||
|
$trackPoints = TrackPoints::model()->getAll(array('where' => '`trackId` = ?', 'noKeys' => TRUE), array($track->id));
|
||||||
|
if ($trackPoints) {
|
||||||
|
for ($index = 0; $index < count($trackPoints); $index++) {
|
||||||
|
|
||||||
|
$trackPoint = $trackPoints[$index];
|
||||||
|
|
||||||
|
if ($index > 2 && $index < count($trackPoints)-2) {
|
||||||
|
|
||||||
|
$nextPoint = $trackPoints[$index+1];
|
||||||
|
$nextPoint = array(
|
||||||
|
'lat' => $nextPoint->lat,
|
||||||
|
'lng' => $nextPoint->lng,
|
||||||
|
);
|
||||||
|
|
||||||
|
$distance1 = Geo::distance($prevPoint, array('lat' => $trackPoint->lat, 'lng' => $trackPoint->lng));
|
||||||
|
|
||||||
|
if ($distance1 < 30) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// $distance2 = Geo::distance($nextPoint, array('lat' => $trackPoint->lat, 'lng' => $trackPoint->lng));
|
||||||
|
// $distance3 = Geo::distance($prevPoint, $nextPoint);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (($distance3 / ($distance1+$distance2)) > 0.982) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
$prevPoint = $trackPoints[$index];
|
||||||
|
$prevPoint = array(
|
||||||
|
'lat' => $prevPoint->lat,
|
||||||
|
'lng' => $prevPoint->lng,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$resLatlngs[] = array(
|
||||||
|
'lat' => $trackPoint->lat,
|
||||||
|
'lng' => $trackPoint->lng,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// die;
|
||||||
|
}
|
||||||
|
|
||||||
|
$totCnt += count($resLatlngs);
|
||||||
|
$resTracks[] = array(
|
||||||
|
'name' => (string) $track->name,
|
||||||
|
'length' => 0,
|
||||||
|
'latlngs' => $resLatlngs,
|
||||||
|
'points' => count($resLatlngs),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$res['wayPoints'] = $resWayPoints;
|
||||||
|
$res['tracks'] = $resTracks;
|
||||||
|
$res['totCnt'] = $totCnt;
|
||||||
|
|
||||||
|
|
||||||
|
$json = self::renderPartial('json.php', $res, TRUE);
|
||||||
|
|
||||||
|
$trip->json = $json;
|
||||||
|
$trip->save();
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
print $json;
|
||||||
|
die;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,340 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class TracksController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
if (!App::$user->id) {
|
||||||
|
App::redirect('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$layout = 'layouts/page.php';
|
||||||
|
self::addStyle('/css/style.css?ver=' . App::getConfig('version'));
|
||||||
|
self::addStyle('/css/pageStyle.css?ver=' . App::getConfig('version'));
|
||||||
|
self::addScript('/js/jquery-2.1.0.min.js');
|
||||||
|
self::addScript('/js/jquery-ui-1.10.4.custom.min.js');
|
||||||
|
self::addScript('/js/bootstrap.min.js');
|
||||||
|
self::addStyle('/css/bootstrap.min.css');
|
||||||
|
self::addStyle('/css/bootstrap-theme.min.css');
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionIndex()
|
||||||
|
{
|
||||||
|
$trips = Trips::model()->getAll(array('where' => '`owner` = ?'), array(App::$user->id));
|
||||||
|
|
||||||
|
self::render('/tracks/index.php', array(
|
||||||
|
'trips' => $trips,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionEdit()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip = Trips::model()->getByPK($id);
|
||||||
|
|
||||||
|
if ($trip->isEmpty() || $trip->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
self::render('/tracks/edit.php', array(
|
||||||
|
'trip' => $trip,
|
||||||
|
'tracks' => Tracks::model()->getAll(array('where' => '`tripId` = ' . $trip->id)),
|
||||||
|
'waypoints' => WayPoints::model()->getAll(array('where' => '`tripId` = ' . $trip->id)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function actionFiles()
|
||||||
|
{
|
||||||
|
$files = TrackFiles::model()->getAll(array('where' => '`owner` = :owner'), array('owner' => App::$user->id));
|
||||||
|
|
||||||
|
self::render('/tracks/files.php', array(
|
||||||
|
'files' => $files,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionUploadfile()
|
||||||
|
{
|
||||||
|
$temp = pathinfo($_FILES['file']['name']);
|
||||||
|
$filename = $_FILES['file']['name'];
|
||||||
|
$extension = strtolower($temp['extension']);
|
||||||
|
$uploaddir = App::getBasedir() . 'tracks/';
|
||||||
|
|
||||||
|
$supportedExtensions = array(TrackFiles::FORMAT_GPX, TrackFiles::FORMAT_KML, TrackFiles::FORMAT_KMZ);
|
||||||
|
|
||||||
|
if (!in_array(strtoupper($extension), $supportedExtensions)) {
|
||||||
|
App::error404('Неизвестный тип');
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp = TrackFiles::model()->add(array(
|
||||||
|
'owner' => App::$user->id,
|
||||||
|
'name' => 'Трек ' . date('d-m-Y H:i:s'),
|
||||||
|
'filename' => $filename,
|
||||||
|
'format' => strtoupper($extension),
|
||||||
|
'createdAt' => date('c'),
|
||||||
|
));
|
||||||
|
|
||||||
|
$newName = 'track' . $tmp->id . '.' . $extension;
|
||||||
|
if (!move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir . $newName)) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
App::redirect('/tracks/import/id/' . $tmp->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionGetFile()
|
||||||
|
{
|
||||||
|
$id = intval(App::getParam('id'));
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trackFile = TrackFiles::model()->getByPK($id);
|
||||||
|
|
||||||
|
if ($trackFile->isEmpty() || $trackFile->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
self::renderPartial('file.php', array(
|
||||||
|
'filePath' => App::getBasedir() . 'tracks/track' . $id . '.' . strtolower($trackFile->format),
|
||||||
|
'fileName' => $trackFile->filename,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionImport()
|
||||||
|
{
|
||||||
|
$id = (int) App::getParam('id');
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
$trackFile = TrackFiles::model()->getByPK($id);
|
||||||
|
|
||||||
|
if ($trackFile->isEmpty() || $trackFile->owner != App::$user->id) {
|
||||||
|
App::error404();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($trackFile->format) {
|
||||||
|
case TrackFiles::FORMAT_GPX:
|
||||||
|
self::importGpx($trackFile);
|
||||||
|
break;
|
||||||
|
case TrackFiles::FORMAT_KML:
|
||||||
|
case TrackFiles::FORMAT_KMZ:
|
||||||
|
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(
|
||||||
|
'name' => isset($gpxObject->metadata->name) ? (string) $gpxObject->metadata->name : 'Track',
|
||||||
|
'createdAt' => isset($gpxObject->metadata->time) ? $gpxObject->metadata->time : date('c'),
|
||||||
|
'owner' => App::$user->id,
|
||||||
|
'distance' => 0,
|
||||||
|
'description' => 'Трек создан ' . date('d-m-Y H:i') . ' из файла ' . $trackFile->filename,
|
||||||
|
'status' => Trips::STATUS_PRIVATE,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$distance = 0;
|
||||||
|
$wayPoints = array();
|
||||||
|
$tracks = array();
|
||||||
|
$latlngs = array();
|
||||||
|
$tracksCounter = 1;
|
||||||
|
$tracksCount = $tptCount = $wptCount = 0;
|
||||||
|
|
||||||
|
foreach ($gpxObject as $key => $block) {
|
||||||
|
if ($key == 'wpt') {
|
||||||
|
if (empty($block)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wayPoint = WayPoints::model()->add(
|
||||||
|
array(
|
||||||
|
'tripId' => $trip->id,
|
||||||
|
'lat' => floatval($block['lat']),
|
||||||
|
'lng' => floatval($block['lon']),
|
||||||
|
'alt' => 0,
|
||||||
|
'speed' => 0,
|
||||||
|
'createdAt' => $block->time,
|
||||||
|
'name' => (string) $block->name,
|
||||||
|
'description' => (string) $block->desc,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$wptCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($key == 'trk') {
|
||||||
|
if (empty($block->trkseg)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($block->trkseg as $trkpt) {
|
||||||
|
if ($trkpt) {
|
||||||
|
$track = Tracks::model()->add(
|
||||||
|
array(
|
||||||
|
'tripId' => $trip->id,
|
||||||
|
'name' => (string) $block->name ? (string) $block->name : 'Фрагмент трека №' . $tracksCounter,
|
||||||
|
'distance' => 0,
|
||||||
|
'description' => '',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$distanceTmp = 0;
|
||||||
|
$prevPoint = array();
|
||||||
|
$tracksCounter++;
|
||||||
|
$trackPoints = array();
|
||||||
|
|
||||||
|
foreach ($trkpt as $tpt) {
|
||||||
|
$trackPoint = TrackPoints::model()->add(
|
||||||
|
array(
|
||||||
|
'trackId' => $track->id,
|
||||||
|
'lat' => floatval($tpt['lat']),
|
||||||
|
'lng' => floatval($tpt['lon']),
|
||||||
|
'alt' => isset($tpt->ele) ? floatval($tpt->ele) : 0,
|
||||||
|
'createdAt' => isset($tpt->time) ? $tpt->time : date('c'),
|
||||||
|
'speed' => 0,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($prevPoint) {
|
||||||
|
$distanceTmp += Geo::distance($prevPoint, array('lat' => floatval($tpt['lat']), 'lng' => floatval($tpt['lon'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
$prevPoint = array(
|
||||||
|
'lat' => floatval($tpt['lat']),
|
||||||
|
'lng' => floatval($tpt['lon']),
|
||||||
|
);
|
||||||
|
$tptCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$distance += $distanceTmp;
|
||||||
|
$track->distance = $distanceTmp;
|
||||||
|
$track->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tracksCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$trip->distance = $distance;
|
||||||
|
$trip->save();
|
||||||
|
|
||||||
|
$trackFile->tracksCount = $tracksCount;
|
||||||
|
$trackFile->tptCount = $tptCount;
|
||||||
|
$trackFile->wptCount = $wptCount;
|
||||||
|
$trackFile->distance = $distance;
|
||||||
|
$trackFile->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class TrackFiles extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
const FORMAT_GPX = 'GPX';
|
||||||
|
const FORMAT_KML = 'KML';
|
||||||
|
const FORMAT_KMZ = 'KMZ';
|
||||||
|
|
||||||
|
function __construct($fromArray = array())
|
||||||
|
{
|
||||||
|
$this->_tableName_ = 'trackFiles';
|
||||||
|
parent::__construct($fromArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function model()
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class TrackPoints extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
function __construct($fromArray = array())
|
||||||
|
{
|
||||||
|
$this->_tableName_ = 'trackPoints';
|
||||||
|
parent::__construct($fromArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function model()
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Tracks extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
function __construct($fromArray = array())
|
||||||
|
{
|
||||||
|
$this->_tableName_ = 'tracks';
|
||||||
|
parent::__construct($fromArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function model()
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
function distance()
|
||||||
|
{
|
||||||
|
return Geo::formatedDistance($this->distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Trips extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
const STATUS_PRIVATE = 'PRIVATE';
|
||||||
|
const STATUS_PUBLIC = 'PUBLIC';
|
||||||
|
const STATUS_DELETED = 'DELETED';
|
||||||
|
|
||||||
|
function __construct($fromArray = array())
|
||||||
|
{
|
||||||
|
$this->_tableName_ = 'trips';
|
||||||
|
parent::__construct($fromArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function model()
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
function distance()
|
||||||
|
{
|
||||||
|
return Geo::formatedDistance($this->distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class WayPoints extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
function __construct($fromArray = array())
|
||||||
|
{
|
||||||
|
$this->_tableName_ = 'wayPoints';
|
||||||
|
parent::__construct($fromArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function model()
|
||||||
|
{
|
||||||
|
return new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -37,6 +37,13 @@ categories.simplepoint = L.icon({
|
||||||
popupAnchor: [7, 7]
|
popupAnchor: [7, 7]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
categories.marker = L.icon({
|
||||||
|
iconUrl: '/ico/marker.png',
|
||||||
|
iconSize: [32, 37],
|
||||||
|
iconAnchor: [16, 37],
|
||||||
|
popupAnchor: [0, 1]
|
||||||
|
});
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
if (pointLat == pointLng) {
|
if (pointLat == pointLng) {
|
||||||
|
|
@ -234,6 +241,10 @@ function initPoints(useBounds)
|
||||||
.setContent('Координаты: N°' + getURLParameter('lat').substring(0,8) + ' E°' + getURLParameter('lng').substring(0,8))
|
.setContent('Координаты: N°' + getURLParameter('lat').substring(0,8) + ' E°' + getURLParameter('lng').substring(0,8))
|
||||||
.openOn(myMap);
|
.openOn(myMap);
|
||||||
}
|
}
|
||||||
|
} else if (getURLParameter('track') != 'null')
|
||||||
|
{
|
||||||
|
showTrack(getURLParameter('track'))
|
||||||
|
$('#trackShowHide' + getURLParameter('track')).prop('checked', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -256,12 +267,13 @@ function loadPointsInBounds()
|
||||||
bounds: bounds
|
bounds: bounds
|
||||||
},
|
},
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
for(var i=0; i < data.length; i++) {
|
if (typeof (data) != 'undefined' && data.length > 0) {
|
||||||
if (typeof points[data[i].id] == 'undefined') {
|
for(var i=0; i < data.length; i++) {
|
||||||
markers.addLayer(constructPoint(data[i]));
|
if (typeof points[data[i].id] == 'undefined') {
|
||||||
|
markers.addLayer(constructPoint(data[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myMap.addLayer(markers);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
var trips = new Object;
|
||||||
|
|
||||||
|
function showHideTrack(id)
|
||||||
|
{
|
||||||
|
if($('#trackShowHide'+id).prop('checked')) {
|
||||||
|
showTrack(id)
|
||||||
|
} else {
|
||||||
|
hideTrack(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTrack(id)
|
||||||
|
{
|
||||||
|
if (typeof (trips[id]) == 'undefined') {
|
||||||
|
loadTrack(id)
|
||||||
|
} else {
|
||||||
|
if (trips[id].status != 'show') {
|
||||||
|
trips[id].addTo(myMap)
|
||||||
|
trips[id].status = 'show';
|
||||||
|
}
|
||||||
|
|
||||||
|
myMap.fitBounds(trips[id].getBounds());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideTrack(id)
|
||||||
|
{
|
||||||
|
if (typeof (trips[id]) == 'undefined') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (trips[id].status == 'show') {
|
||||||
|
myMap.removeLayer(trips[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
trips[id].status = 'hide';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadTrack(id)
|
||||||
|
{
|
||||||
|
colors = ['#ff0000', '#ff8e00', '#ff0', '#0f0', '#003cff', '#ff00ad'];
|
||||||
|
colorIndex = 0;
|
||||||
|
tracks = new Array();
|
||||||
|
markers = new Array();
|
||||||
|
$.ajax({
|
||||||
|
url: "/json/track/id/" + id,
|
||||||
|
success: function (data) {
|
||||||
|
trips[id] = L.featureGroup();
|
||||||
|
|
||||||
|
if (typeof (data.tracks) != 'undefined') {
|
||||||
|
for (var i = 0; i < data.tracks.length; i++) {
|
||||||
|
color = colors[colorIndex];
|
||||||
|
colorIndex = (colorIndex == colors.length-1) ? 0 : colorIndex+1;
|
||||||
|
|
||||||
|
tracks[i] = L.polyline(data.tracks[i].latlngs, {color: color, width: 4, opacity: 0.8});
|
||||||
|
tracks[i].bindPopup(data.tracks[i].name);
|
||||||
|
trips[id].addLayer(tracks[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof (data.wayPoints) != 'undefined') {
|
||||||
|
for (var i = 0; i < data.wayPoints.length; i++) {
|
||||||
|
markers[i] = L.marker([data.wayPoints[i]['lat'], data.wayPoints[i]['lng']], {icon: categories.marker, title: data.wayPoints[i]['name']})
|
||||||
|
markers[i].bindPopup('<b>' + data.wayPoints[i]['name'] + '</b><br/>' + data.wayPoints[i]['description']);
|
||||||
|
trips[id].addLayer(markers[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showTrack(id)
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
alert('Не удалось загрузить трек. Возможно это приватный трек и вы не его владелец.')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSimpleTrack(id)
|
||||||
|
{
|
||||||
|
colors = ['red', 'green', 'blue', 'orange'];
|
||||||
|
colors = ['red'];
|
||||||
|
colorIndex = 0;
|
||||||
|
tracks = new Array();
|
||||||
|
markers = new Array();
|
||||||
|
$.ajax({
|
||||||
|
url: "/json/simpletrack/id/" + id,
|
||||||
|
success: function (data) {
|
||||||
|
trips[id] = L.featureGroup();
|
||||||
|
|
||||||
|
if (typeof (data.tracks) != 'undefined') {
|
||||||
|
for (var i = 0; i < data.tracks.length; i++) {
|
||||||
|
color = colors[colorIndex];
|
||||||
|
colorIndex = (colorIndex == colors.length-1) ? 0 : colorIndex+1;
|
||||||
|
|
||||||
|
tracks[i] = L.polyline(data.tracks[i].latlngs, {color: color, width: 4, opacity: 0.8});
|
||||||
|
tracks[i].bindPopup(data.tracks[i].name);
|
||||||
|
trips[id].addLayer(tracks[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof (data.wayPoints) != 'undefined') {
|
||||||
|
for (var i = 0; i < data.wayPoints.length; i++) {
|
||||||
|
markers[i] = L.marker([data.wayPoints[i]['lat'], data.wayPoints[i]['lng']], {icon: categories.marker, title: data.wayPoints[i]['name']})
|
||||||
|
markers[i].bindPopup('<b>' + data.wayPoints[i]['name'] + '</b><br/>' + data.wayPoints[i]['description']);
|
||||||
|
trips[id].addLayer(markers[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showTrack(id)
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
alert('Не удалось загрузить трек. Возможно это приватный трек и вы не его владелец.')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (file_exists($filePath)) {
|
||||||
|
if (ob_get_level()) {
|
||||||
|
ob_end_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($fileName)) {
|
||||||
|
$fileName = basename($filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Connection: close');
|
||||||
|
header('Content-Type: application/octet-stream');
|
||||||
|
header('Content-Disposition: attachment; filename=' . $fileName);
|
||||||
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
header('Cache-Control: must-revalidate');
|
||||||
|
// header('Transfer-Encoding: chunked');
|
||||||
|
// Читаем файл и отправляем его пользователю
|
||||||
|
readfile($filePath);
|
||||||
|
}
|
||||||
|
|
@ -18,8 +18,9 @@ if (App::$user) {
|
||||||
|
|
||||||
<?php if (App::$user): ?>
|
<?php if (App::$user): ?>
|
||||||
<div class="glyphicon _t" id="addPointButton" title="Добавить точку" onclick="<?= $addWithoutConfirm ? 'activateAddPoint()' : 'showPointagreement()'; ?>"><img src="/img/buttons/addPoint.png" style="margin-top: -10px; height: 30px;" /></div>
|
<div class="glyphicon _t" id="addPointButton" title="Добавить точку" onclick="<?= $addWithoutConfirm ? 'activateAddPoint()' : 'showPointagreement()'; ?>"><img src="/img/buttons/addPoint.png" style="margin-top: -10px; height: 30px;" /></div>
|
||||||
<div class="glyphicon glyphicon-star _c boxButtonFavorites" onclick="openBox('Favorites')" title="Хочу посетить"></div>
|
<div class="glyphicon _c glyphicon-star boxButtonFavorites" onclick="openBox('Favorites')" title="Хочу посетить"></div>
|
||||||
<div class="glyphicon _b glyphicon-cloud-download boxButtonRoutes" onclick="openBox('Routes')" title="Мои маршруты"></div>
|
<div class="glyphicon _c glyphicon-cloud-download boxButtonRoutes" onclick="openBox('Routes')" title="Мои маршруты"></div>
|
||||||
|
<div class="glyphicon _b glyphicon-road boxButtonTracks" onclick="openBox('Tracks')" title="Мои маршруты"></div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="glyphicon" id="addPointButton" onclick="$('#loginModal').modal('show');" title="Добавить точку"><img src="/img/buttons/addPoint.png" style="margin-top: -10px; height: 30px;" /></div>
|
<div class="glyphicon" id="addPointButton" onclick="$('#loginModal').modal('show');" title="Добавить точку"><img src="/img/buttons/addPoint.png" style="margin-top: -10px; height: 30px;" /></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
@ -103,6 +104,32 @@ if (App::$user) {
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="boxTracks">
|
||||||
|
<h3>
|
||||||
|
Мои треки
|
||||||
|
<a href="/tracks/" title="Управление треками"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span></a>
|
||||||
|
</h3>
|
||||||
|
<hr/>
|
||||||
|
<div id="tracks">
|
||||||
|
<?php if ($tracks): ?>
|
||||||
|
<?php foreach ($tracks as $track) : ?>
|
||||||
|
<div style="border-bottom: solid 1px #CCC">
|
||||||
|
<input type="checkbox" id="trackShowHide<?= $track->id ?>" onchange="showHideTrack(<?= $track->id ?>)" />
|
||||||
|
<?= $track->name ?>
|
||||||
|
<b><?= $track->distance(); ?></b>
|
||||||
|
<?php if($track->status == Trips::STATUS_PUBLIC):?>
|
||||||
|
<a href="/?track=<?= $track->id ?>" title="Ссылка на трек. <?="\n"?>[клик правой кнопкой -> копировать адрес]">
|
||||||
|
<span class="glyphicon glyphicon-link" aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
<?php endif;?>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
У вас пока нет сохраненных треков.
|
||||||
|
Загляните в раздел управления треками <a href="/tracks/" title="Управление треками"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span></a>.
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<?= App::$user ? '' : self::renderPartial('modals/login.php', null, true) ?>
|
<?= App::$user ? '' : self::renderPartial('modals/login.php', null, true) ?>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
<a href="/tracks/" class="btn btn-success pull-right">
|
||||||
|
<span class="glyphicon glyphicon-home" aria-hidden="true"></span>
|
||||||
|
Выйти из редактора
|
||||||
|
</a>
|
||||||
|
<a href="/?track=<?= $trip->id ?>" class="btn btn-success pull-right"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span></a>
|
||||||
|
<h3 onclick="$('#tripBlock').toggle(100)" style="cursor: pointer;">Свойства трека</h3>
|
||||||
|
<form onfocusout="saveChangesTrip()" id="tripBlock">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="tripName">Название трека</label>
|
||||||
|
<input type="text" class="form-control" id="tripName" placeholder="Великолепное путешествие <?= date('Y') ?>" value="<?= $trip->name ?>">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="tripDescription">Описание Трека</label>
|
||||||
|
<input type="text" class="form-control" id="tripDescription" placeholder="Это было незабываемое путешествие!..." value="<?= $trip->description ?>">
|
||||||
|
</div>
|
||||||
|
<a href="/edittrack/delete/id/<?= $trip->id ?>" class="btn btn-danger pull-right" onclick="return confirm('Вы уверены, что хотите удалить трек?')">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||||
|
Удалить трек
|
||||||
|
</a>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="tripIsPublic" <?= ($trip->status == Trips::STATUS_PUBLIC) ? 'checked="checked"' : '' ?>> Публичный трек (его могут видеть другие пользователи)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span id="tripSavedOK" style="color: #999; display: none;">изменения сохранены...</span>
|
||||||
|
<span id="tripSavedError" style="color: #900; display: none;">при сохранении возникла ошибка!</span>
|
||||||
|
<br/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php if ($tracks): ?>
|
||||||
|
<h3 onclick="$('#tracksBlock').toggle()" style="cursor: pointer;">Фрагменты трека (<?= count($tracks) ?>)</h3>
|
||||||
|
<div id="tracksBlock" style="display: none;">
|
||||||
|
<!--<hr/>-->
|
||||||
|
<?php foreach ($tracks as $track): ?>
|
||||||
|
<form onfocusout="saveChangesTrack(<?= $track->id ?>)" class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<div style="font-size: 20px" class="col-sm-1"><?= $track->distance() ?></div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<input type="text" class="form-control" id="trackName<?= $track->id ?>" placeholder="День №__" value="<?= $track->name ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="trackDescription<?= $track->id ?>" placeholder="В этот день..." value="<?= $track->description ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<a href="/edittrack/deletetrack/id/<?= $track->id ?>" class="btn btn-danger" onclick="return confirm('Вы уверены, что хотите удалить фрагмент трека?')"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!--<hr/>-->
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<span id="trackSavedOK" style="color: #999; display: none;">изменения сохранены...</span>
|
||||||
|
<span id="trackSavedError" style="color: #900; display: none;">при сохранении возникла ошибка!</span>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($waypoints): ?>
|
||||||
|
<h3 onclick="$('#waypointsBlock').toggle()" style="cursor: pointer;">Путевые точки (<?= count($waypoints) ?>)</h3>
|
||||||
|
<div id="waypointsBlock" style="display: none;">
|
||||||
|
<!--<hr/>-->
|
||||||
|
<?php foreach ($waypoints as $waypoint): ?>
|
||||||
|
<form onfocusout="saveChangesWaypoint(<?= $waypoint->id ?>)" class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<input type="text" class="form-control" id="waypointName<?= $waypoint->id ?>" placeholder="А здесь..." value="<?= $waypoint->name ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="waypointDescription<?= $waypoint->id ?>" placeholder="Здесь очень..." value="<?= $waypoint->description ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<a href="/edittrack/deletewaypoint/id/<?= $waypoint->id ?>" class="btn btn-danger" onclick="return confirm('Вы уверены, что хотите удалить путевую точку?')"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!--<hr/>-->
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<span id="waypointSavedOK" style="color: #999; display: none;">изменения сохранены...</span>
|
||||||
|
<span id="waypointSavedError" style="color: #900; display: none;">при сохранении возникла ошибка!</span>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<script lang="javascript">
|
||||||
|
function saveChangesTrip()
|
||||||
|
{
|
||||||
|
$('#tripSavedOK').hide();
|
||||||
|
$('#tripSavedError').hide();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/edittrack/trip/id/<?= $trip->id ?>",
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
name: $('#tripName').val(),
|
||||||
|
description: $('#tripDescription').val(),
|
||||||
|
isPublic: $('#tripIsPublic').prop('checked')
|
||||||
|
},
|
||||||
|
success: function (data) {
|
||||||
|
$('#tripSavedOK').show();
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#tripSavedOK').fadeOut(300);
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
$('#tripSavedError').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveChangesTrack(id)
|
||||||
|
{
|
||||||
|
$('#trackSavedOK').hide();
|
||||||
|
$('#trackSavedError').hide();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/edittrack/track/id/" + id,
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
name: $('#trackName' + id).val(),
|
||||||
|
description: $('#trackDescription' + id).val()
|
||||||
|
},
|
||||||
|
success: function (data) {
|
||||||
|
$('#trackSavedOK').show();
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#trackSavedOK').fadeOut(300);
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
$('#trackSavedError').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveChangesWaypoint(id)
|
||||||
|
{
|
||||||
|
$('#waypointSavedOK').hide();
|
||||||
|
$('#waypointSavedError').hide();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/edittrack/waypoint/id/" + id,
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
name: $('#waypointName' + id).val(),
|
||||||
|
description: $('#waypointDescription' + id).val()
|
||||||
|
},
|
||||||
|
success: function (data) {
|
||||||
|
$('#waypointSavedOK').show();
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#waypointSavedOK').fadeOut(300);
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
$('#waypointSavedError').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<h3>Ваши исходные файлы с треками</h3>
|
||||||
|
<a href="/tracks/">← вернуться к трекам</a>
|
||||||
|
<hr/>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ($files) {
|
||||||
|
foreach ($files as $file): ?>
|
||||||
|
|
||||||
|
<?= $file->id ?>
|
||||||
|
|
||||||
|
<a href="/tracks/getfile/id/<?= $file->id ?>" title="Скачать файл">
|
||||||
|
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="/tracks/import/id/<?= $file->id ?>" title="Импортировать ещё раз">
|
||||||
|
<span class="glyphicon glyphicon-retweet" aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<?= $file->name ?>
|
||||||
|
— <?= $file->filename ?>
|
||||||
|
[<?= $file->tracksCount?> . <?= $file->tptCount ?> . <?= $file->wptCount ?>]
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<?php endforeach;
|
||||||
|
} else {
|
||||||
|
print 'Пока ничего не загружено';
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<table style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3>Ваши треки</h3>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<form method="POST" action="/tracks/uploadfile/" enctype="multipart/form-data" class="form-inline">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="uploadfile">Загрузить новый файл</label>
|
||||||
|
<input type="file" name="file" id="uploadfile" class="form-control" accept=".gpx, .kml, .kmz"/>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr/>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ($trips) {
|
||||||
|
foreach ($trips as $trip):
|
||||||
|
?>
|
||||||
|
<a href="/tracks/edit/id/<?= $trip->id ?>" class="btn btn-default">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true" title="Редактировать трек"></span>
|
||||||
|
</a>
|
||||||
|
<?= $trip->id ?> —
|
||||||
|
<a href="/?track=<?= $trip->id ?>"><?= $trip->name ?></a> (<?= $trip->createdAt ?>)
|
||||||
|
<?php if($trip->status == Trips::STATUS_PUBLIC):?>
|
||||||
|
<span class="glyphicon glyphicon-eye-open" style="color: #aaa;" aria-hidden="true" title="Публичный трек. Его могут видеть другие пользователи."></span>
|
||||||
|
<?php endif;?>
|
||||||
|
<br/>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
print 'Пока ничего не загружено. В заголовке справа представлена форма для загрузки файлов треков.';
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue