[76] | 1 | /* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
---|
| 2 | * full list of contributors). Published under the Clear BSD license. |
---|
| 3 | * See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
---|
| 4 | * full text of the license. */ |
---|
| 5 | |
---|
| 6 | /** |
---|
| 7 | * @requires OpenLayers/Format/GML/Base.js |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | /** |
---|
| 11 | * Class: OpenLayers.Format.GML.v3 |
---|
| 12 | * Parses GML version 3. |
---|
| 13 | * |
---|
| 14 | * Inherits from: |
---|
| 15 | * - <OpenLayers.Format.GML.Base> |
---|
| 16 | */ |
---|
| 17 | OpenLayers.Format.GML.v3 = OpenLayers.Class(OpenLayers.Format.GML.Base, { |
---|
| 18 | |
---|
| 19 | /** |
---|
| 20 | * Property: schemaLocation |
---|
| 21 | * {String} Schema location for a particular minor version. The writers |
---|
| 22 | * conform with the Simple Features Profile for GML. |
---|
| 23 | */ |
---|
| 24 | schemaLocation: "http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd", |
---|
| 25 | |
---|
| 26 | /** |
---|
| 27 | * Property: curve |
---|
| 28 | * {Boolean} Write gml:Curve instead of gml:LineString elements. This also |
---|
| 29 | * affects the elements in multi-part geometries. Default is false. |
---|
| 30 | * To write gml:Curve elements instead of gml:LineString, set curve |
---|
| 31 | * to true in the options to the contstructor (cannot be changed after |
---|
| 32 | * instantiation). |
---|
| 33 | */ |
---|
| 34 | curve: false, |
---|
| 35 | |
---|
| 36 | /** |
---|
| 37 | * Property: multiCurve |
---|
| 38 | * {Boolean} Write gml:MultiCurve instead of gml:MultiLineString. Since |
---|
| 39 | * the latter is deprecated in GML 3, the default is true. To write |
---|
| 40 | * gml:MultiLineString instead of gml:MultiCurve, set multiCurve to |
---|
| 41 | * false in the options to the constructor (cannot be changed after |
---|
| 42 | * instantiation). |
---|
| 43 | */ |
---|
| 44 | multiCurve: true, |
---|
| 45 | |
---|
| 46 | /** |
---|
| 47 | * Property: surface |
---|
| 48 | * {Boolean} Write gml:Surface instead of gml:Polygon elements. This also |
---|
| 49 | * affects the elements in multi-part geometries. Default is false. |
---|
| 50 | * To write gml:Surface elements instead of gml:Polygon, set surface |
---|
| 51 | * to true in the options to the contstructor (cannot be changed after |
---|
| 52 | * instantiation). |
---|
| 53 | */ |
---|
| 54 | surface: false, |
---|
| 55 | |
---|
| 56 | /** |
---|
| 57 | * Property: multiSurface |
---|
| 58 | * {Boolean} Write gml:multiSurface instead of gml:MultiPolygon. Since |
---|
| 59 | * the latter is deprecated in GML 3, the default is true. To write |
---|
| 60 | * gml:MultiPolygon instead of gml:multiSurface, set multiSurface to |
---|
| 61 | * false in the options to the constructor (cannot be changed after |
---|
| 62 | * instantiation). |
---|
| 63 | */ |
---|
| 64 | multiSurface: true, |
---|
| 65 | |
---|
| 66 | /** |
---|
| 67 | * Constructor: OpenLayers.Format.GML.v3 |
---|
| 68 | * Create a parser for GML v3. |
---|
| 69 | * |
---|
| 70 | * Parameters: |
---|
| 71 | * options - {Object} An optional object whose properties will be set on |
---|
| 72 | * this instance. |
---|
| 73 | * |
---|
| 74 | * Valid options properties: |
---|
| 75 | * featureType - {String} Local (without prefix) feature typeName (required). |
---|
| 76 | * featureNS - {String} Feature namespace (required). |
---|
| 77 | * geometryName - {String} Geometry element name. |
---|
| 78 | */ |
---|
| 79 | initialize: function(options) { |
---|
| 80 | OpenLayers.Format.GML.Base.prototype.initialize.apply(this, [options]); |
---|
| 81 | }, |
---|
| 82 | |
---|
| 83 | /** |
---|
| 84 | * Property: readers |
---|
| 85 | * Contains public functions, grouped by namespace prefix, that will |
---|
| 86 | * be applied when a namespaced node is found matching the function |
---|
| 87 | * name. The function will be applied in the scope of this parser |
---|
| 88 | * with two arguments: the node being read and a context object passed |
---|
| 89 | * from the parent. |
---|
| 90 | */ |
---|
| 91 | readers: { |
---|
| 92 | "gml": OpenLayers.Util.applyDefaults({ |
---|
| 93 | "featureMembers": function(node, obj) { |
---|
| 94 | this.readChildNodes(node, obj); |
---|
| 95 | }, |
---|
| 96 | "Curve": function(node, container) { |
---|
| 97 | var obj = {points: []}; |
---|
| 98 | this.readChildNodes(node, obj); |
---|
| 99 | if(!container.components) { |
---|
| 100 | container.components = []; |
---|
| 101 | } |
---|
| 102 | container.components.push( |
---|
| 103 | new OpenLayers.Geometry.LineString(obj.points) |
---|
| 104 | ); |
---|
| 105 | }, |
---|
| 106 | "segments": function(node, obj) { |
---|
| 107 | this.readChildNodes(node, obj); |
---|
| 108 | }, |
---|
| 109 | "LineStringSegment": function(node, container) { |
---|
| 110 | var obj = {}; |
---|
| 111 | this.readChildNodes(node, obj); |
---|
| 112 | if(obj.points) { |
---|
| 113 | Array.prototype.push.apply(container.points, obj.points); |
---|
| 114 | } |
---|
| 115 | }, |
---|
| 116 | "pos": function(node, obj) { |
---|
| 117 | var str = this.getChildValue(node).replace( |
---|
| 118 | this.regExes.trimSpace, "" |
---|
| 119 | ); |
---|
| 120 | var coords = str.split(this.regExes.splitSpace); |
---|
| 121 | var point; |
---|
| 122 | if(this.xy) { |
---|
| 123 | point = new OpenLayers.Geometry.Point( |
---|
| 124 | coords[0], coords[1], coords[2] |
---|
| 125 | ); |
---|
| 126 | } else { |
---|
| 127 | point = new OpenLayers.Geometry.Point( |
---|
| 128 | coords[1], coords[0], coords[2] |
---|
| 129 | ); |
---|
| 130 | } |
---|
| 131 | obj.points = [point]; |
---|
| 132 | }, |
---|
| 133 | "posList": function(node, obj) { |
---|
| 134 | var str = this.getChildValue(node).replace( |
---|
| 135 | this.regExes.trimSpace, "" |
---|
| 136 | ); |
---|
| 137 | var coords = str.split(this.regExes.splitSpace); |
---|
| 138 | var dim = parseInt(node.getAttribute("dimension")) || 2; |
---|
| 139 | var j, x, y, z; |
---|
| 140 | var numPoints = coords.length / dim; |
---|
| 141 | var points = new Array(numPoints); |
---|
| 142 | for(var i=0, len=coords.length; i<len; i += dim) { |
---|
| 143 | x = coords[i]; |
---|
| 144 | y = coords[i+1]; |
---|
| 145 | z = (dim == 2) ? undefined : coords[i+2]; |
---|
| 146 | if (this.xy) { |
---|
| 147 | points[i/dim] = new OpenLayers.Geometry.Point(x, y, z); |
---|
| 148 | } else { |
---|
| 149 | points[i/dim] = new OpenLayers.Geometry.Point(y, x, z); |
---|
| 150 | } |
---|
| 151 | } |
---|
| 152 | obj.points = points; |
---|
| 153 | }, |
---|
| 154 | "Surface": function(node, obj) { |
---|
| 155 | this.readChildNodes(node, obj); |
---|
| 156 | }, |
---|
| 157 | "patches": function(node, obj) { |
---|
| 158 | this.readChildNodes(node, obj); |
---|
| 159 | }, |
---|
| 160 | "PolygonPatch": function(node, obj) { |
---|
| 161 | this.readers.gml.Polygon.apply(this, [node, obj]); |
---|
| 162 | }, |
---|
| 163 | "exterior": function(node, container) { |
---|
| 164 | var obj = {}; |
---|
| 165 | this.readChildNodes(node, obj); |
---|
| 166 | container.outer = obj.components[0]; |
---|
| 167 | }, |
---|
| 168 | "interior": function(node, container) { |
---|
| 169 | var obj = {}; |
---|
| 170 | this.readChildNodes(node, obj); |
---|
| 171 | container.inner.push(obj.components[0]); |
---|
| 172 | }, |
---|
| 173 | "MultiCurve": function(node, container) { |
---|
| 174 | var obj = {components: []}; |
---|
| 175 | this.readChildNodes(node, obj); |
---|
| 176 | if(obj.components.length > 0) { |
---|
| 177 | container.components = [ |
---|
| 178 | new OpenLayers.Geometry.MultiLineString(obj.components) |
---|
| 179 | ]; |
---|
| 180 | } |
---|
| 181 | }, |
---|
| 182 | "curveMember": function(node, obj) { |
---|
| 183 | this.readChildNodes(node, obj); |
---|
| 184 | }, |
---|
| 185 | "MultiSurface": function(node, container) { |
---|
| 186 | var obj = {components: []}; |
---|
| 187 | this.readChildNodes(node, obj); |
---|
| 188 | if(obj.components.length > 0) { |
---|
| 189 | container.components = [ |
---|
| 190 | new OpenLayers.Geometry.MultiPolygon(obj.components) |
---|
| 191 | ]; |
---|
| 192 | } |
---|
| 193 | }, |
---|
| 194 | "surfaceMember": function(node, obj) { |
---|
| 195 | this.readChildNodes(node, obj); |
---|
| 196 | }, |
---|
| 197 | "surfaceMembers": function(node, obj) { |
---|
| 198 | this.readChildNodes(node, obj); |
---|
| 199 | }, |
---|
| 200 | "pointMembers": function(node, obj) { |
---|
| 201 | this.readChildNodes(node, obj); |
---|
| 202 | }, |
---|
| 203 | "lineStringMembers": function(node, obj) { |
---|
| 204 | this.readChildNodes(node, obj); |
---|
| 205 | }, |
---|
| 206 | "polygonMembers": function(node, obj) { |
---|
| 207 | this.readChildNodes(node, obj); |
---|
| 208 | }, |
---|
| 209 | "geometryMembers": function(node, obj) { |
---|
| 210 | this.readChildNodes(node, obj); |
---|
| 211 | }, |
---|
| 212 | "Envelope": function(node, container) { |
---|
| 213 | var obj = {points: new Array(2)}; |
---|
| 214 | this.readChildNodes(node, obj); |
---|
| 215 | if(!container.components) { |
---|
| 216 | container.components = []; |
---|
| 217 | } |
---|
| 218 | var min = obj.points[0]; |
---|
| 219 | var max = obj.points[1]; |
---|
| 220 | container.components.push( |
---|
| 221 | new OpenLayers.Bounds(min.x, min.y, max.x, max.y) |
---|
| 222 | ); |
---|
| 223 | }, |
---|
| 224 | "lowerCorner": function(node, container) { |
---|
| 225 | var obj = {}; |
---|
| 226 | this.readers.gml.pos.apply(this, [node, obj]); |
---|
| 227 | container.points[0] = obj.points[0]; |
---|
| 228 | }, |
---|
| 229 | "upperCorner": function(node, container) { |
---|
| 230 | var obj = {}; |
---|
| 231 | this.readers.gml.pos.apply(this, [node, obj]); |
---|
| 232 | container.points[1] = obj.points[0]; |
---|
| 233 | } |
---|
| 234 | }, OpenLayers.Format.GML.Base.prototype.readers["gml"]), |
---|
| 235 | "feature": OpenLayers.Format.GML.Base.prototype.readers["feature"], |
---|
| 236 | "wfs": OpenLayers.Format.GML.Base.prototype.readers["wfs"] |
---|
| 237 | }, |
---|
| 238 | |
---|
| 239 | /** |
---|
| 240 | * Method: write |
---|
| 241 | * |
---|
| 242 | * Parameters: |
---|
| 243 | * features - {Array(<OpenLayers.Feature.Vector>) | OpenLayers.Feature.Vector} |
---|
| 244 | * An array of features or a single feature. |
---|
| 245 | * |
---|
| 246 | * Returns: |
---|
| 247 | * {String} Given an array of features, a doc with a gml:featureMembers |
---|
| 248 | * element will be returned. Given a single feature, a doc with a |
---|
| 249 | * gml:featureMember element will be returned. |
---|
| 250 | */ |
---|
| 251 | write: function(features) { |
---|
| 252 | var name; |
---|
| 253 | if(features instanceof Array) { |
---|
| 254 | name = "featureMembers"; |
---|
| 255 | } else { |
---|
| 256 | name = "featureMember"; |
---|
| 257 | } |
---|
| 258 | var root = this.writeNode("gml:" + name, features); |
---|
| 259 | this.setAttributeNS( |
---|
| 260 | root, this.namespaces["xsi"], |
---|
| 261 | "xsi:schemaLocation", this.schemaLocation |
---|
| 262 | ); |
---|
| 263 | |
---|
| 264 | return OpenLayers.Format.XML.prototype.write.apply(this, [root]); |
---|
| 265 | }, |
---|
| 266 | |
---|
| 267 | /** |
---|
| 268 | * Property: writers |
---|
| 269 | * As a compliment to the readers property, this structure contains public |
---|
| 270 | * writing functions grouped by namespace alias and named like the |
---|
| 271 | * node names they produce. |
---|
| 272 | */ |
---|
| 273 | writers: { |
---|
| 274 | "gml": OpenLayers.Util.applyDefaults({ |
---|
| 275 | "featureMembers": function(features) { |
---|
| 276 | var node = this.createElementNSPlus("gml:featureMembers"); |
---|
| 277 | for(var i=0, len=features.length; i<len; ++i) { |
---|
| 278 | this.writeNode("feature:_typeName", features[i], node); |
---|
| 279 | } |
---|
| 280 | return node; |
---|
| 281 | }, |
---|
| 282 | "Point": function(geometry) { |
---|
| 283 | var node = this.createElementNSPlus("gml:Point"); |
---|
| 284 | this.writeNode("pos", geometry, node); |
---|
| 285 | return node; |
---|
| 286 | }, |
---|
| 287 | "pos": function(point) { |
---|
| 288 | // only 2d for simple features profile |
---|
| 289 | var pos = (this.xy) ? |
---|
| 290 | (point.x + " " + point.y) : (point.y + " " + point.x); |
---|
| 291 | return this.createElementNSPlus("gml:pos", { |
---|
| 292 | value: pos |
---|
| 293 | }); |
---|
| 294 | }, |
---|
| 295 | "LineString": function(geometry) { |
---|
| 296 | var node = this.createElementNSPlus("gml:LineString"); |
---|
| 297 | this.writeNode("posList", geometry.components, node); |
---|
| 298 | return node; |
---|
| 299 | }, |
---|
| 300 | "Curve": function(geometry) { |
---|
| 301 | var node = this.createElementNSPlus("gml:Curve"); |
---|
| 302 | this.writeNode("segments", geometry, node); |
---|
| 303 | return node; |
---|
| 304 | }, |
---|
| 305 | "segments": function(geometry) { |
---|
| 306 | var node = this.createElementNSPlus("gml:segments"); |
---|
| 307 | this.writeNode("LineStringSegment", geometry, node); |
---|
| 308 | return node; |
---|
| 309 | }, |
---|
| 310 | "LineStringSegment": function(geometry) { |
---|
| 311 | var node = this.createElementNSPlus("gml:LineStringSegment"); |
---|
| 312 | this.writeNode("posList", geometry.components, node); |
---|
| 313 | return node; |
---|
| 314 | }, |
---|
| 315 | "posList": function(points) { |
---|
| 316 | // only 2d for simple features profile |
---|
| 317 | var len = points.length; |
---|
| 318 | var parts = new Array(len); |
---|
| 319 | var point; |
---|
| 320 | for(var i=0; i<len; ++i) { |
---|
| 321 | point = points[i]; |
---|
| 322 | if(this.xy) { |
---|
| 323 | parts[i] = point.x + " " + point.y; |
---|
| 324 | } else { |
---|
| 325 | parts[i] = point.y + " " + point.x; |
---|
| 326 | } |
---|
| 327 | } |
---|
| 328 | return this.createElementNSPlus("gml:posList", { |
---|
| 329 | value: parts.join(" ") |
---|
| 330 | }); |
---|
| 331 | }, |
---|
| 332 | "Surface": function(geometry) { |
---|
| 333 | var node = this.createElementNSPlus("gml:Surface"); |
---|
| 334 | this.writeNode("patches", geometry, node); |
---|
| 335 | return node; |
---|
| 336 | }, |
---|
| 337 | "patches": function(geometry) { |
---|
| 338 | var node = this.createElementNSPlus("gml:patches"); |
---|
| 339 | this.writeNode("PolygonPatch", geometry, node); |
---|
| 340 | return node; |
---|
| 341 | }, |
---|
| 342 | "PolygonPatch": function(geometry) { |
---|
| 343 | var node = this.createElementNSPlus("gml:PolygonPatch", { |
---|
| 344 | attributes: {interpolation: "planar"} |
---|
| 345 | }); |
---|
| 346 | this.writeNode("exterior", geometry.components[0], node); |
---|
| 347 | for(var i=1, len=geometry.components.length; i<len; ++i) { |
---|
| 348 | this.writeNode( |
---|
| 349 | "interior", geometry.components[i], node |
---|
| 350 | ); |
---|
| 351 | } |
---|
| 352 | return node; |
---|
| 353 | }, |
---|
| 354 | "Polygon": function(geometry) { |
---|
| 355 | var node = this.createElementNSPlus("gml:Polygon"); |
---|
| 356 | this.writeNode("exterior", geometry.components[0], node); |
---|
| 357 | for(var i=1, len=geometry.components.length; i<len; ++i) { |
---|
| 358 | this.writeNode( |
---|
| 359 | "interior", geometry.components[i], node |
---|
| 360 | ); |
---|
| 361 | } |
---|
| 362 | return node; |
---|
| 363 | }, |
---|
| 364 | "exterior": function(ring) { |
---|
| 365 | var node = this.createElementNSPlus("gml:exterior"); |
---|
| 366 | this.writeNode("LinearRing", ring, node); |
---|
| 367 | return node; |
---|
| 368 | }, |
---|
| 369 | "interior": function(ring) { |
---|
| 370 | var node = this.createElementNSPlus("gml:interior"); |
---|
| 371 | this.writeNode("LinearRing", ring, node); |
---|
| 372 | return node; |
---|
| 373 | }, |
---|
| 374 | "LinearRing": function(ring) { |
---|
| 375 | var node = this.createElementNSPlus("gml:LinearRing"); |
---|
| 376 | this.writeNode("posList", ring.components, node); |
---|
| 377 | return node; |
---|
| 378 | }, |
---|
| 379 | "MultiCurve": function(geometry) { |
---|
| 380 | var node = this.createElementNSPlus("gml:MultiCurve"); |
---|
| 381 | for(var i=0, len=geometry.components.length; i<len; ++i) { |
---|
| 382 | this.writeNode("curveMember", geometry.components[i], node); |
---|
| 383 | } |
---|
| 384 | return node; |
---|
| 385 | }, |
---|
| 386 | "curveMember": function(geometry) { |
---|
| 387 | var node = this.createElementNSPlus("gml:curveMember"); |
---|
| 388 | if(this.curve) { |
---|
| 389 | this.writeNode("Curve", geometry, node); |
---|
| 390 | } else { |
---|
| 391 | this.writeNode("LineString", geometry, node); |
---|
| 392 | } |
---|
| 393 | return node; |
---|
| 394 | }, |
---|
| 395 | "MultiSurface": function(geometry) { |
---|
| 396 | var node = this.createElementNSPlus("gml:MultiSurface"); |
---|
| 397 | for(var i=0, len=geometry.components.length; i<len; ++i) { |
---|
| 398 | this.writeNode("surfaceMember", geometry.components[i], node); |
---|
| 399 | } |
---|
| 400 | return node; |
---|
| 401 | }, |
---|
| 402 | "surfaceMember": function(polygon) { |
---|
| 403 | var node = this.createElementNSPlus("gml:surfaceMember"); |
---|
| 404 | if(this.surface) { |
---|
| 405 | this.writeNode("Surface", polygon, node); |
---|
| 406 | } else { |
---|
| 407 | this.writeNode("Polygon", polygon, node); |
---|
| 408 | } |
---|
| 409 | return node; |
---|
| 410 | }, |
---|
| 411 | "Envelope": function(bounds) { |
---|
| 412 | var node = this.createElementNSPlus("gml:Envelope"); |
---|
| 413 | this.writeNode("lowerCorner", bounds, node); |
---|
| 414 | this.writeNode("upperCorner", bounds, node); |
---|
| 415 | // srsName attribute is required for gml:Envelope |
---|
| 416 | if(this.srsName) { |
---|
| 417 | node.setAttribute("srsName", this.srsName); |
---|
| 418 | } |
---|
| 419 | return node; |
---|
| 420 | }, |
---|
| 421 | "lowerCorner": function(bounds) { |
---|
| 422 | // only 2d for simple features profile |
---|
| 423 | var pos = (this.xy) ? |
---|
| 424 | (bounds.left + " " + bounds.bottom) : |
---|
| 425 | (bounds.bottom + " " + bounds.left); |
---|
| 426 | return this.createElementNSPlus("gml:lowerCorner", { |
---|
| 427 | value: pos |
---|
| 428 | }); |
---|
| 429 | }, |
---|
| 430 | "upperCorner": function(bounds) { |
---|
| 431 | // only 2d for simple features profile |
---|
| 432 | var pos = (this.xy) ? |
---|
| 433 | (bounds.right + " " + bounds.top) : |
---|
| 434 | (bounds.top + " " + bounds.right); |
---|
| 435 | return this.createElementNSPlus("gml:upperCorner", { |
---|
| 436 | value: pos |
---|
| 437 | }); |
---|
| 438 | } |
---|
| 439 | }, OpenLayers.Format.GML.Base.prototype.writers["gml"]), |
---|
| 440 | "feature": OpenLayers.Format.GML.Base.prototype.writers["feature"], |
---|
| 441 | "wfs": OpenLayers.Format.GML.Base.prototype.writers["wfs"] |
---|
| 442 | }, |
---|
| 443 | |
---|
| 444 | /** |
---|
| 445 | * Function: setGeometryTypes |
---|
| 446 | * Sets the <geometryTypes> mapping. |
---|
| 447 | */ |
---|
| 448 | setGeometryTypes: function() { |
---|
| 449 | this.geometryTypes = { |
---|
| 450 | "OpenLayers.Geometry.Point": "Point", |
---|
| 451 | "OpenLayers.Geometry.MultiPoint": "MultiPoint", |
---|
| 452 | "OpenLayers.Geometry.LineString": (this.curve === true) ? "Curve": "LineString", |
---|
| 453 | "OpenLayers.Geometry.MultiLineString": (this.multiCurve === false) ? "MultiLineString" : "MultiCurve", |
---|
| 454 | "OpenLayers.Geometry.Polygon": (this.surface === true) ? "Surface" : "Polygon", |
---|
| 455 | "OpenLayers.Geometry.MultiPolygon": (this.multiSurface === false) ? "MultiPolygon" : "MultiSurface", |
---|
| 456 | "OpenLayers.Geometry.Collection": "GeometryCollection" |
---|
| 457 | }; |
---|
| 458 | }, |
---|
| 459 | |
---|
| 460 | CLASS_NAME: "OpenLayers.Format.GML.v3" |
---|
| 461 | |
---|
| 462 | }); |
---|