Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Create your path as usual with Google Earth
  2. Save it as a .kml file (not .kmz)
  3. Run the this script

The current version is KML 2.2

Code Block
 /**
 * Compute distance in Google Earth KML path file from a path
 * @author Marc DEXET ( marcdexet [at] gmail [dot] org )
*/
class Point {
    def lat
    def lon
    public Point(){}

    public Point(String gps) {
        def xyz = gps.tokenize(',');
        lat = Double.parseDouble( xyz[1] )
        lon = Double.parseDouble( xyz[0] )
    }
    public String toString() {
        return "LAT: ${lat} LON: ${lon}"
    }

    public static double distance(Point p0, Point p1) {
        return Haversine.compute(p0, p1)
    }
}

/**
 * List of Points
 */
class PointList {
    def points
    def distance
    def partiels = []

    public PointList( List points ) {
        this.points = points
        compute()
    }

    void compute() {
        def nbPointList = points.size()
        distance = 0;
        partiels = []
        for( idx in 1..(nbPointList-1) ) {
            def p0 = points[(idx-1)]
            def p1 = points[idx]
            def dist = Point.distance(p0,p1)
            partiels << dist
            distance = distance+dist
        }
    }

}
/**
 * Haversine algorithmus
 * (thanks to http://www.movable-type.co.uk/scripts/latlong.html)
 */
class Haversine {
    static double R = 6371

    static double compute(Point p1, Point p2) {
        def dLat = Math.toRadians(p2.lat-p1.lat);
        def dLon = Math.toRadians(p2.lon-p1.lon);
        def a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos( Math.toRadians(p1.lat) ) *
                Math.cos( Math.toRadians(p2.lat) ) * Math.sin(dLon/2) * Math.sin(dLon/2);
        def c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        def d = R * c;
        return d
    }

}

class KmlParser {
    static ns = new groovy.xml.Namespace("http://earth.google.com/kml/2.2", 'ns')
    List parse( Object input ) {
            def kml = new groovy.util.XmlParser().parse( input );
            def coords = kml[ ns.Document ][ ns.Placemark ][ ns.LineString ][ ns.coordinates ].text()
            def myList = coords.tokenize();
            def points = []
            myList.each{ gestring -> points << new Point(gestring) }
            return points;
    }
}

// Application

def kmlParser = new KmlParser()
def points = kmlParser.parse( args[0] )
def PointList pointList = new PointList( points )
def partiels = pointList.partiels;
def distance = pointList.distance;

java.text.DecimalFormat f = new java.text.DecimalFormat( "0.000" );
java.text.DecimalFormat n = new java.text.DecimalFormat( "00" );
println "Distance totale: ${f.format(distance)} km"
partiels.eachWithIndex { d, i ->
    println "${n.format(i)}) ${f.format(d)} km"
}

Archives

KML 2.1

Code Block

/**
 * Compute distance in Google Earth KML path file from a path
 * @author Marc DEXET ( marcdexet [at] gmail [dot] org )
*/
class Point {
    def lat
    def lon
    public Point(){}

    public Point(String gps) {
        def xyz = gps.tokenize(',');
        lat = Double.parseDouble( xyz[1] )
        lon = Double.parseDouble( xyz[0] )
    }
    public String toString() {
        return "LAT: ${lat} LON: ${lon}"
    }

    public static double distance(Point p0, Point p1) {
        return Haversine.compute(p0, p1)
    }
}

/**
 * List of Points
 */
class PointList {
    def points
    def distance
    def partiels = []

    public PointList( List points ) {
        this.points = points
        compute()
    }

    void compute() {
        def nbPointList = points.size()
        distance = 0;
        partiels = []
        for( idx in 1..(nbPointList-1) ) {
            def p0 = points[(idx-1)]
            def p1 = points[idx]
            def dist = Point.distance(p0,p1)
            partiels << dist
            distance = distance+dist
        }
    }

}
/**
 * Haversine algorithmus
 * (thanks to http://www.movable-type.co.uk/scripts/latlong.html)
 */
class Haversine {
    static double R = 6371

    static double compute(Point p1, Point p2) {
        def dLat = Math.toRadians(p2.lat-p1.lat);
        def dLon = Math.toRadians(p2.lon-p1.lon);
        def a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos( Math.toRadians(p1.lat) ) *
                Math.cos( Math.toRadians(p2.lat) ) * Math.sin(dLon/2) * Math.sin(dLon/2);
        def c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        def d = R * c;
        return d
    }

}

class KmlParser {
    static ns = new groovy.xml.Namespace("http://earth.google.com/kml/2.1", 'ns')

    List parse( Object input ) {
            def kml = new groovy.util.XmlParser().parse( input );
            def coords = kml[ ns.Document ][ ns.Placemark ][ ns.LineString ][ ns.coordinates ].value[0]
            def myList = coords.tokenize();
            def points = []
            myList.each{ gestring -> points << new Point(gestring) }
            return points;
    }
}

// Application

def kmlParser = new KmlParser()
def points = kmlParser.parse( args[0] )
def PointList pointList = new PointList( points )
def partiels = pointList.partiels;
def distance = pointList.distance;

java.text.DecimalFormat f = new java.text.DecimalFormat( "0.000" );
java.text.DecimalFormat n = new java.text.DecimalFormat( "00" );
println "Distance totale: ${f.format(distance)} km"
partiels.eachWithIndex { d, i ->
    println "${n.format(i)}) ${f.format(d)} km"
}