3
Originally based in part on the "Improved MSN and Google GPS GPX Waypoint
4
Extraction" bookmarklet described at http://badsegue.org/archives/2005/04/21/
6
Josh Larios <hades@elsewhere.org>
7
August 3, 2005 - September 30, 2008
9
WARNING: Highly dependent on internal formats that aren't part of
10
the API, so subject to complete breakdown at any time, outside my
13
Gmap-pedometer elevation code courtesy of Mathew O'Brien.
15
3/05/2007 - HeyWhatsThat.com code by mk -at- heywhatsthat.com
16
10/09/2007 - Allpoints speed improvement by Kyle Yost
18
TO DO: Separate out gpx writing and point/track extraction, so I can load
19
some array up front regardless of whether it's a google map, a pedometer,
20
heywhatsthat, or whatever, and then just print the damn gpx once.
25
var googledoc = ""; // will hold retrieved google info
27
var gpxvar = ""; // will hold gHomeVPage structure, even for IE
28
var routes = new Array();
29
var polylines = new Array();
30
var milestones = new Array();
31
var yelp = new Array();
32
var googlepage; // Will hold the page element that gets toggled. May change.
35
function fixup (foo) {
36
foo = foo.replace(/\\x3e/g, '>');
37
foo = foo.replace(/\\x3c/g, '<');
38
foo = foo.replace(/\\x26/g, '&');
39
foo = foo.replace(/\\x42/g, '"');
40
foo = foo.replace(/\\x3d/g, '=');
42
foo = foo.replace(/\\u003e/g, '>');
43
foo = foo.replace(/\\u003c/g, '<');
44
foo = foo.replace(/\\u0026/g, '&');
46
foo = foo.replace(/\\042/g, '"');
48
foo = foo.replace(/"*polylines"*:\s*/g, 'polylines:');
49
foo = foo.replace(/"*markers"*:\s*/g, 'markers:');
50
foo = foo.replace(/"*id"*:\s*/g, 'id:');
51
foo = foo.replace(/"*lat"*:\s*/g, 'lat:');
52
foo = foo.replace(/"*lng"*:\s*/g, 'lng:');
53
foo = foo.replace(/"*laddr"*:\s*/g, 'laddr:');
54
foo = foo.replace(/"*points"*:\s*/g, 'points:');
55
foo = foo.replace(/\\"/g, '"');
56
foo = foo.replace(/\"/g, '\'');
61
function callInProgress (xmlhttp) {
62
switch (xmlhttp.readyState) {
63
case 1: case 2: case 3:
73
// Synchronous, with an alarm to catch timeouts (30 seconds)
74
// No idea if this is the best way to do this, but for sure the best way I
75
// came up with at 3 in the morning.
76
function loadXMLDoc(url) {
79
if (window.XMLHttpRequest) {
80
req = new XMLHttpRequest();
81
showstatusdiv('Loading...');
82
timeoutid = window.setTimeout( function(){if(callInProgress(req)){req.abort();}}, 30000);
83
req.open("GET", url, false);
85
window.clearTimeout(timeoutid);
87
} else if (window.ActiveXObject) {
88
req = new ActiveXObject("Microsoft.XMLHTTP");
90
showstatusdiv('Loading...');
91
timeoutid = window.setTimeout( function(){if(callInProgress(req)){req.abort();}}, 30000);
92
req.open("GET", url, false);
94
window.clearTimeout(timeoutid);
99
if (req.readyState == 4) {
101
if (req.status == 200) {
102
return(req.responseText);
104
showstatusdiv('Error ' + req.status + ' getting google data: ' + req.statusText);
108
showstatusdiv('Error: loadXMLDoc continued with readystate: ' + req.readyState);
114
function hidestatusdiv() {
116
if (statusbox = document.getElementById("statusbox")) {
117
document.body.removeChild(statusbox);
121
function showstatusdiv(boxcontents) {
123
z=document.body.appendChild(document.createElement("div"));
125
z.style.position = "absolute";
126
if (self.pageYOffset != null) {
127
z.style.top = self.pageYOffset + "px";
128
} else if (document.documentElement.scrollTop != null) {
129
z.style.top = document.documentElement.scrollTop + "px";
131
z.style.width = "50%";
132
z.style.left = "0px";
133
z.style.background = "#ffffff";
134
z.style.border = ".3em solid #ff0000";
135
z.style.padding = ".3em 1.3em .3em .3em";
136
z.style.zIndex = "1000";
138
z.innerHTML = '<div style="position: absolute; border: 1px solid black; top: 0px; right: 0px;"><span style="padding: .3em; font-weight: bold;"><a style="text-decoration: none;" title="Close status box" href="#" onclick="javascript:hidestatusdiv();">X</a></span></div>';
139
z.innerHTML += boxcontents;
142
// This function is from Google's polyline utility.
143
function decodeLine (encoded) {
144
var len = encoded.length;
150
while (index < len) {
155
b = encoded.charCodeAt(index++) - 63;
156
result |= (b & 0x1f) << shift;
159
var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
165
b = encoded.charCodeAt(index++) - 63;
166
result |= (b & 0x1f) << shift;
169
var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
172
array.push({"lat": round(lat * 1e-5), "lon": round(lng * 1e-5)});
178
function StringBuffer() {
182
StringBuffer.prototype.append = function append(string) {
183
this.buffer.push(string);
187
StringBuffer.prototype.toString = function toString() {
188
return this.buffer.join("");
193
function gmaptogpxdiv(dtype) {
200
Determine which type of data we're extracting -- a route, or points of
201
interest. (Or gmap-pedometer/heywhatsthat.)
204
if (gpxvar && gpxvar.overlays && gpxvar.overlays.polylines) {
208
errorbox('<p>2008.05.07 - GMapToGPX is currently unable to process driving directions, due to a change in the underlying Google Maps code. I\'m working on it.</p>');
214
// Load "polylines" up with the decoded polyline segments
215
for (i = 0; i < gpxvar.overlays.polylines.length; i++) {
216
polylines[i] = decodeLine(gpxvar.overlays.polylines[i].points);
219
// Stuff the descriptions into the "polylines" array
220
if (segmatch = googledoc.match(/<td class=.?dirsegtext.*?id=.?dirsegtext.*?<\/tr>/g)) {
221
for (var s = 0; s < segmatch.length; s++) {
222
var route = segmatch[s].replace(/.*dirsegtext_([0-9]+)_([0-9]+).*/, "$1");
223
var step = segmatch[s].replace(/.*dirsegtext_([0-9]+)_([0-9]+).*/, "$2");
224
var desc = deamp(segmatch[s].replace(/.*dirsegtext[^>]+>(.*?)<\/td>.*/, "$1"));
226
var polyline = gpxvar.drive.routes[route].steps[step].polyline;
227
var ppt = gpxvar.drive.routes[route].steps[step].ppt;
228
polylines[polyline][ppt].desc = deamp(desc);
232
// Figure out which polylines go into which routes
233
for (i = 0; i < gpxvar.drive.routes.length; i++) {
234
var start = gpxvar.drive.routes[i].steps[0].polyline;
235
var end = gpxvar.drive.routes[i].steps[gpxvar.drive.routes[i].steps.length - 1].polyline;
236
var route = "route" + i;
237
routes[route] = new Array();
238
for (n = start; n <= end; n++) {
239
routes[route] = routes[route].concat(polylines[n]);
243
// Get the milestone descriptions
245
if (msaddrmatch = gpxvar.panel.match(/<div id=.?sxaddr.*?>.*?<\/div>/g)) {
246
for (var i = 0; i < msaddrmatch.length; i++) {
247
milestones[parseInt(i)] = deamp(msaddrmatch[i].replace(/<div id=.?sxaddr.?><div[^>]+>(.*?)<\/div>/, "$1"));
252
} else if (googledoc.match(/id:'(A|addr)'/)) {
254
routes['poi'] = new Array();
256
var markers=googledoc.slice(googledoc.indexOf('markers:['));
257
/* markers=markers.slice(0, markers.indexOf('polylines: [')); */
259
var pois = markers.match(/{id:'([A-Z]|addr|loc\d+)'.*?\}/g);
260
for (var i = 0; i < pois.length; i++) {
261
var lat = pois[i].replace(/.*lat:(.*?),.*/, "$1");
262
var lon = pois[i].replace(/.*lng:(.*?),.*/, "$1");
263
var desc = pois[i].replace(/.*laddr:'(.*?)',.*/, "$1");
264
desc = desc.replace(/ @.*/, "");
265
desc = desc.replace(/(.*) \((.*)\)/, "$2 ($1)");
266
routes['poi'].push({"lat": round(lat), "lon": round(lon), "desc": deamp(desc)});
270
/* gmap-pedometer.com */
271
if ( (qtype==0) && (self.gLatLngArray) && (self.gLatLngArray[0]) ) {
276
/* HeyWhatsThat.com list of peaks visible from given location */
277
if (qtype == 0 && location.href.match(/heywhatsthat.com/i) && peaks && peaks.length) {
282
/* Yelp.com search */
283
if (qtype == 0 && location.href.match(/yelp.com/i) && document.body.innerHTML.match('result_plot_obj.map.addOverlay')) {
286
var yelpmatch = document.body.innerHTML.match(/result_plot_obj.map.addOverlay.*?\)\)/g);
287
for (var i = 0; i < yelpmatch.length; i++) {
288
yelp[i] = new Array();
289
yelp[i].name = deamp(yelpmatch[i].replace(/.*<h3>(.*?)<\/h3>.*/, "$1"));
290
yelp[i].addr = deamp(yelpmatch[i].replace(/.*<address[^>]*>(.*?)<\/address>.*/, "$1"));
291
yelp[i].lon = yelpmatch[i].replace(/.*Yelp.TSRUrl.*?,.*?,.*?, (.*?),.*/, "$1");
292
yelp[i].lat = yelpmatch[i].replace(/.*Yelp.TSRUrl.*?,.*?,.*?,.*?, (.*?),.*/, "$1");
295
/* Yelp.com single location */
296
// var json_biz = {"city":"Seattle","zip":"98102","review_count":6,"name":"Tacos Guaymas - CLOSED","neighborhoods":["Capitol Hill"],"photos":[],"address1":"213 Broadway East","avg_rating":4.000000,"longitude":-122.320999,"address2":null,"phone":"(206) 860-7345","state":"WA","latitude":47.620201,"id":"PidHplYWockrwJpijqUwsg","categories":{}};
297
if (qtype == 0 && location.href.match(/yelp.com/i) && json_biz) {
300
yelp[0] = new Array();
301
yelp[0].name = json_biz.name;
302
yelp[0].lat = json_biz.latitude;
303
yelp[0].lon = json_biz.longitude;
304
yelp[0].addr = json_biz.address1 + ", ";
305
if (json_biz.address2 != null) {
306
yelp[0].addr += json_biz.address2 + ", ";
308
yelp[0].addr += json_biz.city + ", " + json_biz.state + " " + json_biz.zip;
312
if (qtype == 0 && location.href.match(/findmespot.com/i) && document.getElementsByTagName('iframe')[1] && document.getElementsByTagName('iframe')[1].contentDocument.getElementById('mapForm:inputHidden1').value) {
318
if (qtype == 0 && location.href.match(/logyourrun.com/i) && route_polyline) {
324
errorbox('<p>There doesn\'t seem to be any extractable data on this page.</p><p>If there is, but it\'s not detected, please visit the <a href="http://www.elsewhere.org/GMapToGPX/">project homepage</a> and leave a bug report, including a link to the page you\'re on right now.</p><p><strong>Note:</strong> Google Maps mashups (that is, a page with a Google Map on it, but not at google.com) do not automatically work with this utility. If you would like to see GMapToGPX work with your Google Maps mashup site, please leave a comment on the project page.</p>');
330
/* t contains the text that will be injected into a <div> overlay */
331
var t="<div style='border:3px dotted orange;padding:2px;background-color:#FFFFFF;margin-left:auto;margin-right:auto;'>";
333
if (navigator.userAgent.match(/Safari/)) {
335
<style type="text/css">\
345
.menubar a , .menubar a:visited {\
346
padding: 1px 10px 1px 10px;\
347
text-decoration:none;\
348
background-color: #3399CC;\
350
font-family:Verdana, Sans-Serif;\
352
-moz-border-radius:10px;\
353
border:2px inset black;\
354
font-weight: bolder;\
358
background-color: transparent;\
361
border: 1px solid #efefef;\
364
.menubar a:hover , .menubar select:hover {\
365
border:2px outset black;\
366
background-color:white;\
368
text-decoration:none;\
375
t+="<div style='background-color:gray;'>";
376
t+='<ul class="menubar">';
377
t+='<li class="menubar">GMapToGPX v' + version + '</li>';
378
if ((qtype > 1) && (qtype != 4)) {
379
if (dtype != "route") {
380
t+='<li class="menubar"><a href="javascript:reload(0)" title="Turn points as a route">Route</a></li>';
382
if (dtype != "track") {
383
t+='<li class="menubar"><a href="javascript:reload(1)" title="Turn points as a track">Track</a></li>';
385
if (dtype != "points") {
386
t+='<li class="menubar"><a href="javascript:reload(2)" title="Turn points as waypoints">Points</a></li>';
388
if ((qtype ==2) && (dtype != "allpoints")) {
389
t+='<li class="menubar"><a href="javascript:reload(3)" title="ALL points as a track (potentially very large)">Full</a></li>';
392
t+='<li class="menubar"><a href="javascript:loadabout()">About</a></li>';
393
t+='<li class="menubar"><a href="javascript:closebox()">CLOSE [X]</a></li></ul></div>';
394
t+='<textarea rows="20" cols="60">';
396
/* This part of the GPX is going to be the same no matter what. */
397
t+= '<?xml version="1.0" encoding="' + charset + '"?>\n' +
398
'<gpx version="1.1"\n' +
399
' creator="GMapToGPX ' + version + ' - http://www.elsewhere.org/GMapToGPX/"\n' +
400
' xmlns="http://www.topografix.com/GPX/1/1"\n' +
401
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n' +
402
' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">\n';
404
if ((qtype==2) && (dtype=="allpoints")) {
405
var title = "Driving directions";
407
t+= ' <name>Google Driving Directions Track</name>\n';
408
var buf = new StringBuffer;
409
for (var key in routes) {
410
var route = routes[key];
411
buf.append(" <trkseg>\n");
412
for(i=0;i<route.length;i++) {
413
if (i == route.length - 1) {
414
route[i].desc = milestones[1 + parseInt(key.replace(/route/,''))];
415
} else if ((route[i].lat == route[i+1].lat) && (route[i].lon ==
419
buf.append(" <trkpt lat=\"");
420
buf.append(route[i].lat);
421
buf.append("\" lon=\"");
422
buf.append(route[i].lon);
426
buf.append(deamp(route[i].desc));
427
buf.append("</cmt>");
429
buf.append("</trkpt>\n");
431
buf.append(" </trkseg>\n");
433
buf.append(" </trk>\n");
436
} else if (qtype == 3) {
437
// var pl = location.href + returnPermalinkString();
438
var pl = "Permalink temporarily unavailable.";
439
var elevationArrayTested = true;
440
// 1st make sure that the gmap elevation array is the same length as
442
if ( (typeof(elevationArray) != 'undefined') && (gLatLngArray.length == elevationArray.length) ) {
443
// Next test all of the elevation data in the array, looking for
444
// bad elevation data
445
// -1.79769313486231E+308 means no valid elevation value was
446
// found at that point
447
for (var e =0;e<elevationArray.length;e++){
448
if (self.elevationArray[e] == "-1.79769313486231E+308")
450
elevationArrayTested = false;
454
elevationArrayTested = false;
457
if (dtype == "track") {
459
t+= ' <name>Gmaps Pedometer Track</name>\n' +
460
' <cmt>Permalink: <![CDATA[\n' + pl + '\n]]>\n</cmt>\n';
462
} else if (dtype == "route") {
464
t+= ' <name>Gmaps Pedometer Route</name>\n' +
465
' <cmt>Permalink: <![CDATA[\n' + pl + '\n]]>\n</cmt>\n';
467
for(var i=0;i<self.gLatLngArray.length;i++){
468
if (dtype == "track") {
470
} else if (dtype == "route") {
472
} else if (dtype == "points") {
475
t+= 'lat="' + round(self.gLatLngArray[i].y) + '" ' +
476
'lon="' + round(self.gLatLngArray[i].x) + '">\n';
479
if ( elevationArrayTested == true ) {
480
var currentElevation = 0;
481
currentElevation = self.elevationArray[i];
482
currentElevation = round(currentElevation * 0.3048)
483
t+= ' <ele>' + currentElevation + '</ele>\n';
486
t+= ' <name>' + (i ? 'Turn ' + i : 'Start') + '</name>\n';
488
if (dtype == "track") {
490
} else if (dtype == "route") {
492
} else if (dtype == "points") {
496
if (dtype == "track") {
499
} else if (dtype == "route") {
502
} else if (qtype == 4 && subtype == 1) {
503
/* HeyWhatsThat.com list of peaks */
504
for (var i = 0; i < peaks.length; i++) {
506
t+= ' <wpt lat="' + p.lat + '" lon="' + p.lon + '">\n' +
507
' <ele>' + p.elev + '</ele>\n' +
508
' <name>' + p.name + '</name>\n' +
509
' <cmt>' + p.name + '</cmt>\n' +
512
} else if (qtype == 4 && subtype == 2) {
513
for (var i = 0; i < yelp.length; i++) {
515
t+= ' <wpt lat="' + p.lat + '" lon="' + p.lon + '">\n' +
516
' <name>' + p.name + '</name>\n' +
517
' <cmt>' + p.addr + '</cmt>\n' +
520
} else if (qtype == 4 && subtype == 3) {
521
var spotdata = document.getElementsByTagName('iframe')[1].contentDocument.getElementById('mapForm:inputHidden1').value;
522
var loc_array = spotdata.split(",");
523
var loc_length = loc_array.length - 1;
524
t += ' <trk><trkseg>\n';
525
for(var i=0;i<loc_length;i++){
526
var loc_point = loc_array[i].split("||");
527
var esn = loc_point[0];
528
var lat = loc_point[1];
529
var lon = loc_point[2];
530
var type = loc_point[3];
531
var dtime = loc_point[4];
532
t+= ' <trkpt lat="' + lat + '" lon="' + lon + '">\n' +
533
' <name>' + i + '-' + type + '</name>\n' +
534
' <cmt>' + type + ' ' + esn + ' @ ' + dtime + '</cmt>\n' +
535
' <desc>' + type + ' ' + esn + ' @ ' + dtime + '</desc>\n' +
538
t += ' </trkseg></trk>\n';
539
} else if (qtype == 4 && subtype == 4) {
540
var lyr = decodeLine(route_polyline);
541
t += ' <trk><trkseg>\n';
542
for (var i = 0; i < lyr.length; i++) {
543
t+= ' <trkpt lat="' + lyr[i].lat + '" lon="' + lyr[i].lon + '">\n' ;
544
t+= ' <name>LYR' + i + '</name>\n' + ' </trkpt>\n';
546
t += ' </trkseg></trk>\n';
548
} else if (qtype == 2) {
549
/* If we're on a page with driving directions, spit out a route. */
550
var title = "Driving directions";
552
if (dtype == "track") {
559
for (var key in routes) {
560
var route = routes[key];
561
var routeno = key.replace(/route/, '');
562
routeno = parseInt(routeno);
563
if (dtype == "track") {
565
} else if (dtype == "route") {
569
if ((dtype=="track") || (dtype=="route")) {
570
t+= ' <name>' + key + '</name>\n';
571
t+= ' <cmt>' + milestones[routeno] + " to " + milestones[routeno + 1] + '</cmt>\n';
572
t+= ' <desc>' + milestones[routeno] + " to " + milestones[routeno + 1] + '</desc>\n';
575
for(i=0;i<route.length;i++){
576
if ((i != route.length - 1) && (route[i].desc == undefined)) {
579
// Only print turn points and milestones (last point is an
580
// undescribed milestone; first point should always have a
593
t+= 'lat="' + route[i].lat + '" ' +
594
'lon="' + route[i].lon + '">\n' +
596
if (i == route.length - 1) {
597
route[i].desc = milestones[routeno+1];
599
t += 'GMLS-' + ((milestone < 100) ? '0' : '') +
600
((milestone < 10) ? '0' : '') + milestone;
604
t += 'GRTP-' + ((turn < 100) ? '0' : '') +
605
((turn < 10) ? '0' : '') + turn;
608
' <cmt>' + route[i].desc + '</cmt>\n' +
609
' <desc>' + route[i].desc + '</desc>\n';
624
if (dtype == "track") {
626
} else if (dtype == "route") {
631
if (dtype == "track") {
635
} else if (qtype == 1) {
636
/* This is a page with points of interest - spit out waypoints. */
637
for(i=0;i<routes['poi'].length;i++){
638
var point = routes['poi'][i];
639
t+= ' <wpt lat="' + point.lat + '" lon="' + point.lon + '">\n' +
640
' <name>' + point.desc + '</name>\n' +
641
' <cmt>' + point.desc.replace(/(.*) \((.*)\)/, "$2 ($1)") + '</cmt>\n' +
642
' <desc>' + point.desc.replace(/(.*) \((.*)\)/, "$2 ($1)") + '</desc>\n' +
646
errorbox('An unknown error occurred. Please leave a bug report at the <a href="http://www.elsewhere.org/GMapToGPX/">project homepage</a> and include a link to the page you\'re on right now.');
652
t+="<div style='background-color:gray;'>";
653
t+='<ul class="menubar">';
654
t+='<li class="menubar"><a href="javascript:loadabout()">About</a></li>';
655
t+='<li class="menubar"><a href="javascript:closebox()">CLOSE [X]</a></li></ul></div></div>';
660
function displaybox(boxcontents) {
662
if (googlepage=document.getElementById("page")) {
663
googlepage.style.display='none';
665
var z=document.body.appendChild(document.createElement("div"));
667
/* I don't know about this stuff; it came from badsegue. */
668
z.style.position = "absolute";
669
if (self.pageYOffset != null) {
670
z.style.top = self.pageYOffset + "px";
671
} else if (document.documentElement.scrollTop != null) {
672
z.style.top = document.documentElement.scrollTop + "px";
674
z.style.width = "99%";
675
z.style.zIndex = "1000";
676
z.innerHTML = boxcontents;
679
function closebox() {
681
if (gpxbox = document.getElementById("gpxbox")) {
682
document.body.removeChild(gpxbox);
684
if (googlepage != undefined) {
685
googlepage.style.display='block';
691
function loadabout() {
692
var about = '<span style="font-size: x-small;"><p><a href="http://www.elsewhere.org/GMapToGPX/">GMapToGPX</a> Extractor ' + version + '<br />';
693
about += 'A project of <a href="http://www.elsewhere.org/">Communications From Elsewhere</a></p>';
694
about += '<p>Usage:<ul>';
695
about += '<li>"Track" displays driving directions as a GPX track with one or more track segments, depending on the number of milestones in the directions.</li>';
696
about += '<li>"Route" displays driving directions as one or more GPX routes.</li>';
697
about += '<li>"Full" displays driving directions as a GPX track containing one or more track segments, each of which contains every single point on the line Google Maps draws to represent the segment. Use with caution, as long routes may produce huge results.</li>';
698
about += '<li>"Points" displays driving directions as a list of waypoints for each turn in the route. The waypoints will be in order, but this option is mainly intended for devices which can only handle waypoints, not tracks or routes. In most cases, you should use another option.</li>';
699
about += '<li>For single or multiple address searches, there are no display options. You get a list of individual waypoints.</li>';
700
about += '</ul>If you have questions or comments, please visit the <a href="http://www.elsewhere.org/GMapToGPX/">project homepage</a>.</p></span>';
701
showstatusdiv(about);
704
function errorbox(a) {
705
var err = '<a href="http://www.elsewhere.org/GMapToGPX/">GMapToGPX</a> v' + version + " (ERROR)<br />" + a;
710
/* Clean up floating point math errors */
712
return parseInt(a*1E+5)/1E+5;
718
gmaptogpxdiv("route");
720
gmaptogpxdiv("track");
722
gmaptogpxdiv("points");
724
gmaptogpxdiv("allpoints");
731
a = a.replace(/<br *\/>(.+)/g, ", $1");
732
a = a.replace(/<br *\/>/g, '');
733
a = a.replace(/'/g, '\'');
734
a = a.replace(/\\047/g, '\'');
735
a = a.replace(/\\042/g, '\"');
736
a = a.replace(/ /g, ' ');
737
a = a.replace(/<\/*b>/g, '');
738
a = a.replace(/<wbr\/*>/g, '');
739
a = a.replace(/<div[^>]*?>.*?<\/div>/g, ' ');
740
a = a.replace(/\\\'/g, '\'');
741
a = a.replace(/\\\"/g, '\"');
742
a = a.replace(/\\x26/g, '&');
743
a = a.replace(/&/g, '&');
744
a = a.replace(/&amp;amp;/g, '&amp;');
745
a = a.replace(/\\n/g, '');
746
a = a.replace(/\\t/g, '');
747
a = a.replace(/\s+/g, ' ');
748
a = a.replace(/^\s+/, '');
749
a = a.replace(/\s+$/, '');
755
if (document.location.hostname.indexOf('google') >= 0) {
758
if (kmlurl = document.getElementById('view_kml_link').href) {
759
if (kmlurl.indexOf(':void') < 0) {
760
kmlurl = kmlurl.replace(/output=nl/, 'output=kml');
761
errorbox('This is a "My Maps" page, which means that the original KML used to create it is available. Please <a href="' + kmlurl + '">download the KML file</a> (using this link, not the one provided by Google) and convert it using <a href="http://www.gpsvisualizer.com/convert" target="_new">GPSVisualizer</a>.');
768
// bar_icon_link is the "link to this page" icon. If they change
769
// its name, I need to fix that here.
770
if (googleurl=document.getElementById('link').href) {
771
googleurl = googleurl.replace(/&view=text/, '');
772
googledoc = loadXMLDoc(googleurl);
774
charset=googledoc.slice(googledoc.indexOf('charset='));
775
charset=charset.slice(8, charset.indexOf('"'));
777
// Doing this as a regexp was causing firefox to stall out. bah.
778
var encpointblob=googledoc.slice(googledoc.indexOf('gHomeVPage ='));
779
encpointblob=encpointblob.slice(0, encpointblob.indexOf('};') + 2
781
encpointblob=encpointblob.replace(/gHomeVPage/, "gpxvar");
783
var panel=googledoc.slice(googledoc.indexOf('id=panel_dir'));
784
panel=panel.slice(0,panel.indexOf('Map data'));
785
gpxvar.panel = panel;
786
googledoc=fixup(googledoc);
791
charset = charset ? charset : "UTF-8";
793
/* This bit of code was causing Safari to seriously freak out, hence the
794
stylesheet being included above in t, but only for Safari. */
795
if (! navigator.userAgent.match(/Safari/)) {
796
var styleObject = document.getElementsByTagName("HEAD")[0].appendChild(document.createElement("link"));
797
styleObject.rel="Stylesheet";
798
styleObject.type="text/css";
799
styleObject.href="http://www.elsewhere.org/GMapToGPX/menubar.css";
800
styleObject.id="sst_css";
804
/* Default action. If it's not a route, the argument doesn't matter. */
805
gmaptogpxdiv("route");