WME GPS Track View

Draws and visualizes custom GPS tracks in Waze Map Editor

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name                WME GPS Track View
// @namespace           http://userscripts.org/scripts/show/461960
// @description         Draws and visualizes custom GPS tracks in Waze Map Editor
// @include             https://www.waze.com/editor/*
// @include             https://www.waze.com/*/editor/*
// @include             https://editor-beta.waze.com/*
// @version             1.2.4
// @grant               none
// @copyright           2014 wlodek76
// @copyright           2014 FZ69617
// ==/UserScript==

var wmech_version = "1.2.4";

/*
 * Version history:
 *
 * 1.2.4 (20141005)
 * - New: Tracks layer summary with clean tracks button.
 * - Revert: Temporary from previous version removed.
 *
 * 1.2.3 (20141004)
 * - Improvement: Map panning to the center of added points.
 * - Temporary: Tracks layer cleaning before track addition.
 * - Other: Minor code changes.
 */



var gps_num_tracks = 0;
var gps_num_points = 0;
var gps_total_distance = 0;


//---------------------------------------------------------------------------------------
function bootstrap_WME_GPS_Track()
{
  var bGreasemonkeyServiceDefined = false;

  try {
    bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object");
  }
  catch (err) { /* Ignore */ }

  if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) {
    unsafeWindow    = ( function () {
      var dummyElem = document.createElement('p');
      dummyElem.setAttribute('onclick', 'return window;');
      return dummyElem.onclick();
    }) ();
  }

    /* begin running the code! */
    setInterval(Draw_WME_GPS_Track, 1000);
    
    console.log("WME GPS Track View " + wmech_version + " loaded.");
}
//---------------------------------------------------------------------------------------
function min_to_deg(v)
{
    var fmin = parseFloat(v) * 0.01;
    var fdeg = parseInt(fmin);
    fmin -= fdeg;
    return (fdeg + fmin * 1.66666666666666666);
}
//---------------------------------------------------------------------------------------
function calc_azym(pt1, pt2, kierWidth)
{
    var dx = pt2.x - pt1.x;
    var dy = pt2.y - pt1.y;
    var azym = (Math.atan2(dx, dy) * 180.0 / Math.PI);
    if (azym > 360) azym -= 360;
    if (azym < 0)   azym += 360;
    return azym;
}
//---------------------------------------------------------------------------------------
function gps_parse()
{
    var gps_wazeMap = unsafeWindow.Waze.map;
    var gps_wazeModel = unsafeWindow.Waze.model;
    var gps_OpenLayers = unsafeWindow.OpenLayers;
    
    var obj1 = document.getElementById('wme_gps_layer_content');
    var obj2 = document.getElementById('wme_gps_layer_info');
    var obj3 = document.getElementById('wme_gps_layer_speed');
    if (obj1 == null) return;
    if (obj2 == null) return;
    if (obj3 == null) return;

    var str = obj1.value;
    var speedmode = obj3.checked;
    
    var points = [];
    var lineFeatures = [];
    var pointFeatures = [];
              
    var proj1 = new OpenLayers.Projection('EPSG:4326');
    var proj2 = gps_wazeMap.getProjectionObject();
    
    var time1 = 0;
    var time2 = 0;
                     
    var pt1 = null;
    var pt2 = null;
                     
    var kier1 = 0;
    var kier2 = 0;
    var kiercolor  = new Array();
    var speedcolor = new Array();

    kiercolor.push('#ff0000');
    kiercolor.push('#00ff40');
    kiercolor.push('#00ff40');
    kiercolor.push('#0000ff');
    kiercolor.push('#0000ff');
    kiercolor.push('#fff000');
    kiercolor.push('#fff000');
    kiercolor.push('#ff0000');

    speedcolor[0]  = '#000000';
    speedcolor[1]  = '#505060';
    speedcolor[2]  = '#b0b0c0';
    speedcolor[3]  = '#FFFF00';
    speedcolor[4]  = '#68fdda';
    speedcolor[5]  = '#00d508';
    speedcolor[6]  = '#f68400';
    speedcolor[7]  = '#8e3f04';
    speedcolor[8]  = '#ff525a';
    speedcolor[9]  = '#e00000';
    speedcolor[10] = '#2594fb';
    speedcolor[11] = '#0500c9';
    speedcolor[12] = '#fa00e4';
    speedcolor[13] = '#68008d';
    speedcolor[14] = '#370143';
    speedcolor[15] = '#370143';
    speedcolor[16] = '#370143';
    speedcolor[17] = '#370143';
    speedcolor[18] = '#370143';
    speedcolor[19] = '#370143';
    speedcolor[20] = '#370143';
    
    var kierWidth = 360 / kiercolor.length;
    kiercolor.push(kiercolor[0]);
    
    var nmea_format = str.indexOf("$GPGGA");
    var gpx_format  = str.indexOf("<trkpt");
    var kml_format1 = str.indexOf("<gx:coord>");
    var kml_format2 = str.indexOf("<LineString>");

    var numPoints = 0;
    var sumDist = 0;
    
    if (nmea_format >= 0) {
        
        pt1 = null;
        pt2 = null;
        kier1 = 0;
        kier2 = 0;
        points.length = 0;
       
        var p = -1;
        for(;;) {
            p = str.indexOf("$GPGGA", p+1);
         if (p < 0) break;
            
            var s = str.substr(p, 80);
            var d = s.split(",");
            
            var lat = min_to_deg(d[2]);
            var lon = min_to_deg(d[4]);
            if (d[3] == 'S') lat = -lat;
            if (d[5] == 'W') lon = -lon;
            
            var pt2 = new gps_OpenLayers.Geometry.Point(lon, lat).transform(proj1, proj2);
            numPoints++;
            
            time1 = time2;
            time2 = parseInt(d[1]);
            var s = time2 % 100;
            time2 = (time2 - s) / 100;
            var m = time2 % 100;
            time2 = (time2 - m) / 100;
            var g = time2 % 100;
            time2 = (g*3600) + (m*60) + s;
            
            var angle = 0;
            var stop = 0;
            var dist = 0;
            var speed = 0;
            var dt = 0;
               
            if (pt1 != null && pt2 != null) {
                angle = calc_azym(pt1, pt2, kierWidth);
                dist = pt1.distanceTo(pt2);
                dt = Math.abs(time2 - time1);
                
                kier2 = parseInt(angle / kierWidth);
                
                if (speedmode) {
                    var line = new OpenLayers.Geometry.LineString( [pt1, pt2] );
                    var geodist = line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    
                    var kmh = (geodist / dt) * 3.6;
                    speed = parseInt(kmh / 10);
                    if (speed < 0)  speed = 0;
                    if (speed > 20) speed = 20;
                    kier2 = speed;
                    if (dist < 5 && kier1<=2 && kier2<=2) continue;
                }
                else {
                    if (dist < 5) continue;
                }
                
                if (dist > 10000)   stop |= 1;
                if (dt > 60)        stop |= 1;
                if (kier2 != kier1) stop |= 2;

            }
              
            //var ptFeature = new OpenLayers.Feature.Vector(pt1, {strokeColor: '#000000', labelText: '', lineWidth: 1 } );
            //pointFeatures.push(ptFeature);
           
            if (stop) {
                if (points.length >= 2) {
                    var k = kiercolor[kier1];
                    var szer = 3;
                    
                    if (speedmode) {
                        k = speedcolor[kier1];
                        szer = 6;
                    }
                    
                    var line = new gps_OpenLayers.Geometry.LineString(points);
                    sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                    lineFeatures.push(lineFeature);
                }
                points.length = 0;
                
                if (stop == 2) points.push(pt1);
            }

            points.push(pt2);
            pt1 = pt2;
            kier1 = kier2;
        }
    }
    

    
    
    
    if (gpx_format >= 0) {
        
        pt1 = null;
        pt2 = null;
        kier1 = 0;
        kier2 = 0;
        points.length = 0;
       
        var p = -1;
        var pend = str.indexOf("</trkseg");
        for (;;) {
            p = str.indexOf("<trkpt", p+1);
            if (p < 0) break;
            
            if (p > pend) {
                if (points.length >= 2) {
                    var k = kiercolor[kier1];
                    var szer = 3;
                    
                    if (speedmode) {
                        k = speedcolor[kier1];
                        szer = 6;
                    }
                    
                    var line = new gps_OpenLayers.Geometry.LineString(points);
                    sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                    lineFeatures.push(lineFeature);
                }

                pt1 = null;
                pt2 = null;
                kier1 = 0;
                kier2 = 0;
                points.length = 0;

                pend = str.indexOf("</trkseg", p+1);
            }

            var s = str.substr(p, 60);
            
            var lat = 0;
            var lon = 0;
            var plat = s.indexOf('lat="');
            var plon = s.indexOf('lon="');
            if (plat>=0 && plon>=0) {
                lat = parseFloat( s.substr(plat + 5, 10) );
                lon = parseFloat( s.substr(plon + 5, 10) );
            }

            var pt2 = new gps_OpenLayers.Geometry.Point(lon, lat).transform(proj1, proj2); 
            numPoints++;
            
            var angle = 0;
            var stop = 0;
            var dist = 0;
            var speed = 0;
            var dt = 0;
               
            if (speedmode) {
                var p_speed  = str.indexOf("<speed>", p);
                var p_time   = str.indexOf("<time>",  p);
                var p_trkend = str.indexOf("</trkpt", p);
                
                if (p_time > p && p_time < p_trkend) {
                    var s       = str.substr(p_time+6, 20);
                    var rok     = parseInt( s.substr(0, 4) );
                    var mies    = parseInt( s.substr(5, 2) );
                    var dzien   = parseInt( s.substr(8, 2) );
                    var godz    = parseInt( s.substr(11, 2) );
                    var minut   = parseInt( s.substr(14, 2) );
                    var sek     = parseInt( s.substr(17, 2) );
                    
                    time1 = time2;
                    time2 = (dzien*24*3600) + (godz*3600) + (minut*60) + sek;
                    dt = Math.abs(time2 - time1);
                    
                    var line = new OpenLayers.Geometry.LineString( [pt1, pt2] );
                    var geodist = line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    
                    var kmh = (geodist / dt) * 3.6;
                    speed = parseInt(kmh / 10);
                    if (speed < 0)  speed = 0;
                    if (speed > 20) speed = 20;
                }
                else {
                    if (p_speed > p && p_speed < p_trkend) {
                        var s   = str.substr(p_speed+7, 8);
                        var kmh = parseFloat(s) * 3.6;
                        speed = parseInt(kmh / 10);
                        if (speed < 0)  speed = 0;
                        if (speed > 20) speed = 20;
                    }
                }

            }
            
            if (pt1 != null && pt2 != null) {
                angle = calc_azym(pt1, pt2, kierWidth);
                dist = pt1.distanceTo(pt2);
                
                kier2 = parseInt(angle / kierWidth);
                
                if (speedmode) {
                    kier2 = speed;
                    if (dist < 5 && kier1<=2 && kier2<=2) continue;
                }
                else {
                    if (dist < 5) continue;
                }
                
                if (dist > 10000)   stop |= 1;
                if (kier2 != kier1) stop |= 2;

            }
              
            //var ptFeature = new OpenLayers.Feature.Vector(pt1, {strokeColor: '#000000', labelText: '', lineWidth: 1 } );
            //pointFeatures.push(ptFeature);
            
            if (stop) {
                if (points.length >= 2) {
                    var k = kiercolor[kier1];
                    var szer = 3;
                    
                    if (speedmode) {
                        k = speedcolor[kier1];
                        szer = 6;
                    }
                    
                    var line = new gps_OpenLayers.Geometry.LineString(points);
                    sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                    lineFeatures.push(lineFeature);
                }
                points.length = 0;
                
                if (stop == 2) points.push(pt1);
            }

            points.push(pt2);
            pt1 = pt2;
            kier1 = kier2;
        }
    }
    
    
    if (kml_format1 >= 0) {
        
        pt1 = null;
        pt2 = null;
        kier1 = 0;
        kier2 = 0;
        points.length = 0;

        var p = -1;
        var pend = str.indexOf("</gx:Track>");
        
        for(;;) {
            p = str.indexOf("<gx:coord>", p+1);
            if (p < 0) break;
            
            if (p > pend) {
                if (points.length >= 2) {
                    var k = kiercolor[kier1];
                    var szer = 3;
                    
                    if (speedmode) {
                        k = speedcolor[kier1];
                        szer = 6;
                    }
                    
                    var line = new gps_OpenLayers.Geometry.LineString(points);
                    sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                    lineFeatures.push(lineFeature);
                }
                pt1 = null;
                pt2 = null;
                kier1 = 0;
                kier2 = 0;
                points.length = 0;

                pend = str.indexOf("</gx:Track>", pend + 1);
            }
            
            var s = str.substr(p + 10, 30);
            var coord = s.split(" ");
            
            var lon = parseFloat( coord[0] );
            var lat = parseFloat( coord[1] );
            
            var pt2 = new gps_OpenLayers.Geometry.Point(lon, lat).transform(proj1, proj2);
            numPoints++;
            
            var angle = 0;
            var stop = 0;
            var dist = 0;
            var speed = 0;
            var dt = 0;
               
            if (pt1 != null && pt2 != null) {
                angle = calc_azym(pt1, pt2, kierWidth);
                dist = pt1.distanceTo(pt2);
                dt = 0;
                
                kier2 = parseInt(angle / kierWidth);
                
                if (speedmode) {
                    kier2 = 0;
                }
                else {
                    if (dist < 5) continue;
                }
                
                if (dist > 10000)   stop |= 1;
                if (dt > 60)        stop |= 1;
                if (kier2 != kier1) stop |= 2;

            }
            
            
            if (stop) {
                if (points.length >= 2) {
                    var k = kiercolor[kier1];
                    var szer = 3;
                    if (speedmode) {
                        k = speedcolor[kier1];
                        szer = 6;
                    }
                    
                    var line = new gps_OpenLayers.Geometry.LineString(points);
                    sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                    lineFeatures.push(lineFeature);
                }
                points.length = 0;
                
                if (stop == 2) points.push(pt1);
            }
            
            points.push(pt2);
            pt1 = pt2;
            kier1 = kier2;
        }
    }
    
    else if (kml_format2 >= 0) {
        
        pt1 = null;
        pt2 = null;
        kier1 = 0;
        kier2 = 0;
        points.length = 0;

        var p = -1;
        
        for(;;) {
            p = str.indexOf("<LineString>", p + 1);
            if (p < 0) break;
            
            var block_start = str.indexOf("<coordinates>", p);
            var block_end   = str.indexOf("</coordinates>", p);
            
            if (block_start>=0 && block_end>=0) {
                block_start += 13;
                var s = str.substr(block_start, block_end - block_start);
                var coords = s.split(" ");
                
                pt1 = null;
                pt2 = null;
                kier1 = 0;
                kier2 = 0;
                points.length = 0;
                
                for(var i=0; i<coords.length; i++) {
                    
                    var xyz = coords[i].split(",");
                    if (xyz[0]=='' || xyz[1]=='') continue;
                    var lon = parseFloat(xyz[0]);
                    var lat = parseFloat(xyz[1]);
                    
                    var pt2 = new gps_OpenLayers.Geometry.Point(lon, lat).transform(proj1, proj2);
                    numPoints++;
                    
                    var angle = 0;
                    var stop = 0;
                    var dist = 0;
                    var speed = 0;
                    var dt = 0;
                    
                    if (pt1 != null && pt2 != null) {
                        angle = calc_azym(pt1, pt2, kierWidth);
                        dist = pt1.distanceTo(pt2);
                        dt = Math.abs(time2 - time1);
                        
                        kier2 = parseInt(angle / kierWidth);
                        
                        if (speedmode) {
                            kier2 = 0;
                        }
                        else {
                            if (dist < 5) continue;
                        }
                        
                        if (dist > 10000)   stop |= 1;
                        if (dt > 60)        stop |= 1;
                        if (kier2 != kier1) stop |= 2;
                        
                    }
                    
                    
                    if (stop) {
                        if (points.length >= 2) {
                            var k = kiercolor[kier1];
                            var szer = 3;
                            
                            if (speedmode) {
                                k = speedcolor[kier1];
                                szer = 6;
                            }
                            
                            var line = new gps_OpenLayers.Geometry.LineString(points);
                            sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                            var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                            lineFeatures.push(lineFeature);
                        }
                        points.length = 0;
                        
                        if (stop == 2) points.push(pt1);
                    }
                    
                    points.push(pt2);
                    pt1 = pt2;
                    kier1 = kier2;
                    
                }
                
                if (points.length >= 2) {
                    var k = kiercolor[kier1];
                    var szer = 3;
                    
                    if (speedmode) {
                        k = speedcolor[kier1];
                        szer = 6;
                    }
                    
                    var line = new gps_OpenLayers.Geometry.LineString(points);
                    sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                    var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                    lineFeatures.push(lineFeature);
                }
                
                
            }
        }
    }
    
        if (points.length >= 2) {
            var k = kiercolor[kier1];
            var szer = 3;
            
            if (speedmode) {
                k = speedcolor[kier1];
                szer = 6;
            }
            
            var line = new gps_OpenLayers.Geometry.LineString(points);
            sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
            var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
            lineFeatures.push(lineFeature);
            points.length = 0;
        }
    
    
    if (lineFeatures.length == 0) {
        
        pt1 = null;
        pt2 = null;
        kier1 = 0;
        kier2 = 0;
        points.length = 0;
        
        var lines = str.split("\n");
        
        if (lines.length >= 5) {
            var l0 = lines[0].split(',');
            var l1 = lines[1].split(',');
            var l2 = lines[2].split(',');
            var l3 = lines[3].split(',');
            var l4 = lines[4].split(',');
            var s0 = '';
            var s1 = '';
            var s2 = '';
            var s3 = '';
            var s4 = '';
            if (l0.length >= 2) s0 = l0[1].trim().toUpperCase();
            if (l1.length >= 2) s1 = l1[1].trim().toUpperCase();
            if (l2.length >= 2) s2 = l2[1].trim().toUpperCase();
            if (l3.length >= 2) s3 = l3[1].trim().toUpperCase();
            if (l4.length >= 2) s4 = l4[1].trim().toUpperCase();
            var len = s0.length + s1.length + s2.length + s3.length + s4.length;
            var c0 = s0.charCodeAt(0);
            var c1 = s1.charCodeAt(0);
            var c2 = s2.charCodeAt(0);
            var c3 = s3.charCodeAt(0);
            var c4 = s4.charCodeAt(0);
            
            if ( len==5 && s0=="S" && c1>=65 && c1<=90 && c2>=65 && c2<=90 && c3>=65 && c3<=90 && c4>=65 && c4<=90 ) {
                
                for(var i=1; i<lines.length; i++) {
                    
                    var line = lines[i].split(',');
                    if (line.length < 5) continue;
                    
                    var mode = line[1].trim();
                    
                    if (mode != 'A') { numPoints++; continue; }
                    
                    var lon = parseInt(line[2].trim()) / 1000000.0;
                    var lat = parseInt(line[3].trim()) / 1000000.0;
                    
                    var pt2 = new gps_OpenLayers.Geometry.Point(lon, lat).transform(proj1, proj2);
                    numPoints++;
                    
                    time1 = time2;
                    time2 = parseInt(line[0]);
                    
                    var angle = 0;
                    var stop = 0;
                    var dist = 0;
                    var speed = 0;
                    var dt = 0;
                    
                    if (pt1 != null && pt2 != null) {
                        angle = calc_azym(pt1, pt2, kierWidth);
                        dist = pt1.distanceTo(pt2);
                        dt = Math.abs(time2 - time1);
                        
                        kier2 = parseInt(angle / kierWidth);
                        
                        if (speedmode) {
                            var line = new OpenLayers.Geometry.LineString( [pt1, pt2] );
                            var geodist = line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                            
                            var kmh = (geodist / dt) * 3.6;
                            speed = parseInt(kmh / 10);
                            if (speed < 0)  speed = 0;
                            if (speed > 20) speed = 20;
                            kier2 = speed;
                            if (dist < 5 && kier1<=2 && kier2<=2) continue;
                        }
                        else {
                            if (dist < 5) continue;
                        }
                        
                        if (dist > 10000)   stop |= 1;
                        if (dt > 60)        stop |= 1;
                        if (kier2 != kier1) stop |= 2;
                    }
                    
                    
                    if (stop) {
                        if (points.length >= 2) {
                            var k = kiercolor[kier1];
                            var szer = 3;
                            
                            if (speedmode) {
                                k = speedcolor[kier1];
                                szer = 6;
                            }
                            
                            var line = new gps_OpenLayers.Geometry.LineString(points);
                            sumDist += line.getGeodesicLength(new OpenLayers.Projection("EPSG:900913"));
                            var lineFeature = new gps_OpenLayers.Feature.Vector(line, {strokeColor: k, labelText: '', lineWidth: szer } );
                            lineFeatures.push(lineFeature);
                        }
                        points.length = 0; //points = []; //points.splice(0, 99999999);
                        
                        if (stop == 2) points.push(pt1);
                    }
                    
                    points.push(pt2);
                    pt1 = pt2;
                    kier1 = kier2;                
                }
            }
            
        }
    }
    
    
    
    var layers = gps_wazeMap.getLayersBy("uniqueName","__WME_GPS_Track");
    if(layers.length != 0) {
        
        var gps_layer = layers[0];
        


        if (lineFeatures.length > 0)  gps_layer.addFeatures(lineFeatures);
        if (pointFeatures.length > 0) gps_layer.addFeatures(pointFeatures);
        
        // go to the center of added features
        if (lineFeatures.length > 0 || pointFeatures.length > 0) {
            var bounds = new OpenLayers.Bounds();

            for (var i = 0; i < lineFeatures.length; ++i) {
                var line = lineFeatures[i];
                bounds.extend(line.geometry.bounds);
            }
            for (var i = 0; i < pointFeatures.length; ++i) {
                var point = pointFeatures[i];
                bounds.extend(point.geometry.bounds);
            }

            var center = bounds.getCenterPixel();
            var zoom = unsafeWindow.Waze.map.getZoom();
            unsafeWindow.Waze.map.setCenter([center.x, center.y], zoom);
        }
    }
    
    if (lineFeatures.length > 0) {
        obj1.value = '';
        
        gps_num_tracks += 1;
        gps_num_points += numPoints;
        gps_total_distance += sumDist;
    }
    
    obj2.innerHTML = 'Processed '

        + numPoints + ' point' + (numPoints != 1 ? 's' : '') + ', '
        + parseInt(sumDist/10) / 100 + ' km';
    
    updateSummary();
}
//---------------------------------------------------------------------------------------
function gps_clear()
{
    var gps_wazeMap = unsafeWindow.Waze.map;

    var layers = gps_wazeMap.getLayersBy("uniqueName","__WME_GPS_Track");
    if(layers.length != 0) {
        
        var gps_layer = layers[0];
        
        gps_layer.removeAllFeatures();
    }
    
    gps_num_tracks = 0;
    gps_num_points = 0;
    gps_total_distance = 0;
    
	updateSummary();
}
//---------------------------------------------------------------------------------------
function updateSummary() {
    var msg = '';
    var clear_display = 'inline';
    
    if (gps_num_tracks == 0) {
        msg = 'No tracks';
        clear_display = 'none';
    } else {
        msg = gps_num_tracks + ' track' + (gps_num_tracks != 1 ? 's' : '') + ', '
            + gps_num_points + ' point' + (gps_num_points != 1 ? 's' : '') + ', '
            + parseInt(gps_total_distance/10) / 100 + 'km';
    }
    
    document.getElementById('wme_gps_layer_summary').innerHTML = msg;
    document.getElementById("wme_gps_layer_clear_button").style.display = clear_display;
}
//---------------------------------------------------------------------------------------
function Draw_WME_GPS_Track()
{
    if(document.getElementById('wme_gps_layer') == null) {
    
        var cnt = '';
        cnt += '<br><div id="wme_gps_layer" style="color:#000000; ">';
        cnt += '<b>GPS Track View:</b>';
        cnt += '<textarea id="wme_gps_layer_content" style="font-family: Tahoma; font-size:9px; min-width:270px; max-width:270px; width:270px; min-height:100px; height: 100px; " ';
        cnt += 'placeholder="Paste a GPS track (nmea, gpx, kml, gps.csv) here..." ></textarea>';
        cnt += '<br>';
        cnt += '</div>';

        var add_btn = $('<button id="wme_gps_layer_add_button" title="" >Add track</button>');
        add_btn.click(gps_parse);

        var clear_btn = $('<button id="wme_gps_layer_clear_button" title="" style="display:none;" >Clear tracks</button>');
        clear_btn.click(gps_clear);
        
        var spd = '&nbsp;&nbsp;&nbsp;<input id="wme_gps_layer_speed" type="checkbox" title="Colour GPS tracks by speed" ><span style="font-family: Tahoma; font-size:9px; position:relative; top:-3px;"> Speed</span>';

        var info = '<p style="font-family: Tahoma; font-size:9px; color:#808080; " id="wme_gps_layer_info" ></p>';

        var summary = '<p id="wme_gps_layer_summary" ></p>';

        $("#sidepanel-drives").append(cnt);
        $("#sidepanel-drives").append(add_btn);
        $("#sidepanel-drives").append(spd);
        $("#sidepanel-drives").append(info);
        $("#sidepanel-drives").append(summary);
        $("#sidepanel-drives").append(clear_btn);

        updateSummary();
        
        return;
    }

    var gps_wazeMap = unsafeWindow.Waze.map;
    var gps_wazeModel = unsafeWindow.Waze.model;
    var gps_OpenLayers = unsafeWindow.OpenLayers;

    if (gps_wazeMap == null) return;
    if (gps_wazeModel == null) return;
    if (gps_OpenLayers == null) return;

    var layers = gps_wazeMap.getLayersBy("uniqueName","__WME_GPS_Track");
    if(layers.length == 0) {
         var gps_style = new gps_OpenLayers.Style({
                strokeDashstyle: 'solid',
                strokeColor : "${strokeColor}",
                strokeOpacity: 1.0,
                strokeWidth: "${lineWidth}",
                //strokeLinecap: 'square',
                fillColor: '#000000',
                fillOpacity: 1.0,
                pointRadius: 2,
                fontWeight: "normal",
                label : "${labelText}",
                fontFamily: "Tahoma, Courier New",
                labelOutlineColor: "#FFFFFF",
                labelOutlineWidth: 2,
                fontColor: '#000000',
                fontSize: "10px"
        });

        var gps_mapLayer = new gps_OpenLayers.Layer.Vector("GPS Track View", {
            displayInLayerSwitcher: true,
            uniqueName: "__WME_GPS_Track",
            styleMap: new gps_OpenLayers.StyleMap(gps_style)
        });
        
        I18n.translations.en.layers.name["__WME_GPS_Track"] = "GPS Track View";
        gps_wazeMap.addLayer(gps_mapLayer);
        gps_mapLayer.setVisibility(true);
        
        return;
    }
    
}
//---------------------------------------------------------------------------------------
bootstrap_WME_GPS_Track();