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 | }); |
---|