// GPX2GM
// Darstellung von GPS-Daten aus einer GPX-Datei in Google Maps
// Version 3.0
// 29. 11. 2008 Jürgen Berkemeier
// www.j-berkemeier.de

document.write('<script src="http://maps.google.com/maps?file=api&amp;v=2.x&amp;key='+key+'" type="text/javascript"><\/script>');

Array.prototype.sum=function() {
 for(var s=0,i=0;i<this.length;i++)s+=this[i];
 return s;
}

function makeMap(ID) {
  var dieses = this;
  var id = ID;
  var id_hp = ID+"_hp";
  var load = false
  var latmin=1000,latmax=-1000,lonmin=1000,lonmax=-1000;
  var zoom = 1;
  var bilder;
  var fname,tcol,rcol,maptype;
  var tcols = new Array("#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#000000");
  var rcols = new Array("#800000","#008000","#000080","#808000","#800080","#008080","#808080");
  var tracks,waypoints,routes,tracklens,routlens,profile;
  var routeNames,trackNames;
  var GPX2GM_Path="";
  var scr = document.getElementsByTagName("script");
  for(var i=0;i<scr.length;i++) if(scr[i].src && scr[i].src.length) {
    var path = scr[i].src;
    var pos = path.search("GPX2GM.js");
    if(pos!=-1) {
      GPX2GM_Path = path.substring(0,pos);
      break;
    }
  }
  var icon = new GIcon();
  icon.image = GPX2GM_Path+"scenic.png";
  icon.shadow = GPX2GM_Path+"shadow.png";
  icon.iconSize = new GSize(21.0, 31.0);
  icon.shadowSize = new GSize(52.0, 29.0);
  icon.iconAnchor = new GPoint(5.0, 30.0);
  icon.infoWindowAnchor = new GPoint(10.0, 5.0);
  var div = document.getElementById(id);
  var w = div.offsetWidth;
  var h = div.offsetHeight;
  var MapHead = document.createElement("div");
  MapHead.id = "map_head"+id;
  MapHead.style.margin = 0;
  MapHead.style.padding = 0;
//  MapHead.style.fontSize = "0.8em";
//  MapHead.style.lineHeight = "1.5em";
  MapHead.appendChild(document.createTextNode(": "));
  var mapdiv = document.createElement("div");
  mapdiv.id = "map_"+id;
  mapdiv.style.width = w+"px";
  while(div.hasChildNodes()) div.removeChild(div.firstChild);
  div.appendChild(MapHead);
  div.appendChild(mapdiv);
  mapdiv.style.height = h-mapdiv.offsetTop+MapHead.offsetTop+"px";
  var map = new GMap2(document.getElementById("map_"+id));
  map.addControl(new GSmallMapControl());
//  map.addControl(new GLargeMapControl());
  map.addMapType(G_PHYSICAL_MAP);
//  map.addControl(new GMapTypeControl());
  map.addControl(new GHierarchicalMapTypeControl());
  map.addControl(new GScaleControl());
  map.enableScrollWheelZoom();
  var hp = document.getElementById(id_hp);
  var hp_diag;
  if(hp) hp_diag = new plot(id_hp);
  this.Spur = function(fn,mpt) {
    tcol = "#ff00ff";
    rcol = "#00FFFF";
    maptype = mpt;
    if (fname!=fn) {
      fname = fn;
      GDownloadUrl(fname, function(data, responseCode) {
        if (responseCode != 200 && responseCode != 0 ) {
          alert("Beim Oeffnen der Datei "+fname+" ist der Fehler "+responseCode+" aufgetreten!");
          return;
        }
        dieses.parseGPX(data) ;
        dieses.setMapHead();
        zoom = map.getBoundsZoomLevel(new GLatLngBounds(new GLatLng(latmin,lonmin),new GLatLng(latmax,lonmax))); // sw, ne
        dieses.rescale();
        map.setMapType(maptype);
        dieses.show("wtr");
      } );
    }
    else {
      dieses.show("wtr");
    }
  } // Spur
  var chkwpt,chktrk,chkrt;
  this.setMapHead = function() {
    var name = fname.replace(/.+\//,"");
    MapHead.innerHTML = name+": ";
    if(waypoints.length) {
      if(waypoints.length==1) var texte=new Array("Wegpunkt"+String.fromCharCode(160));
      else if(waypoints.length>1) var texte=new Array("Wegpunkte"+String.fromCharCode(160));
      chkwpt = new JB_CheckBoxGroup(MapHead.id,texte,ID+"_wpt","black",true,dieses.checkBoxes);
    }
    if(tracks.length) {
      var texte=new Array()
      if(tracks.length==1)
        texte[0] = "Track ("+tracklens[0]+"km) "+String.fromCharCode(160);
      else if(tracks.length>1) {
        texte[0] = "Tracks ("+tracklens.sum()+"km) "+String.fromCharCode(160);
        for(var i=0;i<tracks.length;i++) texte[i+1] = trackNames[i]+" ("+tracklens[i]+"km)";
      }
      chktrk = new JB_CheckBoxGroup(MapHead.id,texte,ID+"_trk",tcols,true,dieses.checkBoxes);
    }
    if(routes.length) {
      var texte=new Array()
      if(routes.length==1)
        texte[0] = "Route ("+routlens[0]+"km) "+String.fromCharCode(160);
      else if(routes.length>1) {
        texte[0] = "Routen ("+routlens.sum()+"km) "+String.fromCharCode(160);
        for(var i=0;i<routes.length;i++) texte[i+1] = routeNames[i]+" ("+routlens[i]+"km)";
      }
      chkrt = new JB_CheckBoxGroup(MapHead.id,texte,ID+"_rt",rcols,true,dieses.checkBoxes);
    }
  } // setMapHead
  this.checkBoxes = function(obj,ele) {
    var what="";
    if(chkwpt && chkwpt.status[0]) what += "w";
    if(chktrk && chktrk.status[0]) what += "t";
    if(chkrt  && chkrt.status[0] ) what += "r";
    dieses.show(what);
  }
  this.parseGPX = function(data) {
    var entf = new this.Entfernung();
    tracks = new Array();
    trackNames = new Array();
    tracklens = new Array() ;
    profile = new Array();
    load = false;
    latmin=1000;latmax=-1000;lonmin=1000;lonmax=-1000;
    var xml = GXml.parse(data);
    var trk = xml.documentElement.getElementsByTagName("trk"); // Tracks
    for(var k=0;k<trk.length;k++) {
      var trkseg = trk[k].getElementsByTagName("trkseg"); // Trackssegmente
      var name = trk[k].getElementsByTagName("name");
      if(name.length && name[0].firstChild && name[0].firstChild.length)
        trackNames[k] = name[0].firstChild.data;
      else
        trackNames[k] = "Track "+k;
      for(var j=0;j<trkseg.length;j++) {
        var trkpts = trkseg[j].getElementsByTagName("trkpt"); // Trackpunkte
        var track = new Array();
        var profil = new Array();
        var tracklen = 0;
        for(var i=0;i<trkpts.length;i++) { // Trackdaten
          var lat = parseFloat(trkpts[i].getAttribute("lat"));
          var lon = parseFloat(trkpts[i].getAttribute("lon"));
          if(i==0) entf.init(lat,lon) ;
          tracklen += entf.rechne(lat,lon);
          if(lat<latmin) latmin=lat; else if(lat>latmax) latmax=lat;
          if(lon<lonmin) lonmin=lon; else if(lon>lonmax) lonmax=lon;
          track.push(new GLatLng(lat,lon));
          if(trkpts[i].getElementsByTagName("ele").length) {
            var h = parseFloat(trkpts[i].getElementsByTagName("ele")[0].firstChild.data);
            profil.push({x:tracklen,y:h});
          }
        }
      }
      tracks.push(track);
      tracklens.push(Math.round(tracklen*10)/10);
      profile.push(profil);
    }
    var rte = xml.documentElement.getElementsByTagName("rte"); // Routen
    routes = new Array();
    routeNames = new Array();
    routlens = new Array();
    for(var j=0;j<rte.length;j++) {
      var rtepts = rte[j].getElementsByTagName("rtept");
      var route = new Array();
      var routlen = 0;
      var name = rte[j].getElementsByTagName("name");
      if(name.length && name[0].firstChild && name[0].firstChild.length)
        routeNames[j] = name[0].firstChild.data;
      else
        routeNames[j] = "Route "+j;
      for(var i=0;i<rtepts.length;i++) { // Zwischenziele
        var lat = parseFloat(rtepts[i].getAttribute("lat"));
        var lon = parseFloat(rtepts[i].getAttribute("lon"));
        if(i==0) entf.init(lat,lon) ;
        routlen += entf.rechne(lat,lon);
        if(lat<latmin) latmin=lat; else if(lat>latmax) latmax=lat;
        if(lon<lonmin) lonmin=lon; else if(lon>lonmax) lonmax=lon;
        route.push(new GLatLng(lat,lon));
        var ext = rtepts[i].getElementsByTagName("extensions");
        if(ext.length) {
          var rpts = JB_GetElementsByTagNameNS(ext[0],"gpxx","rpt"); // Routenpunkte
          for(var k=0;k<rpts.length;k++) {
            var lat = parseFloat(rpts[k].getAttribute("lat"));
            var lon = parseFloat(rpts[k].getAttribute("lon"));
            routlen += entf.rechne(lat,lon);
            if(lat<latmin) latmin=lat; else if(lat>latmax) latmax=lat;
            if(lon<lonmin) lonmin=lon; else if(lon>lonmax) lonmax=lon;
            route.push(new GLatLng(lat,lon));
          }
        }
      }
      routes.push(route);
      routlens.push(Math.round(routlen*10)/10);
    }
    var wpts = xml.documentElement.getElementsByTagName("wpt"); // Waypoints
    waypoints = new Array();
    for(var i=0;i<wpts.length;i++) { // Wegpunktdaten
      var wpt = wpts[i];
      var lat = parseFloat(wpt.getAttribute("lat"));
      var lon = parseFloat(wpt.getAttribute("lon"));
      if(lat<latmin) latmin=lat; else if(lat>latmax) latmax=lat;
      if(lon<lonmin) lonmin=lon; else if(lon>lonmax) lonmax=lon;
      var waypoint = new Object();
      waypoint.lat = lat;
      waypoint.lon = lon;
      waypoint.name = "";
      waypoint.cmt = "";
      waypoint.desc = "";
      var name = wpt.getElementsByTagName("name");
      var cmt = wpt.getElementsByTagName("cmt");
      var desc = wpt.getElementsByTagName("desc");
      if(name.length && name[0].firstChild && name[0].firstChild.length)
        waypoint.name = name[0].firstChild.data;
      if(cmt.length && cmt[0].firstChild && cmt[0].firstChild.length)
        waypoint.cmt = cmt[0].firstChild.data;
      if(desc.length && desc[0].firstChild && desc[0].firstChild.length)
        waypoint.desc = desc[0].firstChild.data;
      waypoints.push(waypoint);
    }
    load = true;
  } // parseGPX
  this.showWpts = function() {
    if (load) {
      delete bilder; bilder = new Array();
      for(var i=0;i<waypoints.length;i++) {
        var waypoint = waypoints[i];
        if(checkImageName(waypoint.name)) {
          bilder[i] = new Image();
          bilder[i].src = waypoint.name;  // Bildurl steckt im Namen
          map.addOverlay(createImgMarker(waypoint));
        }
        else if (waypoint.name.length || waypoint.cmt.length)
          map.addOverlay(createTxtMarker(waypoint));
        else
          map.addOverlay(new GMarker(new GLatLng(waypoint.lat,waypoint.lon)));
      }
    }
  } // showWpts
  this.showTracks = function() {
    if (load) {
       if(hp) {
        hp_diag.label("Strecke in km","H<br />&ouml;<br />h<br />e<br />&nbsp;<br />i<br />n<br />&nbsp;<br />m");
        for(var i=0;i<profile.length;i++) if(profile[i].length) hp_diag.scale(profile[i]);
      }
      if(tracks.length>1) {
        for(var i=0;i<tracks.length;i++) if(chktrk.status[i+1]) {
          map.addOverlay(new GPolyline(tracks[i],tcols[i%tcols.length],2,0.8));
          if(hp&&profile[i].length) hp_diag.plot(profile[i],tcols[i%tcols.length]);
        }
      }
      else if(tracks.length==1) {
        if(chktrk.status[0]) {
          map.addOverlay(new GPolyline(tracks[0],tcols[0],2,0.8));
          if(hp&&profile[0].length) hp_diag.plot(profile[0],tcols[0]);
        }
      }
    }
  } // showTracks
  this.showRoutes = function() {
    if (load) {
      if(routes.length>1) {
        for(var i=0;i<routes.length;i++) if(chkrt.status[i+1])
          map.addOverlay(new GPolyline(routes[i],rcols[i%tcols.length],2,0.8));
      }
      else if(routes.length==1) {
        if(chkrt.status[0])
          map.addOverlay(new GPolyline(routes[0],rcols[0],2,0.8));
      }
    }
  } // showRoutes
  this.show = function(what) {
    map.clearOverlays() ;
    if(hp) hp_diag.init();
//    dieses.rescale();
    if (what.search("w") != -1 ) dieses.showWpts();
    if (what.search("t") != -1 ) dieses.showTracks();
    if (what.search("r") != -1 ) dieses.showRoutes();
  } // show
  this.rescale = function() {
    if(load) {
      map.setCenter(new GLatLng((latmax+latmin)/2,(lonmax+lonmin)/2), zoom);
    }
  } // rescale
  this.Entfernung = function() {
    var ls,bs,sinbs,cosbs,le,be,sinle,cosle,r=6378.137,fak=Math.PI/180,e;
    this.init = function(b,l) {
      le = l*fak;
      be = b*fak;
      with (Math) {
        sinbe = sin(be);
        cosbe = cos(be);
      }
    }
    this.rechne = function(b,l) {
      sinbs = sinbe;
      cosbs = cosbe;
      ls = le ;
      bs = be ;
      le = l*fak;
      be = b*fak;
      with (Math) {
        sinbe = sin(be);
        cosbe = cos(be);
        var arg = round((sinbs*sinbe + cosbs*cosbe*cos(ls-le))*10000000000000)/10000000000000
        e = acos ( arg ) * r;
      }
      return e;
    }
  }
  var createImgMarker = function(waypoint) {
    var marker = new GMarker(new GLatLng(waypoint.lat,waypoint.lon),icon);
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml("<img src='"+waypoint.name+"'\/><br\/>"+waypoint.cmt);
    });
    return marker;
  } // createImgMarker
  var createTxtMarker = function(waypoint) {
    var marker = new GMarker(new GLatLng(waypoint.lat,waypoint.lon));
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml("<strong>"+waypoint.name+"<\/strong><br\/>"+waypoint.cmt);
    });
    return marker;
  } // createTxtMarker
  var checkImageName = function(url) {
    var ext = url.substr(url.lastIndexOf(".")+1).toLowerCase();
    return (ext=="jpg" || ext=="jpeg" || ext=="png" || ext=="gif") ;
  } //  checkImageName
} // makeMap

function JB_GetElementsByTagNameNS(ele,namespace,name) {
  var alltags = ele.getElementsByTagName("*");
  var tagname = namespace.toLowerCase()+":"+name.toLowerCase()
  var tags = new Array();
  for(var i=0;i<alltags.length;i++) if(alltags[i].nodeName.toLowerCase()==tagname) tags.push(alltags[i]);
  return tags;
} // JB_GetElementsByTagNameNS(ele,namespace,name)

function JB_CheckBoxGroup(id,Texte,Label,Farbe,def_stat,clickFunc) {
  var dieses = this;
  var nbx = Texte.length;
  this.nboxen = nbx;
  this.status = new Array(nbx); for(var i=0;i<nbx;i++) this.status[i] = def_stat ;
  var ele;
  var box=document.createElement("div");
  box.style.position = "absolute";
  box.style.display = "inline";
  box.style.height = "1.4em";
  box.style.overflow = "hidden";
  box.style.backgroundColor = "";
  box.style.zIndex = 1000;
  box.style.margin = "0";
  box.style.padding = "0";
//  box.style.color=Farbe;
  box.onmouseover = function() {
    this.style.height = "";
    this.style.overflow = "";
    this.style.backgroundColor = "white";
    this.style.paddingRight = "0.3em";
    this.style.paddingBottom = "0.2em";
  };
  box.onmouseout  = function() {
    this.style.height = "1.4em";
    this.style.overflow = "hidden";
    this.style.backgroundColor = "";
    this.style.paddingRight = "";
    this.style.paddingBottom = "";
  };
  for(var i=0;i<nbx;i++) {
    ele = document.createElement("input");
    ele.type = "checkbox";
    ele.id = Label + i;
    ele.nr = i;
    if(i==0) ele.onclick = function() {
      var l = nbx;
      var n = Label;
      var status = this.checked;
      dieses.status[this.nr] = status;
      for(var j=1;j<l;j++) {
        document.getElementById(n+j).checked=status;
        dieses.status[j] = status;
      }
      clickFunc(dieses,this);
    };
    else     ele.onclick = function() {
      var l = nbx;
      var n = Label;
      var status = false;
      for(var j=1;j<l;j++) status |= document.getElementById(n+j).checked;
      document.getElementById(n+"0").checked = status;
      dieses.status[0] = status==true;
      dieses.status[this.nr] = this.checked;
      clickFunc(dieses,this);
    };
    box.appendChild(ele);
    ele.checked = def_stat;
    ele=document.createElement("span");
    if(i==0 && nbx==1) ele.style.color=Farbe[0];
    else if(i) ele.style.color=Farbe[(i-1)%Farbe.length];
    ele.appendChild(document.createTextNode(Texte[i]));
    box.appendChild(ele);
    if(i<Texte.length-1) box.appendChild(document.createElement("br"));
  }
  ele=document.getElementById(id);
  ele.appendChild(box);
  var spn=document.createElement("span"); // Platzhalter
  spn.appendChild(document.createTextNode(" X "+Texte[0]+" "));
  spn.style.visibility="hidden";
  ele.appendChild(spn);
} // JB_CheckBoxGroup

function JB_addEvent(oTarget, sType, fpDest) {
  var oOldEvent = oTarget[sType];
  if (typeof oOldEvent != "function") {
    oTarget[sType] = fpDest;
  } else {
    oTarget[sType] = function(e) {
      oOldEvent(e);
      fpDest(e);
    }
  }
} // addEvent

// gra
// Version vom 10.12.07
// Jürgen Berkemeier
// www.j-berkemeier.de
function gra(ID) {
 var feld=document.getElementById(ID);
 var dv=document.createElement("div");
 var cont=feld.appendChild(dv);
 var buf=document.createElement("div");
 this.w=parseInt(feld.offsetWidth-1);
 this.h=parseInt(feld.offsetHeight-1);
 var maxbuf=1;
 var bufsize=1;
 var sp = document.createElement("div");
 var col="#000000";
 sp.style.position="absolute";
 sp.style.width="1px";
 sp.style.height="1px";
 sp.style.overflow="hidden";
 sp.style.left="0px";
 sp.style.top="0px";
 sp.style.backgroundColor=col;
 this.setbuf=function(siz) {
  bufsize=maxbuf=Math.max(1,siz);
 }
 this.flush=function() {
  cont.appendChild(buf);
  buf=document.createElement("div");
  bufsize=maxbuf;
 }
 this.punkt=function(x,y,c) {
  if (x<0 || y<0 || x>this.w || y>this.h) return;
  if(c!=col) {col=c;sp.style.backgroundColor=col;}
  var pkt = sp.cloneNode(true);
  pkt.style.left=Math.round(x)+"px";
  pkt.style.top=Math.round(this.h-y)+"px";
  buf.appendChild(pkt);
  bufsize--; if(!bufsize) this.flush();
 } // punkt
 this.ver_linie=function(x,y1,y2,c) {
  if (x<0 || x>this.w) return;
  if ( (y1<0&&y2<0) || (y1>this.h&&y2>this.h) ) return;
  if(c!=col) {col=c;sp.style.backgroundColor=col;}
  y1=Math.max(0,Math.min(this.h,y1));
  y2=Math.max(0,Math.min(this.h,y2));
  var vl = sp.cloneNode(true);
  vl.style.left=Math.round(x)+"px";
  vl.style.top=Math.round(this.h-Math.max(y1,y2))+"px";
  vl.style.height=Math.round(Math.abs(y2-y1)+1)+"px";
  buf.appendChild(vl);
  bufsize--; if(!bufsize) this.flush();
 } // ver_linie
 this.hor_linie=function(x1,x2,y,c) {
  if (y<0 || y>this.h) return;
  if ( (x1<0&&x2<0) || (x1>this.w&&x2>this.w) ) return;
  if(c!=col) {col=c;sp.style.backgroundColor=col;}
  x1=Math.max(0,Math.min(this.w,x1));
  x2=Math.max(0,Math.min(this.w,x2));
  var hl = sp.cloneNode(true);
  hl.style.left=Math.round(Math.min(x1,x2))+"px";
  hl.style.top=Math.round(this.h-y)+"px";
  hl.style.width=Math.round(Math.abs(x2-x1)+1)+"px";
  buf.appendChild(hl);
  bufsize--; if(!bufsize) this.flush();
 } // hor_linie
 this.linie=function(xs,ys,xe,ye,c) {
//  var flag=(maxbuf==1);
//  if(flag) maxbuf=1000;
  xs=Math.round(xs); xe=Math.round(xe);
  ys=Math.round(ys); ye=Math.round(ye);
  var dx=xe-xs;
  var dy=ye-ys;
  if (dx==0 && dy==0) this.punkt(xs,ys,c)
  else if (dx==0) this.ver_linie(xs,ys,ye,c);
  else if (dy==0) this.hor_linie(xs,xe,ys,c);
  else {
   var adx=Math.abs(dx);
   var ady=Math.abs(dy);
   var d=Math.min(adx,ady);
   dx=dx/d;
   dy=dy/d;
   if (adx==ady) {
    for(var x=xs,y=ys,i=0;i<=d;x+=dx,y+=dy,i++) this.punkt(x,y,c) ;
   }
   else if (adx<ady) {
    var dd=dy/Math.abs(dy);
    this.ver_linie(xs,ys,ys+dy/2-dd,c);
    for(var x=xs+dx,y=ys+dy/2,i=1;i<d;x+=dx,y+=dy,i++) this.ver_linie(x,y,y+dy-dd,c) ;
    this.ver_linie(xe,ye-(dy+dd)/2,ye,c);
   }
   else {
    var dd=dx/Math.abs(dx);
    this.hor_linie(xs,xs+dx/2-dd,ys,c);
    for(var x=xs+dx/2,y=ys+dy,i=1;i<d;x+=dx,y+=dy,i++) this.hor_linie(x,x+dx-dd,y,c) ;
    this.hor_linie(xe-(dx+dd)/2,xe,ye,c);
   }
  }
//  if(flag) {maxbuf=1;this.flush();}
 } // linie
 this.del=function() {
  feld.removeChild(cont);
  delete cont;
  delete buf;
  var dv=document.createElement("div");
  cont=feld.appendChild(dv);
  buf=document.createElement("div");
  bufsize=maxbuf;
 } // del
} // gra

// plot
// Version vom 22. 11. 2008
// Jürgen Berkemeier
// www.j-berkemeier.de
var plot = function(id) {
  this.feldid = id;
  this.plotid = id+"plot";
  this.idymin = id+"ymin";
  this.idymax = id+"ymax";
  this.idxmin = id+"xmin";
  this.idxmax = id+"xmax";
  this.idxlabel = id+"xlabel";
  this.idylabel = id+"ylabel";
  this.xmin = 0;
  this.xmax = 0;
  this.ymin = 0;
  this.ymax = 0;
  this.xfak = 0;
  this.yfak = 0;
  this.gr = null;
} // plot
plot.prototype.init = function() {
  this.xfak=this.yfak=0;
  var feld = document.getElementById(this.feldid) ;
  var w = parseInt(feld.offsetWidth-1) - 40;
  var h = parseInt(feld.offsetHeight-1) - 20;
  feld.innerHTML = ""
    +"<table cellpadding=0 cellspacing=0 border=0>"
    +" <tr>"
    +"  <td id='"+this.idymax+"' style='text-align:right;vertical-align:top;padding-right:4px'>&nbsp;</td>"
    +"  <td style='width:"+w+"px;height:"+h+"px;vertical-align:top' rowspan=3 colspan=3>"
    +"   <div id='"+this.plotid+"' style='position:absolute;padding:0px;margin:0px;width:"+w+"px;height:"+h+"px;background-color:#b0b0b0'></div>"
    +"  </td>"
    +" </tr>"
    +" <tr>"
    +"  <td id='"+this.idylabel+"' style='text-align:right;padding-right:4px;vertical-align:middle'>&nbsp;</td>"
    +" </tr>"
    +" <tr>"
    +"  <td id='"+this.idymin+"' style='text-align:right;padding-right:4px;vertical-align:bottom'>&nbsp;</td>"
    +" </tr>"
    +" <tr>"
    +"  <td style='width:40px;height:20px'></td>"
    +"  <td id='"+this.idxmin+"' style='text-align:left'>&nbsp;</td>"
    +"  <td id='"+this.idxlabel+"' style='text-align:center'>&nbsp;</td>"
    +"  <td id='"+this.idxmax+"' style='text-align:right'>&nbsp;</td>"
    +" </tr>"
    +"</table>";
  var rahmen=new gra(this.plotid);
  rahmen.linie(       0,       0,rahmen.w,       0,"black");
  rahmen.linie(rahmen.w,       0,rahmen.w,rahmen.h,"black");
  rahmen.linie(rahmen.w,rahmen.h,       0,rahmen.h,"black");
  rahmen.linie(       0,rahmen.h,       0,       0,"black");
  this.gr=new gra(this.plotid);
  this.gr.setbuf(1000);
} // plot.init
plot.prototype.scale = function(a) {
  if(this.xfak==0 && this.yfak==0) {
    this.xmax = this.xmin = a[0].x;
    this.ymax = this.ymin = a[0].y;
  }
  for(var i=0;i<a.length;i++) {
    var t = a[i];
    if(t.x<this.xmin) this.xmin = t.x;
    if(t.x>this.xmax) this.xmax = t.x;
    if(t.y<this.ymin) this.ymin = t.y;
    if(t.y>this.ymax) this.ymax = t.y;
  }
  var t = this.xmax - this.xmin ;
  t = Math.floor(Math.log(t)/Math.LN10)-1;
  var f = Math.pow(10,t);
  this.xmin = Math.floor(this.xmin/f)*f;
  this.xmax = Math.ceil(this.xmax/f)*f;
  if(this.xmax==this.xmin) { this.xmin -= 0.5; this.xmax += 0.5; }
  this.xfak = this.gr.w/(this.xmax-this.xmin);
  t = this.ymax - this.ymin ;
  t = Math.floor(Math.log(t)/Math.LN10)-1;
  var f = Math.pow(10,t);
  this.ymin = Math.floor(this.ymin/f)*f;
  this.ymax = Math.ceil(this.ymax/f)*f;
  if(this.ymax==this.ymin) { this.ymin -= 0.5; this.ymax += 0.5; }
  this.yfak = this.gr.h/(this.ymax-this.ymin);
  document.getElementById(this.idxmin).firstChild.data = this.xmin ;
  document.getElementById(this.idxmax).firstChild.data = this.xmax ;
  document.getElementById(this.idymin).firstChild.data = this.ymin ;
  document.getElementById(this.idymax).firstChild.data = this.ymax ;
} // plot.scale
plot.prototype.label = function(xlabel,ylabel) {
  document.getElementById(this.idxlabel).innerHTML = xlabel ;
  document.getElementById(this.idylabel).innerHTML = ylabel ;
} // plot.label
plot.prototype.plot = function(a,col) {
  for(var i=0;i<a.length-1;i++)
  this.gr.linie(
   (a[i].x-this.xmin)*this.xfak,
   (a[i].y-this.ymin)*this.yfak,
   (a[i+1].x-this.xmin)*this.xfak,
   (a[i+1].y-this.ymin)*this.yfak,
   col);
  if(this.xmin*this.xmax<0) this.gr.linie(-this.xmin*this.xfak,0,-this.xmin*this.xfak,this.gr.h,"gray");
  if(this.ymin*this.ymax<0) this.gr.linie(0,-this.ymin*this.yfak,this.gr.w,-this.ymin*this.yfak,"gray");
  this.gr.flush();
} // plot.plot

JB_addEvent(window,"onload",function() {
  if(document.getElementsByTagName && GBrowserIsCompatible()) {
    var Map_Nr=0;
    var chkTyp = function(typString) {
      if(typString=="Karte") return G_NORMAL_MAP ;
      if(typString=="Satellit") return G_SATELLITE_MAP ;
      if(typString=="Hybrid") return G_HYBRID_MAP ;
      if(typString=="Oberflaeche") return G_PHYSICAL_MAP ;
      return G_SATELLITE_MAP;
    } // chkTyp
    var divs = document.getElementsByTagName("div");
    var typ = G_SATELLITE_MAP;
    for(var i=0;i<divs.length;i++) {
      var div = divs[i];
      if(div.className) {
        var Klasse = div.className;
        var CN = Klasse.toLowerCase().indexOf("gpxview");
        if(CN>-1) {
          if(div.id) var Id = div.id;
          else {
            var Id = "map"+(Map_Nr++);
            div.id = Id;
          }
          var GPX = Klasse.substring(CN).split()[0];
          GPX = GPX.split(":") ;
          if(GPX.length==3) {
            typ = chkTyp(GPX[2]);
          }
          if(GPX[1].length) {
            window["Karte_"+Id] = new makeMap(Id);
            window["Karte_"+Id].Spur(GPX[1],typ);
          }
        }
      }
    }
    var buttons = document.getElementsByTagName("button");
    for(var i=0;i<buttons.length;i++) {
      var button = buttons[i];
      if(button.className) {
        var Klasse = button.className;
        var CN = Klasse.toLowerCase().indexOf("gpxview");
        if(CN>-1) {
          var cmd = Klasse.substring(CN).split()[0];
          cmd = cmd.split(":") ;
          if(cmd.length>2) {
            var Id = cmd[1];
            switch(cmd[2]) {
              case "skaliere":
                ( function() {
                  var mapid = "Karte_"+Id;
                  button.onclick = function(){window[mapid].rescale()};
                } )();
                break;
              case "lade":
                if(cmd.length>3) {
                  if(cmd.length>4) typ = chkTyp(cmd[4]);
                  else typ = G_SATELLITE_MAP;
                  ( function() {
                    var fn = cmd[3];
                    var mapid = "Karte_"+Id;
                    var tp = typ;
                    button.onclick = function(){window[mapid].Spur(fn,tp)};
                  } )();
                }
                break;
              default:
                break;
            }
          }
        }
      }
    }
    JB_addEvent(window,"onunload",GUnload);
  }
  else alert("Ihr Browser unterstützt nicht die benötigten Methoden!");
});
