Add gpx import feature (closes #14)
This commit is contained in:
parent
a6f3ed1162
commit
33b581b47a
@ -106,7 +106,7 @@ select {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#user, #track, #summary, #export, #other, #units {
|
||||
#user, #track, #summary, #export, #import, #other, #units {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
#summary span {
|
||||
|
15
index.php
15
index.php
@ -189,12 +189,21 @@
|
||||
</div>
|
||||
|
||||
<div id="export">
|
||||
<u><?= $lang["download"] ?></u><br>
|
||||
<a class="menulink" href="javascript:void(0);" onclick="load('kml', userid, trackid);">kml</a>
|
||||
<a class="menulink" href="javascript:void(0);" onclick="load('gpx', userid, trackid);">gpx</a>
|
||||
<u><?= $lang["export"] ?></u><br>
|
||||
<a class="menulink" href="javascript:void(0);" onclick="exportFile('kml', userid, trackid);">kml</a>
|
||||
<a class="menulink" href="javascript:void(0);" onclick="exportFile('gpx', userid, trackid);">gpx</a>
|
||||
</div>
|
||||
|
||||
<?php if ($user->isValid): ?>
|
||||
<div id="import">
|
||||
<u><?= $lang["import"] ?></u><br>
|
||||
<form id="importForm" enctype="multipart/form-data" method="POST">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="1048576" />
|
||||
<input type="file" id="inputFile" name="gpx" style="display:none" onchange="importFile(this)" />
|
||||
</form>
|
||||
<a class="menulink" href="javascript:void(0);" onclick="document.getElementById('inputFile').click();">gpx</a>
|
||||
</div>
|
||||
|
||||
<div id="admin_menu">
|
||||
<u><?= $lang["adminmenu"] ?></u><br>
|
||||
<?php if ($user->isAdmin): ?>
|
||||
|
35
js/main.js
35
js/main.js
@ -217,11 +217,42 @@ function getPopupHtml(p, i, count) {
|
||||
return popup;
|
||||
}
|
||||
|
||||
function load(type, userid, trackid) {
|
||||
var url = 'utils/download.php?type=' + type + '&userid=' + userid + '&trackid=' + trackid;
|
||||
function exportFile(type, userid, trackid) {
|
||||
var url = 'utils/export.php?type=' + type + '&userid=' + userid + '&trackid=' + trackid;
|
||||
window.location.assign(url);
|
||||
}
|
||||
|
||||
function importFile(input){
|
||||
var xhr = getXHR();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
var xml = xhr.responseXML;
|
||||
var message = "";
|
||||
if (xml) {
|
||||
var root = xml.getElementsByTagName('root');
|
||||
if (root.length && getNode(root[0], 'error') == 0) {
|
||||
trackId = getNode(root[0], 'trackid');
|
||||
getTracks(userid);
|
||||
loadTrack(userid, trackId, 1);
|
||||
return;
|
||||
}
|
||||
errorMsg = getNode(root[0], 'message');
|
||||
if (errorMsg) { message = errorMsg; }
|
||||
}
|
||||
alert(lang['actionfailure'] + '\n' + message);
|
||||
xhr = null;
|
||||
}
|
||||
}
|
||||
xhr.upload.onprogress = function(e) {
|
||||
console.log(e.loaded, e.total)
|
||||
}
|
||||
xhr.upload.onload = function(e) {
|
||||
console.log('file upload')
|
||||
}
|
||||
xhr.open("POST", "utils/import.php", true);
|
||||
xhr.send(new FormData(input.parentElement));
|
||||
}
|
||||
|
||||
function updateSummary(l, d, s) {
|
||||
var t = document.getElementById('summary');
|
||||
if (latest == 0) {
|
||||
|
@ -25,7 +25,7 @@ $lang["track"] = "Route";
|
||||
$lang["latest"] = "letzte Position";
|
||||
$lang["autoreload"] = "Autoneuladen";
|
||||
$lang["reload"] = "Neuladen";
|
||||
$lang["download"] = "Download Daten";
|
||||
$lang["export"] = "Download Daten";
|
||||
$lang["chart"] = "Höhentabelle";
|
||||
$lang["close"] = "Schließen";
|
||||
$lang["time"] = "Zeit";
|
||||
|
@ -54,7 +54,7 @@ $lang["track"] = "Track";
|
||||
$lang["latest"] = "latest position";
|
||||
$lang["autoreload"] = "autoreload";
|
||||
$lang["reload"] = "Reload now";
|
||||
$lang["download"] = "Download data";
|
||||
$lang["export"] = "Export track";
|
||||
$lang["chart"] = "Altitudes chart";
|
||||
$lang["close"] = "close";
|
||||
$lang["time"] = "Time";
|
||||
@ -114,5 +114,7 @@ $lang["passrules"][3] = "It should contain at least one lower case letter, one u
|
||||
$lang["owntrackswarn"] = "Your can only edit your own tracks";
|
||||
$lang["gmauthfailure"] = "There may be problem with Google Maps API key on this page";
|
||||
$lang["gmapilink"] = "You may find more information about API keys on <a target=\"_blank\" href=\"https://developers.google.com/maps/documentation/javascript/get-api-key\">this Google webpage</a>";
|
||||
|
||||
$lang["import"] = "Import track";
|
||||
$lang["iparsefailure"] = "Parsing failed";
|
||||
$lang["idatafailure"] = "No track data in imported file";
|
||||
?>
|
||||
|
@ -25,7 +25,7 @@ $lang["track"] = "Rastro";
|
||||
$lang["latest"] = "última posición";
|
||||
$lang["autoreload"] = "autorecarga";
|
||||
$lang["reload"] = "Recargar ahora";
|
||||
$lang["download"] = "Descargar datos";
|
||||
$lang["export"] = "Descargar datos";
|
||||
$lang["chart"] = "Gráfico de altitudes";
|
||||
$lang["close"] = "cerrar";
|
||||
$lang["time"] = "Hora";
|
||||
|
@ -25,7 +25,7 @@ $lang["track"] = "Piste";
|
||||
$lang["latest"] = "dernière position";
|
||||
$lang["autoreload"] = "rechargement automatique";
|
||||
$lang["reload"] = "Recharger maintenant";
|
||||
$lang["download"] = "Télécharger les données";
|
||||
$lang["export"] = "Télécharger les données";
|
||||
$lang["chart"] = "Courbes d'altitudes";
|
||||
$lang["close"] = "fermer";
|
||||
$lang["time"] = "Temps";
|
||||
|
@ -25,7 +25,7 @@ $lang["track"] = "Útvonal";
|
||||
$lang["latest"] = "Utolsó rögzített pont";
|
||||
$lang["autoreload"] = "Automatikus frissítés";
|
||||
$lang["reload"] = "Frissítés most";
|
||||
$lang["download"] = "Adatok letöltése";
|
||||
$lang["export"] = "Adatok letöltése";
|
||||
$lang["chart"] = "Magasság diagramm";
|
||||
$lang["close"] = "Bezár";
|
||||
$lang["time"] = "Rögzítés ideje";
|
||||
|
@ -54,7 +54,7 @@ $lang["track"] = "Traccia";
|
||||
$lang["latest"] = "ultima posizione";
|
||||
$lang["autoreload"] = "auto-ricarica";
|
||||
$lang["reload"] = "Ricarica ora";
|
||||
$lang["download"] = "Scarica dati";
|
||||
$lang["export"] = "Scarica dati";
|
||||
$lang["chart"] = "Grafico altitudine";
|
||||
$lang["close"] = "chiudi";
|
||||
$lang["time"] = "Ora";
|
||||
|
@ -49,7 +49,7 @@ $lang["track"] = "Trasa";
|
||||
$lang["latest"] = "ostatnia pozycja";
|
||||
$lang["autoreload"] = "odświeżaj";
|
||||
$lang["reload"] = "Odśwież teraz";
|
||||
$lang["download"] = "Pobierz dane";
|
||||
$lang["export"] = "Eksportuj trasę";
|
||||
$lang["chart"] = "Wykres przewyższeń";
|
||||
$lang["close"] = "zamknij";
|
||||
$lang["time"] = "Czas";
|
||||
@ -109,5 +109,8 @@ $lang["passrules"][3] = "Powinno ono zawierać przynajmniej jedną małą, jedn
|
||||
$lang["owntrackswarn"] = "Możesz edytować tylko swoje własne trasy";
|
||||
$lang["gmauthfailure"] = "Prawdopodobnie na tej stronie występuje problem z kluczem API Google Maps";
|
||||
$lang["gmapilink"] = "Więcej informacji o kluczach API znajdziesz <a target=\"_blank\" href=\"https://developers.google.com/maps/documentation/javascript/get-api-key\">pod tym linkiem</a>";
|
||||
$lang["import"] = "Importuj trasę";
|
||||
$lang["iparsefailure"] = "Błąd parsowania pliku";
|
||||
$lang["idatafailure"] = "Brak trasy w importowanym pliku";
|
||||
|
||||
?>
|
||||
|
@ -182,7 +182,7 @@ if ($trackId && $userId) {
|
||||
$xml->writeAttribute("version", "1.1");
|
||||
$xml->startElement("metadata");
|
||||
$xml->writeElement("name", $positionsArr[0]->trackName);
|
||||
$xml->writeElement("time", str_replace(" ", "T", $positionsArr[0]->time));
|
||||
$xml->writeElement("time", gmdate("Y-m-d\TH:i:s\Z", strtotime($positionsArr[0]->time)));
|
||||
$xml->endElement();
|
||||
$xml->startElement("trk");
|
||||
$xml->writeElement("name", $positionsArr[0]->trackName);
|
||||
@ -200,7 +200,7 @@ if ($trackId && $userId) {
|
||||
$xml->writeAttribute("lat", $position->latitude);
|
||||
$xml->writeAttribute("lon", $position->longitude);
|
||||
if (!is_null($position->altitude)) { $xml->writeElement("ele", $position->altitude); }
|
||||
$xml->writeElement("time", str_replace(" ", "T", $position->time));
|
||||
$xml->writeElement("time", gmdate("Y-m-d\TH:i:s\Z", strtotime($position->time)));
|
||||
$xml->writeElement("name", ++$i);
|
||||
$xml->startElement("desc");
|
||||
$description =
|
109
utils/import.php
Executable file
109
utils/import.php
Executable file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/* μlogger
|
||||
*
|
||||
* Copyright(C) 2017 Bartek Fabiszewski (www.fabiszewski.net)
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
require_once(dirname(__DIR__) . "/auth.php"); // sets $user
|
||||
require_once(ROOT_DIR . "/helpers/track.php");
|
||||
require_once(ROOT_DIR . "/helpers/position.php");
|
||||
|
||||
/**
|
||||
* Exit with xml response
|
||||
* @param boolean $isError Error if true
|
||||
* @param string $errorMessage Optional error message
|
||||
*/
|
||||
function exitWithStatus($isError, $errorMessage = NULL, $trackId = NULL) {
|
||||
header("Content-type: text/xml");
|
||||
$xml = new XMLWriter();
|
||||
$xml->openURI("php://output");
|
||||
$xml->startDocument("1.0");
|
||||
$xml->setIndent(true);
|
||||
$xml->startElement('root');
|
||||
$xml->writeElement("error", (int) $isError);
|
||||
if ($isError) {
|
||||
$xml->writeElement("message", $errorMessage);
|
||||
} else {
|
||||
$xml->writeElement("trackid", $trackId);
|
||||
}
|
||||
$xml->endElement();
|
||||
$xml->endDocument();
|
||||
$xml->flush();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$user->isValid) {
|
||||
exitWithStatus(true, $lang["servererror"]);
|
||||
}
|
||||
|
||||
$sizeMax = 10 * 1024 * 1024; //FIXME: set to php limits
|
||||
$gpxFile = NULL;
|
||||
$gpxUpload = $_FILES["gpx"];
|
||||
if ($gpxUpload["error"] == UPLOAD_ERR_OK && $gpxUpload["size"] < $sizeMax) {
|
||||
$gpxFile = $gpxUpload["tmp_name"];
|
||||
$gpxName = basename($gpxUpload["name"]);
|
||||
}
|
||||
|
||||
$gpx = false;
|
||||
libxml_use_internal_errors(true);
|
||||
if ($gpxFile && file_exists($gpxFile)) {
|
||||
$gpx = simplexml_load_file($gpxFile);
|
||||
}
|
||||
|
||||
if ($gpx === false) {
|
||||
$message = $lang["iparsefailure"];
|
||||
$parserMessages = [];
|
||||
foreach(libxml_get_errors() as $parseError) {
|
||||
$parserMessages[] = $parseError->message;
|
||||
}
|
||||
$parserMessage = implode(", ", $parserMessages);
|
||||
if (!empty($parserMessage)) {
|
||||
$message .= ": $parserMessage";
|
||||
}
|
||||
if ($gpxUpload["error"] != UPLOAD_ERR_OK) {
|
||||
$message .= " (" . $gpxUpload["error"] . ")";
|
||||
}
|
||||
exitWithStatus(true, $message);
|
||||
}
|
||||
else if (empty($gpx->trk)) {
|
||||
exitWithStatus(true, $lang["idatafailure"]);
|
||||
}
|
||||
|
||||
$trackName = empty($gpx->trk->name) ? $gpxName : $gpx->trk->name->__toString();
|
||||
$metaName = empty($gpx->metadata->name) ? NULL : $gpx->metadata->name->__toString();
|
||||
$track = new uTrack();
|
||||
$trackId = $track->add($user->id, $trackName, $metaName);
|
||||
if ($trackId === false) {
|
||||
exitWithStatus(true, $lang["servererror"]);
|
||||
break;
|
||||
}
|
||||
|
||||
$position = new uPosition();
|
||||
foreach($gpx->trk->trkseg as $segment) {
|
||||
foreach($segment->trkpt as $point) {
|
||||
$ret = $position->add($user->id, $trackId,
|
||||
strtotime($point->time), $point["lat"], $point["lon"], $point->ele,
|
||||
NULL, NULL, NULL, "gps", NULL, NULL);
|
||||
if ($ret === false) {
|
||||
exitWithStatus(true, $lang["servererror"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return track id
|
||||
exitWithStatus(false, NULL, $trackId);
|
||||
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user