Add decimals option to format write

This commit is contained in:
Peter Robins
2016-03-17 19:46:22 +00:00
parent e742181fe9
commit a18bf636f8
3 changed files with 66 additions and 4 deletions

View File

@@ -1632,7 +1632,8 @@ olx.format.ReadOptions.prototype.featureProjection;
/** /**
* @typedef {{dataProjection: ol.proj.ProjectionLike, * @typedef {{dataProjection: ol.proj.ProjectionLike,
* featureProjection: ol.proj.ProjectionLike, * featureProjection: ol.proj.ProjectionLike,
* rightHanded: (boolean|undefined)}} * rightHanded: (boolean|undefined),
* decimals: (number|undefined)}}
* @api * @api
*/ */
olx.format.WriteOptions; olx.format.WriteOptions;
@@ -1675,6 +1676,20 @@ olx.format.WriteOptions.prototype.featureProjection;
olx.format.WriteOptions.prototype.rightHanded; olx.format.WriteOptions.prototype.rightHanded;
/**
* Maximum number of decimal places for coordinates. Coordinates are stored
* internally as floats, but floating-point arithmetic can create coordinates
* with a large number of decimal places, not generally wanted on output.
* Set a number here to round coordinates. Can also be used to ensure that
* coordinates read in can be written back out with the same number of decimals.
* Default is no rounding.
*
* @type {number|undefined}
* @api
*/
olx.format.WriteOptions.prototype.decimals;
/** /**
* @typedef {{defaultDataProjection: ol.proj.ProjectionLike, * @typedef {{defaultDataProjection: ol.proj.ProjectionLike,
* geometryName: (string|undefined)}} * geometryName: (string|undefined)}}

View File

@@ -71,6 +71,9 @@ ol.format.Feature.prototype.adaptOptions = function(options) {
options.dataProjection : this.defaultDataProjection, options.dataProjection : this.defaultDataProjection,
rightHanded: options.rightHanded rightHanded: options.rightHanded
}; };
if (options.decimals) {
updatedOptions.decimals = options.decimals;
}
} }
return updatedOptions; return updatedOptions;
}; };
@@ -165,21 +168,45 @@ ol.format.Feature.transformWithOptions = function(
ol.proj.get(opt_options.featureProjection) : null; ol.proj.get(opt_options.featureProjection) : null;
var dataProjection = opt_options ? var dataProjection = opt_options ?
ol.proj.get(opt_options.dataProjection) : null; ol.proj.get(opt_options.dataProjection) : null;
/**
* @type {ol.geom.Geometry|ol.Extent}
*/
var transformed;
if (featureProjection && dataProjection && if (featureProjection && dataProjection &&
!ol.proj.equivalent(featureProjection, dataProjection)) { !ol.proj.equivalent(featureProjection, dataProjection)) {
if (geometry instanceof ol.geom.Geometry) { if (geometry instanceof ol.geom.Geometry) {
return (write ? geometry.clone() : geometry).transform( transformed = (write ? geometry.clone() : geometry).transform(
write ? featureProjection : dataProjection, write ? featureProjection : dataProjection,
write ? dataProjection : featureProjection); write ? dataProjection : featureProjection);
} else { } else {
// FIXME this is necessary because ol.format.GML treats extents // FIXME this is necessary because ol.format.GML treats extents
// as geometries // as geometries
return ol.proj.transformExtent( transformed = ol.proj.transformExtent(
write ? geometry.slice() : geometry, write ? geometry.slice() : geometry,
write ? featureProjection : dataProjection, write ? featureProjection : dataProjection,
write ? dataProjection : featureProjection); write ? dataProjection : featureProjection);
} }
} else { } else {
return geometry; transformed = geometry;
} }
if (write && opt_options && opt_options.decimals) {
var power = Math.pow(10, opt_options.decimals);
// if decimals option on write, round each coordinate appropriately
/**
* @param {Array.<number>} coordinates Coordinates.
* @return {Array.<number>} Transformed coordinates.
*/
var transform = function(coordinates) {
for (var i = 0, ii = coordinates.length; i < ii; ++i) {
coordinates[i] = Math.round(coordinates[i] * power) / power;
}
return coordinates;
};
if (Array.isArray(transformed)) {
transform(/** @type {ol.Extent} */ (transformed));
} else {
transformed.applyTransform(transform);
}
}
return transformed;
}; };

View File

@@ -746,6 +746,26 @@ describe('ol.format.GeoJSON', function() {
expect(geometries[1].getCoordinates()[0][1]).to.roughlyEqual( expect(geometries[1].getCoordinates()[0][1]).to.roughlyEqual(
gotGeometries[1].getCoordinates()[0][1], 1e-8); gotGeometries[1].getCoordinates()[0][1], 1e-8);
}); });
it('truncates transformed point with decimals option', function() {
var point = new ol.geom.Point([2, 3]).transform('EPSG:4326','EPSG:3857');
var geojson = format.writeGeometry(point, {
featureProjection: 'EPSG:3857',
decimals: 2
});
expect(format.readGeometry(geojson).getCoordinates()).to.eql(
[2, 3]);
});
it('truncates a linestring with decimals option', function() {
var linestring = new ol.geom.LineString([[42.123456789, 38.987654321],
[43, 39]]);
var geojson = format.writeGeometry(linestring, {
decimals: 6
});
expect(format.readGeometry(geojson).getCoordinates()).to.eql(
[[42.123457, 38.987654], [43, 39]]);
});
}); });
}); });