Skip to content

Instantly share code, notes, and snippets.

@mikearmstrong001
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikearmstrong001/2e2810fbf1c36c99b52d to your computer and use it in GitHub Desktop.
Save mikearmstrong001/2e2810fbf1c36c99b52d to your computer and use it in GitHub Desktop.
split gpx files
<html>
<head>
</head>
<body>
<div>
Choose a GPX file to load<p>
Click on red bar to find location of transition point<p>
Click on add to save point and find others<p>
Use prev, next and zoom options to help<p>
Save option will save the splits to your local download folder<p>
</div>
<input type="file" id="file-input" />
<button onclick="dumpxml()">save</button>
<br>
<table>
<tr>
<td width="30px">zoom</td>
<td width="30px"><button onclick="zoomout()">-</button></td>
<td width="30px"><div id="zoom">1.0</div></td>
<td width="30px"><button onclick="zoomin()">+</button></td>
</tr>
</table>
<br>
<canvas id="canvas" width="512" height="512"></canvas>
<table>
<tr>
<td><button onclick="prev()">prev</button></td>
<td><div id="timebar" style="width:512px;height:20px;background:red" onclick="clicked()" onmousedown="startdown(this)" onmouseup="enddown()" onmousemove="moved(this)"></div></td>
<td><button onclick="next()">next</button></td>
<td><button onclick="add()">add</button></td>
</tr>
</table>
<br>
<div id="timebar2"></div>
<br>
<br>
<div id="timebar3"></div>
</body>
<script type="text/javascript">
var gpx = undefined;
var track = undefined;
var cursor = -1.0;
var mouseElement = undefined;
var keys = [];
var zoom = 0.0;
Array.prototype.unique = function()
{
var i = 1;
while ( i < this.length )
{
if ( this[i] === this[i-1] )
{
this.splice(i,1,0);
} else {
i++;
}
}
}
function zoomin() {
zoom = zoom + 0.5;
draw();
}
function zoomout() {
zoom = zoom - 0.5;
if ( zoom < 0.0 ) {
zoom = 0.0;
}
draw();
}
function next() {
if ( cursor >= 0.0 ) {
var index = Math.round(cursor * (track.points.length/2));
index = index + 1;
if ( index > (track.points.length/2) ) {
index = (track.points.length/2);
}
cursor = index / (track.points.length/2);
draw();
}
}
function prev() {
if ( cursor >= 0.0 ) {
var index = Math.round(cursor * (track.points.length/2));
index = index - 1;
if ( index < 0 ) {
index = 0;
}
cursor = index / (track.points.length/2);
draw();
}
}
function add() {
if ( cursor >= 0.0 )
{
keys.push( cursor );
keys.sort();
draw();
}
}
function keepRegionElements( x, start, end ) {
var gpx = FindChild( x, "gpx" );
var trk = FindChild( gpx, "trk" );
var trkseg = FindChild( trk, "trkseg" );
if ( trkseg === undefined || trkseg.childNodes === undefined )
return undefined;
var index = 0;
var i = 0;
var firstTime = undefined;
while (i<trkseg.childNodes.length)
{
var trkpt = trkseg.childNodes[i];
if ( trkpt.nodeName !== "trkpt" )
{
trkseg.removeChild( trkpt );
continue;
}
if ( index < start || index>=end )
{
trkseg.removeChild( trkpt );
} else
{
if ( firstTime === undefined )
{
var trkpttime = FindChild( trkpt, "time" );
firstTime = trkpttime.firstChild.data;
}
i++;
}
index = index + 1;
}
var metadata = FindChild( gpx, "metadata" );
var time = FindChild( metadata, "time" );
time.firstChild.data = firstTime;
var trkname = FindChild( trk, "name" );
trkname.firstChild.data = trkname.firstChild.data + " : " + firstTime;
}
function download(filename, text) {
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
if (document.createEvent) {
var event = document.createEvent('MouseEvents');
event.initEvent('click', true, true);
pom.dispatchEvent(event);
}
else {
pom.click();
}
}
function dumpxml() {
if ( gpx === undefined )
return;
var xml_serializer = new XMLSerializer();
var xmlstring = xml_serializer.serializeToString(gpx);
var start = 0;
for (var i=0; i<keys.length; i++)
{
var x = LoadXML( xmlstring );
var end = Math.round(keys[i] * (track.points.length/2));
keepRegionElements( x, start, end );
var xs = xml_serializer.serializeToString(x);
download( start + ".gpx", xs);
start = end;
}
{
var x = LoadXML( xmlstring );
var fin = track.points.length/2;
keepRegionElements( x, start, fin );
var xs = xml_serializer.serializeToString(x);
download( start + ".gpx", xs);
}
}
function removekey(idx){
var oldkeys = keys;
keys = [];
for (var i=0; i<oldkeys.length; i++) {
if ( i !== idx ) {
keys.push( oldkeys[i] );
}
}
draw();
}
function draw() {
var z= document.getElementById("zoom");
z.innerHTML = (zoom+1.0).toString();
var timebar = document.getElementById("timebar");
var timebar2 = document.getElementById("timebar2");
var timebar3 = document.getElementById("timebar3");
var timebarRect = timebar.getBoundingClientRect();
while (timebar2.firstChild) {
timebar2.removeChild(timebar2.firstChild);
}
while (timebar3.firstChild) {
timebar3.removeChild(timebar3.firstChild);
}
for (var i=0; i<keys.length; i++)
{
var left = Math.round(keys[i] * timebarRect.width) + timebarRect.left;
var d = document.createElement( "div" );
d.id = "tag"+i;
d.style.cssText="position:absolute;top:"+(timebarRect.top+timebarRect.height-5)+"px;left:"+left+"px;width:2px;height:"+timebarRect.height+"px;background:green";
var index = Math.round(keys[i] * (track.points.length/2));
d.innerHTML = index;
timebar2.appendChild( d );
var d2 = document.createElement( "div" );
d2.innerHTML = "<button onclick=\"removekey("+i+");\">X</button>" + index;
timebar3.appendChild( d2 );
}
if ( cursor >= 0.0 ) {
var left = Math.round(cursor * timebarRect.width) + timebarRect.left;
var d = document.createElement( "div" );
d.style.cssText="position:absolute;top:"+(timebarRect.top+timebarRect.height-5)+"px;left:"+left+"px;width:2px;height:"+(timebarRect.height*2)+"px;background:blue";
var index = Math.round(cursor * (track.points.length/2));
d.innerHTML = index;
timebar2.appendChild( d );
}
//timebar.
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.clearRect ( 0 , 0 , canvas.width, canvas.height );
if ( track !== undefined )
{
var offsetx = track.bb[0];
var offsety = track.bb[1];
var scalex = (canvas.width-10) / (track.bb[2] - track.bb[0]);
var scaley = (canvas.height-10) / (track.bb[3] - track.bb[1]);
var scale = scalex;
if ( scaley < scale ) {
scale = scaley;
}
scale = scale * (1.0 + zoom);
if ( zoom > 0.0 ) {
var index = Math.round(cursor * (track.points.length/2)) * 2;
offsetx = track.points[index+0] - ((canvas.width/2)/scale);
offsety = track.points[index+1] - ((canvas.height/2)/scale);
}
ctx.fillStyle = "rgb(200,0,0)";
for (var i=0; i<track.points.length; i+=2) {
ctx.fillRect ((track.points[i+0]-offsetx) * scale, (track.points[i+1]-offsety) * scale, 5, 5);
}
if ( cursor >= 0.0 ) {
var index = Math.round(cursor * (track.points.length/2)) * 2;
ctx.fillStyle = "rgb(0,200,0)";
ctx.fillRect ((track.points[index+0]-offsetx) * scale, (track.points[index+1]-offsety) * scale, 10, 10);
}
}
}
}
function startdown(e) {
if ( mouseElement === undefined )
mouseElement = e;
}
function enddown() {
mouseElement = undefined;
}
function clicked() {
if ( track === undefined )
return;
var posx = 0;
var posy = 0;
var evt = window.event;
if (evt.pageX || evt.pageY)
{
posx = evt.pageX;
posy = evt.pageY;
}
else if (evt.clientX || evt.clientY)
{
posx = evt.clientX;
posy = evt.clientY;
}
var timebar = document.getElementById("timebar");
var rect = timebar.getBoundingClientRect();
cursor = (posx-rect.left) / (rect.right-rect.left)
draw();
}
function moved(e) {
if ( mouseElement !== e )
return;
clicked();
}
function LoadXML( txt )
{
var xmlDoc;
if (window.DOMParser)
{
var parser=new DOMParser();
xmlDoc=parser.parseFromString(txt,"text/xml");
}
else // Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.loadXML(txt);
}
return xmlDoc;
}
function FindAttribute( n, name ) {
if ( n === undefined || n.attributes === undefined )
return undefined;
for (var i=0; i<n.attributes.length; i++) {
if ( n.attributes[i].name === name ){
return n.attributes[i];
}
}
return undefined;
}
function FindChild( n, name ) {
if ( n === undefined || n.childNodes === undefined )
return undefined;
for (var i=0; i<n.childNodes.length; i++) {
if ( n.childNodes[i].nodeName === name ){
return n.childNodes[i];
}
}
return undefined;
}
function TrackToMesh( x ) {
var gpx = FindChild( x, "gpx" )
var trk = FindChild( gpx, "trk" );
var trkseg = FindChild( trk, "trkseg" );
if ( trkseg === undefined || trkseg.childNodes === undefined )
return undefined;
var mesh = { points : [], bb : [] };
mesh.points = [];
for (var i=0; i<trkseg.childNodes.length; i++)
{
var trkpt = trkseg.childNodes[i];
if ( trkpt.nodeName !== "trkpt" )
continue;
var lat = parseFloat( FindAttribute( trkpt, "lat" ).value );
var lon = parseFloat( FindAttribute( trkpt, "lon" ).value );
if ( mesh.points.length === 0 ) {
mesh.bb = [ lat, lon, lat, lon ];
} else {
if ( lat < mesh.bb[0] )
mesh.bb[0] = lat;
if ( lon < mesh.bb[1] )
mesh.bb[1] = lon;
if ( lat > mesh.bb[2] )
mesh.bb[2] = lat;
if ( lon > mesh.bb[3] )
mesh.bb[3] = lon;
}
mesh.points.push( lat );
mesh.points.push( lon );
}
return mesh;
}
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
gpx = LoadXML(contents);
track = TrackToMesh( gpx );
cursor = 0.0;
mouseElement = undefined;
keys = [];
zoom = 0.0;
draw();
};
reader.readAsText(file);
}
function displayContents(contents) {
var element = document.getElementById('file-content');
element.innerHTML = contents;
}
var e = document.getElementById('file-input');
e.addEventListener('change', readSingleFile, false);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment