Last active
August 29, 2015 14:16
-
-
Save mikearmstrong001/2e2810fbf1c36c99b52d to your computer and use it in GitHub Desktop.
split gpx files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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