diff --git a/externs/olx.js b/externs/olx.js index a3a78dc84b..d89440409a 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -1666,7 +1666,8 @@ olx.format.WriteOptions.prototype.decimals; /** * @typedef {{defaultDataProjection: ol.ProjectionLike, - * geometryName: (string|undefined)}} + * geometryName: (string|undefined), + * featureProjection: ol.ProjectionLike}} */ olx.format.GeoJSONOptions; @@ -1679,6 +1680,15 @@ olx.format.GeoJSONOptions; olx.format.GeoJSONOptions.prototype.defaultDataProjection; +/** + * Projection for features read or written by the format. Options passed to + * read or write methods will take precedence. + * @type {ol.ProjectionLike} + * @api stable + */ +olx.format.GeoJSONOptions.prototype.featureProjection; + + /** * Geometry name to use when creating features. * @type {string|undefined} diff --git a/src/ol/format/feature.js b/src/ol/format/feature.js index c974c09fae..37a05cc26c 100644 --- a/src/ol/format/feature.js +++ b/src/ol/format/feature.js @@ -1,6 +1,7 @@ goog.provide('ol.format.Feature'); goog.require('ol.geom.Geometry'); +goog.require('ol.obj'); goog.require('ol.proj'); @@ -24,6 +25,12 @@ ol.format.Feature = function() { */ this.defaultDataProjection = null; + /** + * @protected + * @type {ol.proj.Projection} + */ + this.defaultFeatureProjection = null; + }; @@ -64,19 +71,10 @@ ol.format.Feature.prototype.getReadOptions = function(source, opt_options) { * Updated options. */ ol.format.Feature.prototype.adaptOptions = function(options) { - var updatedOptions; - if (options) { - updatedOptions = { - featureProjection: options.featureProjection, - dataProjection: options.dataProjection ? - options.dataProjection : this.defaultDataProjection, - rightHanded: options.rightHanded - }; - if (options.decimals) { - updatedOptions.decimals = options.decimals; - } - } - return updatedOptions; + return ol.obj.assign({ + dataProjection: this.defaultDataProjection, + featureProjection: this.defaultFeatureProjection + }, options); }; diff --git a/src/ol/format/geojson.js b/src/ol/format/geojson.js index 4c2173722d..82368db72d 100644 --- a/src/ol/format/geojson.js +++ b/src/ol/format/geojson.js @@ -42,6 +42,10 @@ ol.format.GeoJSON = function(opt_options) { options.defaultDataProjection : 'EPSG:4326'); + if (options.featureProjection) { + this.defaultFeatureProjection = ol.proj.get(options.featureProjection); + } + /** * Name of the geometry attribute for features. * @type {string|undefined} diff --git a/test/spec/ol/format/geojson.test.js b/test/spec/ol/format/geojson.test.js index 226b6540b4..e97fd6fe2d 100644 --- a/test/spec/ol/format/geojson.test.js +++ b/test/spec/ol/format/geojson.test.js @@ -208,6 +208,24 @@ describe('ol.format.GeoJSON', function() { ol.proj.transform([102.0, 0.5], 'EPSG:4326', 'EPSG:3857')); }); + it('uses featureProjection passed to the constructor', function() { + var format = new ol.format.GeoJSON({featureProjection: 'EPSG:3857'}); + var feature = format.readFeatures(pointGeoJSON); + expect(feature[0].getGeometry()).to.be.an(ol.geom.Point); + expect(feature[0].getGeometry().getCoordinates()).to.eql( + ol.proj.transform([102.0, 0.5], 'EPSG:4326', 'EPSG:3857')); + }); + + it('gives precedence to options passed to the read method', function() { + var format = new ol.format.GeoJSON({featureProjection: 'EPSG:1234'}); + var feature = format.readFeatures(pointGeoJSON, { + featureProjection: 'EPSG:3857' + }); + expect(feature[0].getGeometry()).to.be.an(ol.geom.Point); + expect(feature[0].getGeometry().getCoordinates()).to.eql( + ol.proj.transform([102.0, 0.5], 'EPSG:4326', 'EPSG:3857')); + }); + it('can read and transform a feature collection', function() { var features = format.readFeatures(featureCollectionGeoJSON, { featureProjection: 'EPSG:3857' @@ -578,6 +596,21 @@ describe('ol.format.GeoJSON', function() { format.readGeometry(geojson).getCoordinates()); }); + it('accepts featureProjection', function() { + var point = new ol.geom.Point(ol.proj.fromLonLat([10, 20])); + var geojson = format.writeGeometry(point, {featureProjection: 'EPSG:3857'}); + var obj = JSON.parse(geojson); + expect(obj.coordinates).to.eql([10, 20]); + }); + + it('respects featureProjection passed to constructor', function() { + var format = new ol.format.GeoJSON({featureProjection: 'EPSG:3857'}); + var point = new ol.geom.Point(ol.proj.fromLonLat([10, 20])); + var geojson = format.writeGeometry(point); + var obj = JSON.parse(geojson); + expect(obj.coordinates).to.eql([10, 20]); + }); + it('encodes linestring', function() { var linestring = new ol.geom.LineString([[10, 20], [30, 40]]); var geojson = format.writeGeometry(linestring);