Skip to content

Instantly share code, notes, and snippets.

@blemoine
Created September 9, 2015 10:07
Show Gist options
  • Save blemoine/6ea25402b37e9830f6ca to your computer and use it in GitHub Desktop.
Save blemoine/6ea25402b37e9830f6ca to your computer and use it in GitHub Desktop.
Compressing GeoJSON with informations loss
/*
pour lancer :
node geoJsonMinifier.js <cheminDuFichierGeoJson> > <cheminDuFichierDeSorti>
*/
var fs = require('fs');
var _ = require('lodash');
var geoJsonPath = process.argv[2];
if (!geoJsonPath) {
console.error("You must pass a path to a geoJson file", geoJsonPath);
return;
}
fs.readFile(geoJsonPath, function (err, geoJsonContent) {
if (err) {
console.error("Error while reading file", err);
return;
}
var geoJson = JSON.parse(geoJsonContent);
if (geoJson.type != 'FeatureCollection') {
console.error("The type of the geoJsonContent must be FeatureCollection", geoJson.type);
return;
}
console.log(JSON.stringify(minifyGeoJson(geoJson)));
});
function minifyGeoJson(geoJson) {
var minifiedFeatures = geoJson.features.map(function (feature) {
var minifyCoordinate = _.flow(decreasePrecision(3), removeDuplicatePoint);
var newCoordinates = minifyCoordinate(feature.geometry.coordinates);
return {
"type": "Feature",
"id": feature.id,
"properties": feature.properties,
"geometry": {
"type": feature.geometry.type,
"coordinates": newCoordinates
}
};
});
return {
"type": "FeatureCollection",
"features": minifiedFeatures
}
}
function isCoordinate(maybeCoordinates) {
return _.isArray(maybeCoordinates) && maybeCoordinates.length == 2 && _.isNumber(maybeCoordinates[0]) && _.isNumber(maybeCoordinates[1])
}
function removeDuplicatePoint(arr) {
var arrSize = arr.length;
return arr.map(function(el) {
if(_.isArray(el) ) {
if(el.every(isCoordinate)) {
var elSize = el.length;
return el.filter(function(coordinates, idx) {
//Minus 2 beacause we want at least 3 points
if(idx > 0 && idx < elSize - 2) {
return distanceBetweenCoordinates(coordinates, el[idx - 1]) > 100
} else {
return true;
}
});
} else {
return removeDuplicatePoint(el);
}
} else {
return el;
}
})
}
function decreasePrecision(precision) {
return function _decreasePrecision(arr) {
var tenFactor = Math.pow(10, precision);
return arr.map(function (el) {
if (_.isArray(el)) {
return _decreasePrecision(el);
} else if (_.isNumber(el)) {
return Math.round(el * tenFactor) / tenFactor;
} else {
return el;
}
})
}
}
function toRadians(n) {
return n * Math.PI / 180;
}
function distanceBetweenCoordinates(coord1, coord2) {
var lon1 = coord1[0];
var lat1 = coord1[1];
var lon2 = coord2[0];
var lat2 = coord2[1];
var R = 6371000; // earth radius in meters
var φ1 = toRadians(lat1);
var φ2 = toRadians(lat2);
var Δφ = toRadians(lat2-lat1);
var Δλ = toRadians(lon2-lon1);
var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment