GeoJSON should parse and serialize GeometryCollections as a Geometry.Collection
object. (Closes #1067) git-svn-id: http://svn.openlayers.org/trunk/openlayers@5435 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -40,9 +40,9 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
* Parameters:
|
||||
* json - {String} A GeoJSON string
|
||||
* type - {String} Optional string that determines the structure of
|
||||
* the output. Supported values are "Geometry", "Feature",
|
||||
* "GeometryCollection", and "FeatureCollection". If absent or null,
|
||||
* a default of "FeatureCollection" is assumed.
|
||||
* the output. Supported values are "Geometry", "Feature", and
|
||||
* "FeatureCollection". If absent or null, a default of
|
||||
* "FeatureCollection" is assumed.
|
||||
* filter - {Function} A function which will be called for every key and
|
||||
* value at every level of the final result. Each value will be
|
||||
* replaced by the result of the filter function. This can be used to
|
||||
@@ -56,9 +56,7 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
* must represent a single geometry, and the return will be an
|
||||
* <OpenLayers.Geometry>. If type is "Feature", the input json must
|
||||
* represent a single feature, and the return will be an
|
||||
* <OpenLayers.Feature.Vector>. If type is "GeometryCollection", the
|
||||
* input json must represent a geometry collection, and the return will
|
||||
* be an array of <OpenLayers.Geometry>.
|
||||
* <OpenLayers.Feature.Vector>.
|
||||
*/
|
||||
read: function(json, type, filter) {
|
||||
type = (type) ? type : "FeatureCollection";
|
||||
@@ -91,17 +89,6 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
OpenLayers.Console.error(err);
|
||||
}
|
||||
break;
|
||||
case "GeometryCollection":
|
||||
results = [];
|
||||
for(var i=0; i<obj.geometries.length; ++i) {
|
||||
try {
|
||||
results.push(this.parseGeometry(obj.geometries[i]));
|
||||
} catch(err) {
|
||||
results = null;
|
||||
OpenLayers.Console.error(err);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "FeatureCollection":
|
||||
// for type FeatureCollection, we allow input to be any type
|
||||
results = [];
|
||||
@@ -124,17 +111,6 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "GeometryCollection":
|
||||
for(var i=0; i<obj.geometries.length; ++i) {
|
||||
try {
|
||||
var geom = this.parseGeometry(obj.geometries[i]);
|
||||
results.push(new OpenLayers.Feature.Vector(geom));
|
||||
} catch(err) {
|
||||
results = null;
|
||||
OpenLayers.Console.error(err);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
var geom = this.parseGeometry(obj);
|
||||
@@ -161,9 +137,10 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
var valid = false;
|
||||
switch(type) {
|
||||
case "Geometry":
|
||||
if(OpenLayers.Util.indexOf(["Point", "MultiPoint", "LineString",
|
||||
"MultiLineString", "Polygon",
|
||||
"MultiPolygon", "Box"], obj.type) == -1) {
|
||||
if(OpenLayers.Util.indexOf(
|
||||
["Point", "MultiPoint", "LineString", "MultiLineString",
|
||||
"Polygon", "MultiPolygon", "Box", "GeometryCollection"],
|
||||
obj.type) == -1) {
|
||||
// unsupported geometry type
|
||||
OpenLayers.Console.error("Unsupported geometry type: " +
|
||||
obj.type);
|
||||
@@ -176,7 +153,7 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
valid = true;
|
||||
break;
|
||||
default:
|
||||
// for GeometryCollection and Feature, types must match
|
||||
// for Feature types must match
|
||||
if(obj.type == type) {
|
||||
valid = true;
|
||||
} else {
|
||||
@@ -226,17 +203,33 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
*/
|
||||
parseGeometry: function(obj) {
|
||||
var geometry;
|
||||
if(!(obj.coordinates instanceof Array)) {
|
||||
throw "Geometry must have coordinates array: " + obj;
|
||||
}
|
||||
if(!this.parseCoords[obj.type.toLowerCase()]) {
|
||||
throw "Unsupported geometry type: " + obj.type;
|
||||
}
|
||||
try {
|
||||
geometry = this.parseCoords[obj.type.toLowerCase()].apply(this, [obj.coordinates]);
|
||||
} catch(err) {
|
||||
// deal with bad coordinates
|
||||
throw err;
|
||||
if(obj.type == "GeometryCollection") {
|
||||
if(!(obj.geometries instanceof Array)) {
|
||||
throw "GeometryCollection must have geometries array: " + obj;
|
||||
}
|
||||
var numGeom = obj.geometries.length;
|
||||
var components = new Array(numGeom);
|
||||
for(var i=0; i<numGeom; ++i) {
|
||||
components[i] = this.parseGeometry.apply(
|
||||
this, [obj.geometries[i]]
|
||||
);
|
||||
}
|
||||
geometry = new OpenLayers.Geometry.Collection(components);
|
||||
} else {
|
||||
if(!(obj.coordinates instanceof Array)) {
|
||||
throw "Geometry must have coordinates array: " + obj;
|
||||
}
|
||||
if(!this.parseCoords[obj.type.toLowerCase()]) {
|
||||
throw "Unsupported geometry type: " + obj.type;
|
||||
}
|
||||
try {
|
||||
geometry = this.parseCoords[obj.type.toLowerCase()].apply(
|
||||
this, [obj.coordinates]
|
||||
);
|
||||
} catch(err) {
|
||||
// deal with bad coordinates
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
return geometry;
|
||||
},
|
||||
@@ -418,53 +411,38 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
|
||||
/**
|
||||
* APIMethod: write
|
||||
* Serialize a feature, geometry, array of features, or array of geometries
|
||||
* into a GeoJSON string.
|
||||
* Serialize a feature, geometry, array of features into a GeoJSON string.
|
||||
*
|
||||
* Parameters:
|
||||
* obj - {Object} An <OpenLayers.Feature.Vector>, <OpenLayers.Geometry>,
|
||||
* or an array of either features or geometries.
|
||||
* or an array of features.
|
||||
* pretty - {Boolean} Structure the output with newlines and indentation.
|
||||
* Default is false.
|
||||
*
|
||||
* Returns:
|
||||
* {String} The GeoJSON string representation of the input geometry,
|
||||
* features, array of geometries, or array of features.
|
||||
* features, or array of features.
|
||||
*/
|
||||
write: function(obj, pretty) {
|
||||
var geojson = {
|
||||
"type": null
|
||||
};
|
||||
if(obj instanceof Array) {
|
||||
if(obj[0] instanceof OpenLayers.Feature.Vector) {
|
||||
geojson.features = [];
|
||||
} else if (obj[0].CLASS_NAME.search("OpenLayers.Geometry") == 0) {
|
||||
geojson.geometries = [];
|
||||
}
|
||||
for(var i=0; i<obj.length; ++i) {
|
||||
geojson.type = "FeatureCollection";
|
||||
var numFeatures = obj.length;
|
||||
geojson.features = new Array(numFeatures);
|
||||
for(var i=0; i<numFeatures; ++i) {
|
||||
var element = obj[i];
|
||||
if(element instanceof OpenLayers.Feature.Vector) {
|
||||
if(geojson.type == null) {
|
||||
geojson.type = "FeatureCollection";
|
||||
if(element.layer && element.layer.projection) {
|
||||
geojson.crs = this.createCRSObject(element);
|
||||
}
|
||||
} else if(geojson.type != "FeatureCollection") {
|
||||
OpenLayers.Console.error("FeatureCollection only supports collections of features: " + element);
|
||||
break;
|
||||
}
|
||||
geojson.features.push(this.extract.feature.apply(this, [element]));
|
||||
} else if (element.CLASS_NAME.search("OpenLayers.Geometry") == 0) {
|
||||
if(geojson.type == null) {
|
||||
geojson.type = "GeometryCollection";
|
||||
} else if(geojson.type != "GeometryCollection") {
|
||||
OpenLayers.Console.error("GeometryCollection only supports collections of geometries: " + element);
|
||||
break;
|
||||
}
|
||||
geojson.geometries.push(this.extract.geometry.apply(this, [element]));
|
||||
if(!element instanceof OpenLayers.Feature.Vector) {
|
||||
var msg = "FeatureCollection only supports collections " +
|
||||
"of features: " + element;
|
||||
throw msg;
|
||||
}
|
||||
geojson.features[i] = this.extract.feature.apply(
|
||||
this, [element]
|
||||
);
|
||||
}
|
||||
} else if (obj.CLASS_NAME.search("OpenLayers.Geometry") == 0) {
|
||||
} else if (obj.CLASS_NAME.indexOf("OpenLayers.Geometry") == 0) {
|
||||
geojson = this.extract.geometry.apply(this, [obj]);
|
||||
} else if (obj instanceof OpenLayers.Feature.Vector) {
|
||||
geojson = this.extract.feature.apply(this, [obj]);
|
||||
@@ -550,14 +528,24 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
'geometry': function(geometry) {
|
||||
var geometryType = geometry.CLASS_NAME.split('.')[2];
|
||||
var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);
|
||||
return {
|
||||
"type": geometryType,
|
||||
"coordinates": data
|
||||
};
|
||||
var json;
|
||||
if(geometryType == "Collection") {
|
||||
json = {
|
||||
"type": "GeometryCollection",
|
||||
"geometries": data
|
||||
};
|
||||
} else {
|
||||
json = {
|
||||
"type": geometryType,
|
||||
"coordinates": data
|
||||
};
|
||||
}
|
||||
|
||||
return json;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: extract.poin
|
||||
* Method: extract.point
|
||||
* Return an array of coordinates from a point.
|
||||
*
|
||||
* Parameters:
|
||||
@@ -662,7 +650,30 @@ OpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {
|
||||
array.push(this.extract.polygon.apply(this, [multipolygon.components[i]]));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: extract.collection
|
||||
* Return an array of geometries from a geometry collection.
|
||||
*
|
||||
* Parameters:
|
||||
* collection - {<OpenLayers.Geometry.Collection>}
|
||||
*
|
||||
* Returns:
|
||||
* {Array} An array of geometry objects representing the geometry
|
||||
* collection.
|
||||
*/
|
||||
'collection': function(collection) {
|
||||
var len = collection.components.length;
|
||||
var array = new Array(len);
|
||||
for(var i=0; i<len; ++i) {
|
||||
array[i] = this.extract.geometry.apply(
|
||||
this, [collection.components[i]]
|
||||
);
|
||||
}
|
||||
return array;
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user