Changeset 5435
- Timestamp:
- 12/15/07 16:45:51 (1 year ago)
- Files:
-
- trunk/openlayers/examples/geojson.html (added)
- trunk/openlayers/lib/OpenLayers/Format/GeoJSON.js (modified) (12 diffs)
- trunk/openlayers/tests/Format/test_GeoJSON.html (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/openlayers/lib/OpenLayers/Format/GeoJSON.js
r5401 r5435 41 41 * json - {String} A GeoJSON string 42 42 * type - {String} Optional string that determines the structure of 43 * the output. Supported values are "Geometry", "Feature", 44 * " GeometryCollection", and "FeatureCollection". If absent or null,45 * a default of"FeatureCollection" is assumed.43 * the output. Supported values are "Geometry", "Feature", and 44 * "FeatureCollection". If absent or null, a default of 45 * "FeatureCollection" is assumed. 46 46 * filter - {Function} A function which will be called for every key and 47 47 * value at every level of the final result. Each value will be … … 57 57 * <OpenLayers.Geometry>. If type is "Feature", the input json must 58 58 * represent a single feature, and the return will be an 59 * <OpenLayers.Feature.Vector>. If type is "GeometryCollection", the 60 * input json must represent a geometry collection, and the return will 61 * be an array of <OpenLayers.Geometry>. 59 * <OpenLayers.Feature.Vector>. 62 60 */ 63 61 read: function(json, type, filter) { … … 92 90 } 93 91 break; 94 case "GeometryCollection":95 results = [];96 for(var i=0; i<obj.geometries.length; ++i) {97 try {98 results.push(this.parseGeometry(obj.geometries[i]));99 } catch(err) {100 results = null;101 OpenLayers.Console.error(err);102 }103 }104 break;105 92 case "FeatureCollection": 106 93 // for type FeatureCollection, we allow input to be any type … … 125 112 } 126 113 break; 127 case "GeometryCollection":128 for(var i=0; i<obj.geometries.length; ++i) {129 try {130 var geom = this.parseGeometry(obj.geometries[i]);131 results.push(new OpenLayers.Feature.Vector(geom));132 } catch(err) {133 results = null;134 OpenLayers.Console.error(err);135 }136 }137 break;138 114 default: 139 115 try { … … 162 138 switch(type) { 163 139 case "Geometry": 164 if(OpenLayers.Util.indexOf(["Point", "MultiPoint", "LineString", 165 "MultiLineString", "Polygon", 166 "MultiPolygon", "Box"], obj.type) == -1) { 140 if(OpenLayers.Util.indexOf( 141 ["Point", "MultiPoint", "LineString", "MultiLineString", 142 "Polygon", "MultiPolygon", "Box", "GeometryCollection"], 143 obj.type) == -1) { 167 144 // unsupported geometry type 168 145 OpenLayers.Console.error("Unsupported geometry type: " + … … 177 154 break; 178 155 default: 179 // for GeometryCollection and Feature,types must match156 // for Feature types must match 180 157 if(obj.type == type) { 181 158 valid = true; … … 227 204 parseGeometry: function(obj) { 228 205 var geometry; 229 if(!(obj.coordinates instanceof Array)) { 230 throw "Geometry must have coordinates array: " + obj; 231 } 232 if(!this.parseCoords[obj.type.toLowerCase()]) { 233 throw "Unsupported geometry type: " + obj.type; 234 } 235 try { 236 geometry = this.parseCoords[obj.type.toLowerCase()].apply(this, [obj.coordinates]); 237 } catch(err) { 238 // deal with bad coordinates 239 throw err; 206 if(obj.type == "GeometryCollection") { 207 if(!(obj.geometries instanceof Array)) { 208 throw "GeometryCollection must have geometries array: " + obj; 209 } 210 var numGeom = obj.geometries.length; 211 var components = new Array(numGeom); 212 for(var i=0; i<numGeom; ++i) { 213 components[i] = this.parseGeometry.apply( 214 this, [obj.geometries[i]] 215 ); 216 } 217 geometry = new OpenLayers.Geometry.Collection(components); 218 } else { 219 if(!(obj.coordinates instanceof Array)) { 220 throw "Geometry must have coordinates array: " + obj; 221 } 222 if(!this.parseCoords[obj.type.toLowerCase()]) { 223 throw "Unsupported geometry type: " + obj.type; 224 } 225 try { 226 geometry = this.parseCoords[obj.type.toLowerCase()].apply( 227 this, [obj.coordinates] 228 ); 229 } catch(err) { 230 // deal with bad coordinates 231 throw err; 232 } 240 233 } 241 234 return geometry; … … 419 412 /** 420 413 * APIMethod: write 421 * Serialize a feature, geometry, array of features, or array of geometries 422 * into a GeoJSON string. 414 * Serialize a feature, geometry, array of features into a GeoJSON string. 423 415 * 424 416 * Parameters: 425 417 * obj - {Object} An <OpenLayers.Feature.Vector>, <OpenLayers.Geometry>, 426 * or an array of either features or geometries.418 * or an array of features. 427 419 * pretty - {Boolean} Structure the output with newlines and indentation. 428 420 * Default is false. … … 430 422 * Returns: 431 423 * {String} The GeoJSON string representation of the input geometry, 432 * features, array of geometries,or array of features.424 * features, or array of features. 433 425 */ 434 426 write: function(obj, pretty) { … … 437 429 }; 438 430 if(obj instanceof Array) { 439 if(obj[0] instanceof OpenLayers.Feature.Vector) { 440 geojson.features = []; 441 } else if (obj[0].CLASS_NAME.search("OpenLayers.Geometry") == 0) { 442 geojson.geometries = []; 443 } 444 for(var i=0; i<obj.length; ++i) { 431 geojson.type = "FeatureCollection"; 432 var numFeatures = obj.length; 433 geojson.features = new Array(numFeatures); 434 for(var i=0; i<numFeatures; ++i) { 445 435 var element = obj[i]; 446 if(element instanceof OpenLayers.Feature.Vector) { 447 if(geojson.type == null) { 448 geojson.type = "FeatureCollection"; 449 if(element.layer && element.layer.projection) { 450 geojson.crs = this.createCRSObject(element); 451 } 452 } else if(geojson.type != "FeatureCollection") { 453 OpenLayers.Console.error("FeatureCollection only supports collections of features: " + element); 454 break; 455 } 456 geojson.features.push(this.extract.feature.apply(this, [element])); 457 } else if (element.CLASS_NAME.search("OpenLayers.Geometry") == 0) { 458 if(geojson.type == null) { 459 geojson.type = "GeometryCollection"; 460 } else if(geojson.type != "GeometryCollection") { 461 OpenLayers.Console.error("GeometryCollection only supports collections of geometries: " + element); 462 break; 463 } 464 geojson.geometries.push(this.extract.geometry.apply(this, [element])); 465 } 466 } 467 } else if (obj.CLASS_NAME.search("OpenLayers.Geometry") == 0) { 436 if(!element instanceof OpenLayers.Feature.Vector) { 437 var msg = "FeatureCollection only supports collections " + 438 "of features: " + element; 439 throw msg; 440 } 441 geojson.features[i] = this.extract.feature.apply( 442 this, [element] 443 ); 444 } 445 } else if (obj.CLASS_NAME.indexOf("OpenLayers.Geometry") == 0) { 468 446 geojson = this.extract.geometry.apply(this, [obj]); 469 447 } else if (obj instanceof OpenLayers.Feature.Vector) { … … 551 529 var geometryType = geometry.CLASS_NAME.split('.')[2]; 552 530 var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]); 553 return { 554 "type": geometryType, 555 "coordinates": data 556 }; 557 }, 558 559 /** 560 * Method: extract.poin 531 var json; 532 if(geometryType == "Collection") { 533 json = { 534 "type": "GeometryCollection", 535 "geometries": data 536 }; 537 } else { 538 json = { 539 "type": geometryType, 540 "coordinates": data 541 }; 542 } 543 544 return json; 545 }, 546 547 /** 548 * Method: extract.point 561 549 * Return an array of coordinates from a point. 562 550 * … … 663 651 } 664 652 return array; 665 } 653 }, 654 655 /** 656 * Method: extract.collection 657 * Return an array of geometries from a geometry collection. 658 * 659 * Parameters: 660 * collection - {<OpenLayers.Geometry.Collection>} 661 * 662 * Returns: 663 * {Array} An array of geometry objects representing the geometry 664 * collection. 665 */ 666 'collection': function(collection) { 667 var len = collection.components.length; 668 var array = new Array(len); 669 for(var i=0; i<len; ++i) { 670 array[i] = this.extract.geometry.apply( 671 this, [collection.components[i]] 672 ); 673 } 674 return array; 675 }, 676 666 677 667 678 }, trunk/openlayers/tests/Format/test_GeoJSON.html
r4819 r5435 23 23 24 24 function test_Format_GeoJSON_valid_type(t) { 25 t.plan(1 3);25 t.plan(14); 26 26 27 27 OpenLayers.Console.error = function(error) { window.global_error = error; } 28 var types = ["Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", "Box" ];28 var types = ["Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", "Box", "GeometryCollection"]; 29 29 for (var i = 0; i < types.length; i++) { 30 30 t.ok(parser.isValidType({'type':types[i]}, "Geometry"), "Geometry with type " + types[i] + " is valid"); … … 141 141 142 142 // This test is from the geom_collection example on geojson spec. 143 function test_Format_GeoJSON_ geom_collection(t) {144 t.plan( 7);143 function test_Format_GeoJSON_collection(t) { 144 t.plan(10); 145 145 146 146 var geomcol = { … … 159 159 ] 160 160 }; 161 data = parser.read(geomcol, "GeometryCollection"); 162 t.eq(data[0].CLASS_NAME, 163 "OpenLayers.Geometry.Point", "First geom in geom collection is point type"); 164 t.eq(data[0].x, 100, "First geom in geom collection has correct x"); 165 t.eq(data[0].y, 0, "First geom in geom collection has correct x"); 161 data = parser.read(geomcol, "Geometry"); 162 t.eq(data.CLASS_NAME, "OpenLayers.Geometry.Collection", 163 "GeometryCollection deserialized into geometry.collection"); 164 t.eq(data.components[0].CLASS_NAME, "OpenLayers.Geometry.Point", 165 "First geom is correct type"); 166 t.eq(data.components[0].x, 100, 167 "First geom in geom collection has correct x"); 168 t.eq(data.components[0].y, 0, 169 "First geom in geom collection has correct x"); 166 170 167 t.eq(data[1].CLASS_NAME, 168 "OpenLayers.Geometry.LineString", "Second geom in geom collection is point linestring"); 169 t.eq(data[1].components.length, 2, "linestring is correct length"); 170 t.eq(data[1].components[1].x, 102, "linestring is correct x end"); 171 t.eq(data[1].components[1].y, 1, "linestring is correct y end"); 171 t.eq(data.components[1].CLASS_NAME, "OpenLayers.Geometry.LineString", 172 "Second geom in geom collection is point linestring"); 173 t.eq(data.components[1].components.length, 2, 174 "linestring is correct length"); 175 t.eq(data.components[1].components[1].x, 102, 176 "linestring is correct x end"); 177 t.eq(data.components[1].components[1].y, 1, 178 "linestring is correct y end"); 179 180 data = parser.read(geomcol, "FeatureCollection"); 181 t.eq(data[0].CLASS_NAME, "OpenLayers.Feature.Vector", 182 "GeometryCollection can be read in as a feature collection"); 183 t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Collection", 184 "feature contains the correct geometry type"); 185 var feature = { 186 "type": "Feature", 187 "geometry": { 188 "type": "GeometryCollection", 189 "geometries": [ 190 { 191 "type": "Point", 192 "coordinates": [100.0, 0.0] 193 }, 194 { 195 "type": "LineString", 196 "coordinates": [ 197 [101.0, 0.0], [102.0, 1.0] 198 ] 199 } 200 ] 201 }, 202 "properties": { 203 "prop0": "value0", 204 "prop1": "value1" 205 } 206 }; 207 data = parser.read(feature); 208 t.eq(data.geometry.CLASS_NAME, "OpenLayers.Geometry.Collection", "Geometry of feature is a collection"); 209 var l = new OpenLayers.Layer.Vector(); 210 l.addFeatures(data); 211 t.ok(true, "adding a feature with geomcollection to layer doesn't cause error."); 172 212 } 173 213 … … 264 304 ]), 265 305 '{"type":"Polygon","coordinates":[[[1,2],[3,4],[5,6],[1,2]]]}' 306 ], 307 [ 308 new OpenLayers.Geometry.Collection([ 309 new OpenLayers.Geometry.Polygon([ 310 new OpenLayers.Geometry.LinearRing([ 311 new OpenLayers.Geometry.Point(1,2), 312 new OpenLayers.Geometry.Point(3,4), 313 new OpenLayers.Geometry.Point(5,6) 314 ]) 315 ]), 316 new OpenLayers.Geometry.LineString([ 317 new OpenLayers.Geometry.Point(1,2), 318 new OpenLayers.Geometry.Point(3,4) 319 ]), 320 new OpenLayers.Geometry.Point(1,2) 321 ]), 322 '{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[1,2],[3,4],[5,6],[1,2]]]},{"type":"LineString","coordinates":[[1,2],[3,4]]},{"type":"Point","coordinates":[1,2]}]}' 266 323 ] 267 324 ]; … … 272 329 serialize_tests.push([multipolygon, '{"type":"MultiPolygon","coordinates":[[[[1,2],[3,4],[5,6],[1,2]]],[[[1,2],[3,4],[5,6],[1,2]]]]}']); 273 330 serialize_tests.push([ [ serialize_tests[0][0] ], '{"type":"FeatureCollection","features":[{"type":"Feature","id":0,"properties":{},"geometry":{"type":"Point","coordinates":[1,2]}}]}' ]); 274 serialize_tests.push([ [ serialize_tests[1][0], serialize_tests[2][0] ], '{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[1,2]},{"type":"MultiPoint","coordinates":[[1,2]]}]}' ]);275 331 for (var i = 0; i < serialize_tests.length; i++) { 276 332 var input = serialize_tests[i][0];
