diff --git a/src/ol/parser/geojson.js b/src/ol/parser/geojson.js
index ac6859e8d1..b67332b9f4 100644
--- a/src/ol/parser/geojson.js
+++ b/src/ol/parser/geojson.js
@@ -63,7 +63,7 @@ ol.parser.GeoJSON.read = function(str) {
ol.parser.GeoJSON.prototype.readFeaturesFromString =
function(str, opt_options) {
var json = /** @type {GeoJSONFeatureCollection} */ (JSON.parse(str));
- return {features: this.parseFeatureCollection_(json, opt_options),
+ return {features: this.parseAsFeatureCollection_(json, opt_options),
metadata: {projection: 'EPSG:4326'}};
};
@@ -77,64 +77,82 @@ ol.parser.GeoJSON.prototype.readFeaturesFromString =
*/
ol.parser.GeoJSON.prototype.readFeaturesFromObject =
function(object, opt_options) {
- return {features: this.parseFeatureCollection_(object, opt_options),
+ return {features: this.parseAsFeatureCollection_(object, opt_options),
metadata: {projection: 'EPSG:4326'}};
};
/**
+ * Parse any GeoJSON object. Note that this method should not be called
+ * recursively due to the shared vertex creation.
+ *
* @param {GeoJSONObject} json GeoJSON object.
+ * @param {ol.parser.ReadFeaturesOptions=} opt_options Reader options.
* @return {ol.Feature|Array.
|
* ol.geom.Geometry|Array.} Parsed geometry or array
* of geometries.
* @private
*/
-ol.parser.GeoJSON.prototype.parse_ = function(json) {
+ol.parser.GeoJSON.prototype.parse_ = function(json, opt_options) {
var result;
- switch (json.type) {
- case 'FeatureCollection':
- result = this.parseFeatureCollection_(
- /** @type {GeoJSONFeatureCollection} */ (json));
- break;
- case 'Feature':
- result = this.parseFeature_(
- /** @type {GeoJSONFeature} */ (json));
- break;
- case 'GeometryCollection':
- result = this.parseGeometryCollection_(
- /** @type {GeoJSONGeometryCollection} */ (json));
- break;
- case 'Point':
- result = this.parsePoint_(
- /** @type {GeoJSONGeometry} */ (json));
- break;
- case 'LineString':
- result = this.parseLineString_(
- /** @type {GeoJSONGeometry} */ (json));
- break;
- case 'Polygon':
- result = this.parsePolygon_(
- /** @type {GeoJSONGeometry} */ (json));
- break;
- case 'MultiPoint':
- result = this.parseMultiPoint_(
- /** @type {GeoJSONGeometry} */ (json));
- break;
- case 'MultiLineString':
- result = this.parseMultiLineString_(
- /** @type {GeoJSONGeometry} */ (json));
- break;
- case 'MultiPolygon':
- result = this.parseMultiPolygon_(
- /** @type {GeoJSONGeometry} */ (json));
- break;
- default:
- throw new Error('GeoJSON parsing not implemented for type: ' + json.type);
+ if (json.type === 'FeatureCollection') {
+ result = this.parseFeatureCollection_(
+ /** @type {GeoJSONFeatureCollection} */ (json), opt_options);
+ } else if (json.type === 'Feature') {
+ result = this.parseFeature_(
+ /** @type {GeoJSONFeature} */ (json), opt_options);
+ } else if (json.type === 'GeometryCollection') {
+ result = this.parseGeometryCollection_(
+ /** @type {GeoJSONGeometryCollection} */ (json), opt_options);
+ } else {
+ // we've been called with a geometry or an unknown object
+ // create a feature to get shared vertices handling
+ var feature = this.parseFeature_(
+ /** @type {GeoJSONFeature} */ ({type: 'Feature', geometry: json}),
+ opt_options);
+ result = feature.getGeometry();
}
return result;
};
+/**
+ * @param {GeoJSONObject} json GeoJSON object.
+ * @param {ol.parser.ReadFeaturesOptions=} opt_options Reader options.
+ * @return {Array.} Parsed object coerced into array of features.
+ * @private
+ */
+ol.parser.GeoJSON.prototype.parseAsFeatureCollection_ = function(json,
+ opt_options) {
+ var obj = this.parse_(json, opt_options);
+ var features = [];
+ var feature;
+ if (obj instanceof ol.Feature) {
+ features = [obj];
+ } else if (obj instanceof ol.geom.Geometry) {
+ feature = new ol.Feature();
+ feature.setGeometry(obj);
+ features = [feature];
+ } else if (goog.isArray(obj)) {
+ var item, geomArray;
+ for (var i = 0, ii = obj.length; i < ii; ++i) {
+ item = obj[i];
+ geomArray = geomArray || (item instanceof ol.geom.Geometry);
+ if (!geomArray) {
+ goog.asserts.assert(item instanceof ol.Feature, 'expected feature');
+ features = obj;
+ break;
+ } else {
+ feature = new ol.Feature();
+ feature.setGeometry(item);
+ features[i] = feature;
+ }
+ }
+ }
+ return features;
+};
+
+
/**
* @param {GeoJSONFeature} json GeoJSON feature.
* @param {ol.parser.ReadFeaturesOptions=} opt_options Read options.
@@ -209,17 +227,20 @@ ol.parser.GeoJSON.prototype.parseFeatureCollection_ = function(
/**
* @param {GeoJSONGeometryCollection} json GeoJSON geometry collection.
+ * @param {ol.parser.ReadFeaturesOptions=} opt_options Read options.
* @return {Array.} Parsed array of geometries.
* @private
*/
-ol.parser.GeoJSON.prototype.parseGeometryCollection_ = function(json) {
+ol.parser.GeoJSON.prototype.parseGeometryCollection_ = function(json,
+ opt_options) {
var geometries = json.geometries,
len = geometries.length,
result = new Array(len),
i;
for (i = 0; i < len; ++i) {
- result[i] = this.parse_(/** @type {GeoJSONGeometry} */ (geometries[i]));
+ result[i] = this.parse_(/** @type {GeoJSONGeometry} */ (geometries[i]),
+ opt_options);
}
return result;
};
diff --git a/test/spec/ol/parser/geojson.test.js b/test/spec/ol/parser/geojson.test.js
index 92132db407..f49221fdc2 100644
--- a/test/spec/ol/parser/geojson.test.js
+++ b/test/spec/ol/parser/geojson.test.js
@@ -267,6 +267,267 @@ describe('ol.parser.GeoJSON', function() {
});
+ describe('#parseAsFeatureCollection_()', function() {
+
+ it('returns an array of features for FeatureCollection', function() {
+ var pointVertices = new ol.geom.SharedVertices();
+ var lineVertices = new ol.geom.SharedVertices();
+ var polygonVertices = new ol.geom.SharedVertices();
+
+ var lookup = {
+ 'point': pointVertices,
+ 'linestring': lineVertices,
+ 'polygon': polygonVertices,
+ 'multipoint': pointVertices,
+ 'multilinstring': lineVertices,
+ 'multipolygon': polygonVertices
+ };
+
+ var callback = function(feature, type) {
+ return lookup[type];
+ };
+
+ var parser = new ol.parser.GeoJSON();
+ var json = {
+ type: 'FeatureCollection',
+ features: [{
+ type: 'Feature',
+ properties: {
+ foo: 'bar'
+ },
+ geometry: {
+ type: 'Point',
+ coordinates: [1, 2]
+ }
+ }, {
+ type: 'Feature',
+ properties: {
+ bam: 'baz'
+ },
+ geometry: {
+ type: 'LineString',
+ coordinates: [[1, 2], [3, 4]]
+ }
+ }]
+ };
+ var features = parser.parseAsFeatureCollection_(json,
+ {callback: callback});
+
+ expect(features.length).to.be(2);
+
+ var first = features[0];
+ expect(first).to.be.a(ol.Feature);
+ expect(first.get('foo')).to.be('bar');
+ expect(first.getGeometry()).to.be.a(ol.geom.Point);
+
+ var second = features[1];
+ expect(second).to.be.a(ol.Feature);
+ expect(second.get('bam')).to.be('baz');
+ expect(second.getGeometry()).to.be.a(ol.geom.LineString);
+
+ expect(pointVertices.coordinates.length).to.be(2);
+ expect(lineVertices.coordinates.length).to.be(4);
+ expect(polygonVertices.coordinates.length).to.be(0);
+ });
+
+ it('returns an array of features for Feature', function() {
+ var pointVertices = new ol.geom.SharedVertices();
+ var lineVertices = new ol.geom.SharedVertices();
+ var polygonVertices = new ol.geom.SharedVertices();
+
+ var lookup = {
+ 'point': pointVertices,
+ 'linestring': lineVertices,
+ 'polygon': polygonVertices,
+ 'multipoint': pointVertices,
+ 'multilinstring': lineVertices,
+ 'multipolygon': polygonVertices
+ };
+
+ var callback = function(feature, type) {
+ return lookup[type];
+ };
+
+ var parser = new ol.parser.GeoJSON();
+ var json = {
+ type: 'Feature',
+ properties: {
+ bam: 'baz'
+ },
+ geometry: {
+ type: 'LineString',
+ coordinates: [[1, 2], [3, 4]]
+ }
+ };
+ var features = parser.parseAsFeatureCollection_(json,
+ {callback: callback});
+
+ expect(features.length).to.be(1);
+
+ var first = features[0];
+ expect(first).to.be.a(ol.Feature);
+ expect(first.get('bam')).to.be('baz');
+ expect(first.getGeometry()).to.be.a(ol.geom.LineString);
+
+ expect(pointVertices.coordinates.length).to.be(0);
+ expect(lineVertices.coordinates.length).to.be(4);
+ expect(polygonVertices.coordinates.length).to.be(0);
+ });
+
+ it('returns an array of features for GeometryCollection', function() {
+ var pointVertices = new ol.geom.SharedVertices();
+ var lineVertices = new ol.geom.SharedVertices();
+ var polygonVertices = new ol.geom.SharedVertices();
+
+ var lookup = {
+ 'point': pointVertices,
+ 'linestring': lineVertices,
+ 'polygon': polygonVertices,
+ 'multipoint': pointVertices,
+ 'multilinstring': lineVertices,
+ 'multipolygon': polygonVertices
+ };
+
+ var callback = function(feature, type) {
+ return lookup[type];
+ };
+
+ var parser = new ol.parser.GeoJSON();
+ var json = {
+ type: 'GeometryCollection',
+ geometries: [{
+ type: 'Point',
+ coordinates: [1, 2]
+ }, {
+ type: 'LineString',
+ coordinates: [[3, 4], [5, 6]]
+ }, {
+ type: 'Polygon',
+ coordinates: [[[7, 8], [9, 10], [11, 12], [7, 8]]]
+ }]
+ };
+ var features = parser.parseAsFeatureCollection_(json,
+ {callback: callback});
+
+ expect(features.length).to.be(3);
+
+ expect(features[0].getGeometry()).to.be.a(ol.geom.Point);
+ expect(features[1].getGeometry()).to.be.a(ol.geom.LineString);
+ expect(features[2].getGeometry()).to.be.a(ol.geom.Polygon);
+
+ expect(pointVertices.coordinates.length).to.be(2);
+ expect(lineVertices.coordinates.length).to.be(4);
+ expect(polygonVertices.coordinates.length).to.be(8);
+ });
+
+ it('returns an array of features for Point', function() {
+ var pointVertices = new ol.geom.SharedVertices();
+ var lineVertices = new ol.geom.SharedVertices();
+ var polygonVertices = new ol.geom.SharedVertices();
+
+ var lookup = {
+ 'point': pointVertices,
+ 'linestring': lineVertices,
+ 'polygon': polygonVertices,
+ 'multipoint': pointVertices,
+ 'multilinstring': lineVertices,
+ 'multipolygon': polygonVertices
+ };
+
+ var callback = function(feature, type) {
+ return lookup[type];
+ };
+
+ var parser = new ol.parser.GeoJSON();
+ var json = {
+ type: 'Point',
+ coordinates: [1, 2]
+ };
+ var features = parser.parseAsFeatureCollection_(json,
+ {callback: callback});
+
+ expect(features.length).to.be(1);
+
+ expect(features[0].getGeometry()).to.be.a(ol.geom.Point);
+
+ expect(pointVertices.coordinates.length).to.be(2);
+ expect(lineVertices.coordinates.length).to.be(0);
+ expect(polygonVertices.coordinates.length).to.be(0);
+ });
+
+ it('returns an array of features for LineString', function() {
+ var pointVertices = new ol.geom.SharedVertices();
+ var lineVertices = new ol.geom.SharedVertices();
+ var polygonVertices = new ol.geom.SharedVertices();
+
+ var lookup = {
+ 'point': pointVertices,
+ 'linestring': lineVertices,
+ 'polygon': polygonVertices,
+ 'multipoint': pointVertices,
+ 'multilinstring': lineVertices,
+ 'multipolygon': polygonVertices
+ };
+
+ var callback = function(feature, type) {
+ return lookup[type];
+ };
+
+ var parser = new ol.parser.GeoJSON();
+ var json = {
+ type: 'LineString',
+ coordinates: [[3, 4], [5, 6]]
+ };
+ var features = parser.parseAsFeatureCollection_(json,
+ {callback: callback});
+
+ expect(features.length).to.be(1);
+
+ expect(features[0].getGeometry()).to.be.a(ol.geom.LineString);
+
+ expect(pointVertices.coordinates.length).to.be(0);
+ expect(lineVertices.coordinates.length).to.be(4);
+ expect(polygonVertices.coordinates.length).to.be(0);
+ });
+
+ it('returns an array of features for Polygon', function() {
+ var pointVertices = new ol.geom.SharedVertices();
+ var lineVertices = new ol.geom.SharedVertices();
+ var polygonVertices = new ol.geom.SharedVertices();
+
+ var lookup = {
+ 'point': pointVertices,
+ 'linestring': lineVertices,
+ 'polygon': polygonVertices,
+ 'multipoint': pointVertices,
+ 'multilinstring': lineVertices,
+ 'multipolygon': polygonVertices
+ };
+
+ var callback = function(feature, type) {
+ return lookup[type];
+ };
+
+ var parser = new ol.parser.GeoJSON();
+ var json = {
+ type: 'Polygon',
+ coordinates: [[[7, 8], [9, 10], [11, 12], [7, 8]]]
+ };
+ var features = parser.parseAsFeatureCollection_(json,
+ {callback: callback});
+
+ expect(features.length).to.be(1);
+
+ expect(features[0].getGeometry()).to.be.a(ol.geom.Polygon);
+
+ expect(pointVertices.coordinates.length).to.be(0);
+ expect(lineVertices.coordinates.length).to.be(0);
+ expect(polygonVertices.coordinates.length).to.be(8);
+ });
+
+
+ });
+
});
goog.require('ol.Feature');