From 3d8d8b0ce6baf38107c53e5b264d5a0065518684 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Wed, 6 Nov 2013 20:47:50 +0100 Subject: [PATCH] Add ol.reader.GeoJSON --- src/ol/reader/geojson/geojson.js | 139 ++++++++++++++++++++++++++++ test/spec/ol/reader/geojson.test.js | 111 ++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 src/ol/reader/geojson/geojson.js create mode 100644 test/spec/ol/reader/geojson.test.js diff --git a/src/ol/reader/geojson/geojson.js b/src/ol/reader/geojson/geojson.js new file mode 100644 index 0000000000..4f8e978bf5 --- /dev/null +++ b/src/ol/reader/geojson/geojson.js @@ -0,0 +1,139 @@ +// FIXME coordinate order +// FIXME reprojection +// FIXME support other geometry types + +goog.provide('ol.reader.GeoJSON'); + +goog.require('goog.asserts'); +goog.require('goog.json'); +goog.require('ol.Feature'); +goog.require('ol.geom.LineString'); +goog.require('ol.geom.Point'); +goog.require('ol.geom.Polygon'); + + + +/** + * @constructor + */ +ol.reader.GeoJSON = function() { +}; + + +/** + * @param {GeoJSONGeometry} geometry Geometry. + * @private + * @return {ol.geom.Point} Point. + */ +ol.reader.GeoJSON.readPointGeometry_ = function(geometry) { + goog.asserts.assert(geometry.type == 'Point'); + return new ol.geom.Point(geometry.coordinates); +}; + + +/** + * @param {GeoJSONGeometry} geometry Geometry. + * @private + * @return {ol.geom.LineString} LineString. + */ +ol.reader.GeoJSON.readLineStringGeometry_ = function(geometry) { + goog.asserts.assert(geometry.type == 'LineString'); + return new ol.geom.LineString(geometry.coordinates); +}; + + +/** + * @param {GeoJSONGeometry} geometry Geometry. + * @private + * @return {ol.geom.Polygon} Polygon. + */ +ol.reader.GeoJSON.readPolygonGeometry_ = function(geometry) { + goog.asserts.assert(geometry.type == 'Polygon'); + return new ol.geom.Polygon(geometry.coordinates); +}; + + +/** + * @param {GeoJSONFeature} feature Feature. + * @param {function(ol.Feature): *} callback Callback. + * @private + * @return {*} Callback result. + */ +ol.reader.GeoJSON.readFeature_ = function(feature, callback) { + goog.asserts.assert(feature.type == 'Feature'); + var geometryReader = + ol.reader.GeoJSON.GEOMETRY_READERS_[feature.geometry.type]; + goog.asserts.assert(goog.isDef(geometryReader)); + var geometry = geometryReader(feature.geometry); + var f = new ol.Feature(geometry); + if (goog.isDef(feature.properties)) { + f.setValues(feature.properties); + } + return callback(f); +}; + + +/** + * @param {GeoJSONFeatureCollection} featureCollection Feature collection. + * @param {function(ol.Feature): *} callback Callback. + * @private + * @return {*} Callback result. + */ +ol.reader.GeoJSON.readFeatureCollection_ = + function(featureCollection, callback) { + goog.asserts.assert(featureCollection.type == 'FeatureCollection'); + var features = featureCollection.features; + var i, ii; + for (i = 0, ii = features.length; i < ii; ++i) { + var result = ol.reader.GeoJSON.readFeature_(features[i], callback); + if (result) { + return result; + } + } + return undefined; +}; + + +/** + * @param {GeoJSONObject} object Object. + * @param {function(ol.Feature): *} callback Callback. + * @return {*} Callback result. + */ +ol.reader.GeoJSON.readObject = function(object, callback) { + var objectReader = ol.reader.GeoJSON.OBJECT_READERS_[object.type]; + goog.asserts.assert(goog.isDef(objectReader)); + return objectReader(object, callback); +}; + + +/** + * @param {string} string String. + * @param {function(ol.Feature): *} callback Callback. + * @return {*} Callback result. + */ +ol.reader.GeoJSON.readString = function(string, callback) { + var object = goog.json.parse(string); + return ol.reader.GeoJSON.readObject( + /** @type {GeoJSONObject} */ (object), callback); +}; + + +/** + * @private + * @type {Object.} + */ +ol.reader.GeoJSON.GEOMETRY_READERS_ = { + 'Point': ol.reader.GeoJSON.readPointGeometry_, + 'LineString': ol.reader.GeoJSON.readLineStringGeometry_, + 'Polygon': ol.reader.GeoJSON.readPolygonGeometry_ +}; + + +/** + * @private + * @type {Object.} + */ +ol.reader.GeoJSON.OBJECT_READERS_ = { + 'Feature': ol.reader.GeoJSON.readFeature_, + 'FeatureCollection': ol.reader.GeoJSON.readFeatureCollection_ +}; diff --git a/test/spec/ol/reader/geojson.test.js b/test/spec/ol/reader/geojson.test.js new file mode 100644 index 0000000000..c4ddb9debe --- /dev/null +++ b/test/spec/ol/reader/geojson.test.js @@ -0,0 +1,111 @@ +goog.provide('ol.test.reader.GeoJSON'); + + +describe('ol.reader.GeoJSON', function() { + + var pointGeoJSON = { + 'type': 'Feature', + 'geometry': { + 'type': 'Point', + 'coordinates': [102.0, 0.5] + }, + 'properties': { + 'prop0': 'value0' + } + }; + + var lineStringGeoJSON = { + 'type': 'Feature', + 'geometry': { + 'type': 'LineString', + 'coordinates': [ + [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0] + ] + }, + 'properties': { + 'prop0': 'value0', + 'prop1': 0.0 + } + }; + + var polygonGeoJSON = { + 'type': 'Feature', + 'geometry': { + 'type': 'Polygon', + 'coordinates': [[ + [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] + ]] + }, + 'properties': { + 'prop0': 'value0', + 'prop1': {'this': 'that'} + } + }; + + var featureCollectionGeoJSON = { + 'type': 'FeatureCollection', + 'features': [pointGeoJSON, lineStringGeoJSON, polygonGeoJSON] + }; + + describe('readObject', function() { + + it('can read a single point feature', function() { + var feature = ol.reader.GeoJSON.readObject(pointGeoJSON, function(f) { + return f; + }); + expect(feature).to.be.an(ol.Feature); + var geometry = feature.getGeometry(); + expect(geometry).to.be.an(ol.geom.Point); + expect(geometry.getCoordinate()).to.eql([102.0, 0.5]); + expect(feature.get('prop0')).to.be('value0'); + }); + + it('can read a single line string feature', function() { + var feature = ol.reader.GeoJSON.readObject(lineStringGeoJSON, + function(f) { + return f; + }); + expect(feature).to.be.an(ol.Feature); + var geometry = feature.getGeometry(); + expect(geometry).to.be.an(ol.geom.LineString); + expect(geometry.getCoordinates()).to.eql( + [[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]]); + expect(feature.get('prop0')).to.be('value0'); + expect(feature.get('prop1')).to.be(0.0); + }); + + it('can read a single polygon feature', function() { + var feature = ol.reader.GeoJSON.readObject(polygonGeoJSON, function(f) { + return f; + }); + expect(feature).to.be.an(ol.Feature); + var geometry = feature.getGeometry(); + expect(geometry).to.be.an(ol.geom.Polygon); + expect(geometry.getRings()).to.eql([[ + [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] + ]]); + expect(feature.get('prop0')).to.be('value0'); + expect(feature.get('prop1')).to.eql({'this': 'that'}); + }); + + it('can read a feature collection', function() { + var features = []; + ol.reader.GeoJSON.readObject(featureCollectionGeoJSON, function(f) { + features.push(f); + }); + expect(features).to.have.length(3); + expect(features[0].getGeometry()).to.be.an(ol.geom.Point); + expect(features[1].getGeometry()).to.be.an(ol.geom.LineString); + expect(features[2].getGeometry()).to.be.an(ol.geom.Polygon); + }); + + }); + +}); + + +goog.require('ol.Feature'); +goog.require('ol.geom.LineString'); +goog.require('ol.geom.Point'); +goog.require('ol.geom.Polygon'); +goog.require('ol.reader.GeoJSON');