Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Reducing coordinate density in KML files. Original script by Ben Buckman.

View distance.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* */
/* Simple node js module to get distance between two coordinates. */
/* */
/* Code transformed from Chris Veness example code - please refer to his website for licensing */
/* questions. */
/* */
/* */
/* Latitude/longitude spherical geodesy formulae & scripts (c) Chris Veness 2002-2011 */
/* - www.movable-type.co.uk/scripts/latlong.html */
/* */
/* */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
 
/** Converts numeric degrees to radians */
if(typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function () {
return this * Math.PI / 180;
}
}
 
// start and end are objects with latitude and longitude
//decimals (default 2) is number of decimals in the output
//return is distance in kilometers.
exports.getDistance = function(start, end, decimals) {
decimals = decimals || 2;
var earthRadius = 6371; // km
lat1 = parseFloat(start.latitude);
lat2 = parseFloat(end.latitude);
lon1 = parseFloat(start.longitude);
lon2 = parseFloat(end.longitude);
 
var dLat = (lat2 - lat1).toRad();
var dLon = (lon2 - lon1).toRad();
var lat1 = lat1.toRad();
var lat2 = lat2.toRad();
 
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = earthRadius * c;
return Math.round(d * Math.pow(10, decimals)) / Math.pow(10, decimals);
};
View distance.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
// reduce the coordinate density of a KML file.
// you will need the distance.js file too.
 
var async = require('async')
, fs = require('fs')
, path = require('path')
, distance = require('distance');
var argv = require('optimist')
.usage('Usage: $0 --in [PATH] --out [PATH] --reduce [NUM] --distance [NUM]')
.describe('in', 'source KML file')
.describe('out', 'write to new KML file')
.describe('reduce', 'Preserve 1/N coordinates. 1=all, 4=25%, 10=10%. Default 2 (50%).')
.describe('distance', 'Minimum distance between each coordinates (in Km)')
.demand(['in', 'out', 'reduce', 'distance'])
.default({'reduce': 2, 'distance':1})
.argv;
 
try {
if (isNaN(argv.reduce) || argv.reduce < 1 || argv.reduce % 1 !== 0) {
throw("--reduce has to be an integer >= 1");
}
if (isNaN(argv.distance) || argv.distance < 1) {
throw("--distance has to be an number >= 1");
}
}
catch(e) {
console.error(e);
process.exit(1);
}
 
var origXml, newXml = '';
 
async.series([
// make sure input file exists
function(next) {
path.exists(argv.in, function(exists){
if (exists) next();
else {
console.error("Input file %s does not exist.", argv.in);
process.exit(1);
}
});
},
// read it
function(next) {
fs.readFile(argv.in, 'utf8', function (err, data) {
if (err) throw err;
origXml = data;
next();
});
},
 
// parse it
function(next) {
var lines = origXml.split("\n")
, coordRegex = /-?\d+\.\d+,-?\d+\.\d+/g
, ind
, coordCounter = 0;
 
var curLine;
var prevLine;
 
for (ind = 0; ind < lines.length; ind++) {
isCoordLine = lines[ind].match(coordRegex);
if (! isCoordLine) {
newXml += lines[ind] + '\n';
} else {
if (prevLine) {
 
coords = isCoordLine[0].split(",");
coord1 = {'latitude':coords[0],'longitude':coords[1]};
 
coords = prevLine[0].split(",");
coord2 = {'latitude':coords[0], 'longitude':coords[1]};
 
dist = distance.getDistance(coord1, coord2);
 
coordCounter++;
 
//console.log('Distance: '+dist);
//console.log('coordCounter: ' + coordCounter);
 
if (dist >= argv.distance && coordCounter >= argv.reduce) {
//console.log('Adding to file...');
coordCounter=0;
newXml += lines[ind] + '\n';
} else {
//console.log('Skipping...');
}
}
 
prevLine = isCoordLine;
 
}
}
next();
},
 
// write
function(next) {
fs.writeFile(argv.out, newXml, 'utf8', function(err) {
if (err) throw(err);
else next();
});
}
]);
Owner
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.