Ticket #1648: wfs.patch
| File wfs.patch, 115.1 kB (added by tschaub, 3 months ago) |
|---|
-
tests/Format/GML/v3.html
old new 198 198 <body> 199 199 <div id="v3/envelope.xml"><!-- 200 200 <gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="foo"> 201 <gml:lowerCorner> <gml:pos>1 2</gml:pos></gml:lowerCorner>202 <gml:upperCorner> <gml:pos>3 4</gml:pos></gml:upperCorner>201 <gml:lowerCorner>1 2</gml:lowerCorner> 202 <gml:upperCorner>3 4</gml:upperCorner> 203 203 </gml:Envelope> 204 204 --></div> 205 205 <div id="v3/linearring.xml"><!-- -
tests/Protocol/WFS/v1_0_0.html
old new 1 <html> 2 <head> 3 <script src="../../../lib/OpenLayers.js"></script> 4 <script type="text/javascript"> 5 6 function test_initialize(t) { 7 t.plan(1); 8 9 var protocol = new OpenLayers.Protocol.WFS.v1_0_0({ 10 format: new OpenLayers.Format.GML.v2({ 11 featureType: "type", 12 featureNS: "http://namespace.org" 13 }) 14 }); 15 t.ok(protocol instanceof OpenLayers.Protocol.WFS.v1_0_0, 16 "initialize returns instance") 17 } 18 19 function test_read(t) { 20 t.plan(2); 21 22 var url = "http://some.url.org"; 23 var protocol = new OpenLayers.Protocol.WFS.v1_0_0({ 24 url: url, 25 featureNS: "http://namespace.org", 26 featureType: "type", 27 format: new OpenLayers.Format.GML.v2({ 28 featureNS: "http://namespace.org", 29 featureType: "type", 30 }) 31 }); 32 33 var _POST = OpenLayers.Request.POST; 34 35 OpenLayers.Request.POST = function(obj) { 36 return obj; 37 }; 38 39 var response = protocol.read(); 40 var simpleReadXML = '<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0" outputFormat="GML2"><wfs:Query typeName="feature:type" srsName="EPSG:4326" xmlns:feature="http://namespace.org"/></wfs:GetFeature>'; 41 42 var request = response.priv; 43 t.xml_eq(request.data, simpleReadXML, "read with no option"); 44 45 options = { 46 maxFeatures: 10, 47 featureType: 'type2', 48 srsName: 'EPSG:900913', 49 featureNS: 'htttp://alternative.namespace.org' 50 }; 51 var optionsReadXML = '<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0" maxFeatures="10" outputFormat="GML2"><wfs:Query typeName="feature:type2" srsName="EPSG:900913" xmlns:feature="htttp://alternative.namespace.org"/></wfs:GetFeature>'; 52 53 var response = protocol.read(options); 54 var request = response.priv; 55 t.xml_eq(request.data, optionsReadXML, "read with options") 56 57 OpenLayers.Request.POST = _POST; 58 } 59 60 function test_update(t) { 61 t.plan( 4 ); 62 63 var url = "http://some.url.org"; 64 var protocol = new OpenLayers.Protocol.WFS.v1_0_0({ 65 url: url, 66 featureNS: "http://namespace.org", 67 featureType: "type", 68 format: new OpenLayers.Format.GML.v2({ 69 featureNS: "http://namespace.org", 70 featureType: "type", 71 }) 72 }); 73 74 var test_feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(42, 7), {has : "cheeseburger"}); 75 test_feature.fid = "fid.37"; 76 test_feature.layer = { 77 projection: { 78 getCode : function(){ 79 return "EPSG:4326"; 80 } 81 } 82 } 83 84 options = {featureNS: "http://some.namespace.org", featureType: "type"} 85 86 var node = protocol.update(test_feature,options); 87 88 t.ok(node,"Output of update is not null"); 89 t.eq(node.nodeType, 1, "Output of update is a node of the proper type."); 90 t.eq(node.tagName, "wfs:Update", "Tagname is the appropriate one."); 91 t.eq(node.textContent, "the_geom42,7hascheeseburger", "The node created by update has the right textcontent."); 92 } 93 94 function test_delete(t) { 95 t.plan( 2 ); 96 97 var url = "http://some.url.org"; 98 var protocol = new OpenLayers.Protocol.WFS.v1_0_0({ 99 url: url, 100 featureNS: "http://namespace.org", 101 featureType: "type", 102 format: new OpenLayers.Format.GML.v2({ 103 featureNS: "http://namespace.org", 104 featureType: "type", 105 }) 106 }); 107 108 var test_feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(42, 7), {has : "cheeseburger"}); 109 test_feature.fid = "fid.37"; 110 test_feature.layer = { 111 projection: { 112 getCode : function(){ 113 return "EPSG:4326"; 114 } 115 } 116 } 117 118 options = {featureNS: "http://some.namespace.org", featureType: "type"} 119 var node = protocol['delete'](test_feature, options); 120 121 t.eq(node.tagName, "wfs:Delete", "Tagname is the appropriate one."); 122 t.eq(node.firstChild.firstChild.attributes.fid.nodeValue, "fid.37", "The right fid is stored in an attribute as expected."); 123 } 124 125 126 //TODO: Add more commit tests 127 function test_commit(t){ 128 t.plan(2); 129 130 var url = "http://some.url.org"; 131 var protocol = new OpenLayers.Protocol.WFS.v1_0_0({ 132 url: url, 133 featureNS: "http://namespace.org", 134 featureType: "type", 135 format: new OpenLayers.Format.GML.v2({ 136 featureNS: "http://namespace.org", 137 featureType: "type", 138 }) 139 }); 140 141 var _POST = OpenLayers.Request.POST; 142 OpenLayers.Request.POST = function(object) { 143 return object; 144 }; 145 146 var featureFactory = function(attribute, id) { 147 var feature = new OpenLayers.Feature.Vector( 148 new OpenLayers.Geometry.Point(42, 7), {has: attribute} 149 ); 150 feature.layer = { 151 projection: { 152 getCode : function(){ 153 return "EPSG:4326"; 154 } 155 } 156 } 157 feature.fid = "fid." + id; 158 return feature; 159 } 160 161 var test_feature1 = featureFactory("cheeseburger",7); 162 163 var response = protocol.commit([test_feature1]); 164 var request = response.priv; 165 var expected = '<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0" outputFormat="GML2" />'; 166 167 t.xml_eq(request.data, expected, "Correct envelope XML for request data for no changed features"); 168 169 //testing getMethod 170 test_feature1.state = OpenLayers.State.INSERT; 171 172 var test_feature2 = featureFactory("lolcat", 8); 173 test_feature2.state = OpenLayers.State.UPDATE; 174 175 var test_feature3 = featureFactory("asdf", 9); 176 test_feature3.state = OpenLayers.State.DELETE; 177 178 var response = protocol.commit([test_feature1, test_feature2, test_feature3]); 179 var request = response.priv; 180 181 expected = '<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0" outputFormat="GML2" xmlns:feature="http://namespace.org"><wfs:Insert><feature:type fid="fid.7"><feature:geometry><gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">42,7</gml:coordinates></gml:Point></feature:geometry><feature:has>cheeseburger</feature:has></feature:type></wfs:Insert><wfs:Update typeName="feature:type"><wfs:Property><wfs:Name>the_geom</wfs:Name><wfs:Value><gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">42,7</gml:coordinates></gml:Point></wfs:Value></wfs:Property><wfs:Property><wfs:Name>has</wfs:Name><wfs:Value>lolcat</wfs:Value></wfs:Property><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="fid.8"/></ogc:Filter></wfs:Update><wfs:Delete typeName="feature:type"><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:FeatureId fid="fid.9"/></ogc:Filter></wfs:Delete></wfs:Transaction>'; 182 183 t.xml_eq(request.data, expected, "Got expected XML for commit with insert, update, and delete"); 184 185 OpenLayers.Request.POST = _POST; 186 } 187 188 function test_callback(t) { 189 t.plan(3) 190 191 var xmlText = '<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult><ogc:FeatureId fid="new0"/><ogc:FeatureId fid="new1"/><ogc:FeatureId fid="new2"/><ogc:FeatureId fid="new3"/><ogc:FeatureId fid="new4"/><ogc:FeatureId fid="new5"/></wfs:InsertResult> <wfs:TransactionResult> <wfs:Status> <wfs:SUCCESS/> </wfs:Status> </wfs:TransactionResult></wfs:WFS_TransactionResponse>'; 192 193 var url = "http://some.url.org"; 194 var protocol = new OpenLayers.Protocol.WFS.v1_0_0({ 195 url: url, 196 featureNS: "http://namespace.org", 197 featureType: "type", 198 format: new OpenLayers.Format.GML.v2({ 199 featureNS: "http://namespace.org", 200 featureType: "type", 201 }) 202 }); 203 204 var _POST = OpenLayers.Request.POST; 205 var xml = new OpenLayers.Format.XML(); 206 OpenLayers.Request.POST = function(obj) { 207 var request = {responseXML: xml.read(xmlText)}; 208 window.setTimeout(function() { 209 obj.callback.call(obj.scope, request); 210 }, 0.1); 211 t.delay_call(0.2, function() { 212 t.ok(cbResponse.success(), "success parsed and set on response"); 213 t.eq(cbResponse.insertIds, ["new0","new1","new2","new3","new4","new5"], 214 "Inserted FIDs parsed and passed through to callback"); 215 t.eq(cbScope.foo, "bar", "Callback called in proper scope"); 216 }); 217 return request; 218 }; 219 220 var cbResponse, cbScope; 221 var options = { 222 callback: function(response) { 223 cbResponse = response; 224 cbScope = this; 225 }, 226 scope: {foo: "bar"} 227 }; 228 var response = protocol.commit([], options); 229 230 OpenLayers.Request.POST = _POST; 231 } 232 233 </script> 234 </head> 235 <body> 236 <div id="map" style="width:512px; height:256px"> </div> 237 </body> 238 </html> -
tests/list-tests.html
old new 119 119 <li>Protocol/HTTP.html</li> 120 120 <li>Protocol/SQL.html</li> 121 121 <li>Protocol/SQL/Gears.html</li> 122 <li>Protocol/WFS/v1_0_0.html</li> 122 123 <li>Renderer.html</li> 123 124 <li>Renderer/Canvas.html</li> 124 125 <li>Renderer/Elements.html</li> -
lib/OpenLayers/Filter/Comparison.js
old new 46 46 value: null, 47 47 48 48 /** 49 * Property: matchCase 50 * {Boolean} Force case sensitive searches for EQUAL_TO comparisons. The 51 * Filter Encoding 1.1 specification added a matchCase attribute to 52 * ogc:PropertyIsEqualTo elements. This property will be serialized 53 * with those elements only if using the v1.1.0 filter format. 54 * However, when evaluating filters here, the matchCase property 55 * will always be respected (for EQUAL_TO). Default is true. 56 */ 57 matchCase: true, 58 59 /** 49 60 * APIProperty: lowerBoundary 50 61 * {Number} or {String} 51 62 * lower boundary for between comparisons. In the case of a String, this … … 90 101 * {Boolean} The filter applies. 91 102 */ 92 103 evaluate: function(context) { 104 var result = false; 93 105 switch(this.type) { 94 106 case OpenLayers.Filter.Comparison.EQUAL_TO: 107 var got = context[this.property]; 108 var exp = this.value; 109 if(!this.matchCase && 110 typeof got == "string" && typeof exp == "string") { 111 result = (got.toUpperCase() == exp.toUpperCase()); 112 } else { 113 result = (got == exp); 114 } 115 break; 116 case OpenLayers.Filter.Comparison.NOT_EQUAL_TO: 117 result = (context[this.property] != this.value); 118 break; 95 119 case OpenLayers.Filter.Comparison.LESS_THAN: 120 result = context[this.property] < this.value; 121 break; 96 122 case OpenLayers.Filter.Comparison.GREATER_THAN: 123 result = context[this.property] > this.value; 124 break; 97 125 case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO: 126 result = context[this.property] <= this.value; 127 break; 98 128 case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO: 99 re turn this.binaryCompare(context, this.property, this.value);100 129 result = context[this.property] >= this.value; 130 break; 101 131 case OpenLayers.Filter.Comparison.BETWEEN: 102 var result = 103 context[this.property] >= this.lowerBoundary; 104 result = result && 105 context[this.property] <= this.upperBoundary; 106 return result; 132 result = (context[this.property] >= this.lowerBoundary) && 133 (context[this.property] <= this.upperBoundary); 134 break; 107 135 case OpenLayers.Filter.Comparison.LIKE: 108 var regexp = new RegExp(this.value, 109 "gi");110 return regexp.test(context[this.property]);136 var regexp = new RegExp(this.value, "gi"); 137 result = regexp.test(context[this.property]); 138 break; 111 139 } 140 return result; 112 141 }, 113 142 114 143 /** … … 191 220 192 221 return value; 193 222 }, 194 195 /**196 * Function: binaryCompare197 * Compares a feature property to a rule value198 *199 * Parameters:200 * context - {Object}201 * property - {String} or {Number}202 * value - {String} or {Number}, same as property203 *204 * Returns:205 * {Boolean}206 */207 binaryCompare: function(context, property, value) {208 switch (this.type) {209 case OpenLayers.Filter.Comparison.EQUAL_TO:210 return context[property] == value;211 case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:212 return context[property] != value;213 case OpenLayers.Filter.Comparison.LESS_THAN:214 return context[property] < value;215 case OpenLayers.Filter.Comparison.GREATER_THAN:216 return context[property] > value;217 case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:218 return context[property] <= value;219 case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:220 return context[property] >= value;221 }222 },223 223 224 224 CLASS_NAME: "OpenLayers.Filter.Comparison" 225 225 }); -
lib/OpenLayers/Format/GML/v3.js
old new 141 141 }, 142 142 "lowerCorner": function(node, container) { 143 143 var obj = {}; 144 this.read ChildNodes(node, obj);144 this.readers.gml.pos.apply(this, [node, obj]); 145 145 container.points[0] = obj.points[0]; 146 146 }, 147 147 "upperCorner": function(node, container) { 148 148 var obj = {}; 149 this.read ChildNodes(node, obj);149 this.readers.gml.pos.apply(this, [node, obj]); 150 150 container.points[1] = obj.points[0]; 151 151 } 152 152 }, OpenLayers.Format.GML.Base.prototype.readers["gml"]), … … 268 268 return node; 269 269 }, 270 270 "lowerCorner": function(bounds) { 271 var node = this.createElementNSPlus("gml:lowerCorner"); 272 this.writeNode("pos", {x: bounds.left, y: bounds.bottom}, node); 273 return node; 271 // only 2d for simple features profile 272 var pos = (this.xy) ? 273 (bounds.left + " " + bounds.bottom) : 274 (bounds.bottom + " " + bounds.left); 275 return this.createElementNSPlus("gml:lowerCorner", { 276 value: pos 277 }); 274 278 }, 275 279 "upperCorner": function(bounds) { 276 var node = this.createElementNSPlus("gml:upperCorner"); 277 this.writeNode("pos", {x: bounds.right, y: bounds.top}, node); 278 return node; 280 // only 2d for simple features profile 281 var pos = (this.xy) ? 282 (bounds.right + " " + bounds.top) : 283 (bounds.top + " " + bounds.right); 284 return this.createElementNSPlus("gml:upperCorner", { 285 value: pos 286 }); 279 287 } 280 288 }, OpenLayers.Format.GML.Base.prototype.writers["gml"]), 281 289 "feature": OpenLayers.Format.GML.Base.prototype.writers["feature"], -
lib/OpenLayers/Format/GML/Base.js
old new 8 8 */ 9 9 10 10 /** 11 * Though required in the full build, if the GML format is excluded, we set 12 * the namespace here. 13 */ 14 if(!OpenLayers.Format.GML) { 15 OpenLayers.Format.GML = {}; 16 } 17 18 /** 11 19 * Class: OpenLayers.Format.GML.Base 12 20 * Superclass for GML parsers. 13 21 * -
lib/OpenLayers/Format/SLD/v1.js
old new 396 396 ); 397 397 // add in optional name 398 398 if(sld.name) { 399 this.writeNode( root, "Name", sld.name);399 this.writeNode("Name", sld.name, root); 400 400 } 401 401 // add in optional title 402 402 if(sld.title) { 403 this.writeNode( root, "Title", sld.title);403 this.writeNode("Title", sld.title, root); 404 404 } 405 405 // add in optional description 406 406 if(sld.description) { 407 this.writeNode( root, "Abstract", sld.description);407 this.writeNode("Abstract", sld.description, root); 408 408 } 409 409 // add in named layers 410 410 for(var name in sld.namedLayers) { 411 this.writeNode( root, "NamedLayer", sld.namedLayers[name]);411 this.writeNode("NamedLayer", sld.namedLayers[name], root); 412 412 } 413 413 return root; 414 414 }, … … 427 427 var node = this.createElementNSPlus("NamedLayer"); 428 428 429 429 // add in required name 430 this.writeNode( node, "Name", layer.name);430 this.writeNode("Name", layer.name, node); 431 431 432 432 // optional sld:LayerFeatureConstraints here 433 433 … … 435 435 if(layer.namedStyles) { 436 436 for(var i=0, len=layer.namedStyles.length; i<len; ++i) { 437 437 this.writeNode( 438 node, "NamedStyle", layer.namedStyles[i]438 "NamedStyle", layer.namedStyles[i], node 439 439 ); 440 440 } 441 441 } … … 444 444 if(layer.userStyles) { 445 445 for(var i=0, len=layer.userStyles.length; i<len; ++i) { 446 446 this.writeNode( 447 node, "UserStyle", layer.userStyles[i]447 "UserStyle", layer.userStyles[i], node 448 448 ); 449 449 } 450 450 } … … 453 453 }, 454 454 "NamedStyle": function(name) { 455 455 var node = this.createElementNSPlus("NamedStyle"); 456 this.writeNode( node, "Name", name);456 this.writeNode("Name", name, node); 457 457 return node; 458 458 }, 459 459 "UserStyle": function(style) { … … 461 461 462 462 // add in optional name 463 463 if(style.name) { 464 this.writeNode( node, "Name", style.name);464 this.writeNode("Name", style.name, node); 465 465 } 466 466 // add in optional title 467 467 if(style.title) { 468 this.writeNode( node, "Title", style.title);468 this.writeNode("Title", style.title, node); 469 469 } 470 470 // add in optional description 471 471 if(style.description) { 472 this.writeNode( node, "Abstract", style.description);472 this.writeNode("Abstract", style.description, node); 473 473 } 474 474 475 475 // add isdefault 476 476 if(style.isDefault) { 477 this.writeNode( node, "IsDefault", style.isDefault);477 this.writeNode("IsDefault", style.isDefault, node); 478 478 } 479 479 480 480 // add FeatureTypeStyles 481 this.writeNode( node, "FeatureTypeStyle", style);481 this.writeNode("FeatureTypeStyle", style, node); 482 482 483 483 return node; 484 484 }, … … 496 496 497 497 // add in rules 498 498 for(var i=0, len=style.rules.length; i<len; ++i) { 499 this.writeNode( node, "Rule", style.rules[i]);499 this.writeNode("Rule", style.rules[i], node); 500 500 } 501 501 502 502 return node; … … 506 506 507 507 // add in optional name 508 508 if(rule.name) { 509 this.writeNode( node, "Name", rule.name);509 this.writeNode("Name", rule.name, node); 510 510 } 511 511 // add in optional title 512 512 if(rule.title) { 513 this.writeNode( node, "Title", rule.title);513 this.writeNode("Title", rule.title, node); 514 514 } 515 515 // add in optional description 516 516 if(rule.description) { 517 this.writeNode( node, "Abstract", rule.description);517 this.writeNode("Abstract", rule.description, node); 518 518 } 519 519 520 520 // add in LegendGraphic here 521 521 522 522 // add in optional filters 523 523 if(rule.elseFilter) { 524 this.writeNode( node, "ElseFilter");524 this.writeNode("ElseFilter", null, node); 525 525 } else if(rule.filter) { 526 this.writeNode( node, "ogc:Filter", rule.filter);526 this.writeNode("ogc:Filter", rule.filter, node); 527 527 } 528 528 529 529 // add in scale limits 530 530 if(rule.minScaleDenominator != undefined) { 531 531 this.writeNode( 532 node, "MinScaleDenominator", rule.minScaleDenominator532 "MinScaleDenominator", rule.minScaleDenominator, node 533 533 ); 534 534 } 535 535 if(rule.maxScaleDenominator != undefined) { 536 536 this.writeNode( 537 node, "MaxScaleDenominator", rule.maxScaleDenominator537 "MaxScaleDenominator", rule.maxScaleDenominator, node 538 538 ); 539 539 } 540 540 … … 546 546 symbolizer = rule.symbolizer[type]; 547 547 if(symbolizer) { 548 548 this.writeNode( 549 node, type + "Symbolizer", symbolizer549 type + "Symbolizer", symbolizer, node 550 550 ); 551 551 } 552 552 } … … 568 568 }, 569 569 "LineSymbolizer": function(symbolizer) { 570 570 var node = this.createElementNSPlus("LineSymbolizer"); 571 this.writeNode( node, "Stroke", symbolizer);571 this.writeNode("Stroke", symbolizer, node); 572 572 return node; 573 573 }, 574 574 "Stroke": function(symbolizer) { … … 580 580 // add in CssParameters 581 581 if(symbolizer.strokeColor != undefined) { 582 582 this.writeNode( 583 node, "CssParameter", 584 {symbolizer: symbolizer, key: "strokeColor"} 583 "CssParameter", 584 {symbolizer: symbolizer, key: "strokeColor"}, 585 node 585 586 ); 586 587 } 587 588 if(symbolizer.strokeOpacity != undefined) { 588 589 this.writeNode( 589 node, "CssParameter", 590 {symbolizer: symbolizer, key: "strokeOpacity"} 590 "CssParameter", 591 {symbolizer: symbolizer, key: "strokeOpacity"}, 592 node 591 593 ); 592 594 } 593 595 if(symbolizer.strokeWidth != undefined) { 594 596 this.writeNode( 595 node, "CssParameter", 596 {symbolizer: symbolizer, key: "strokeWidth"} 597 "CssParameter", 598 {symbolizer: symbolizer, key: "strokeWidth"}, 599 node 597 600 ); 598 601 } 599 602 return node; … … 609 612 var node = this.createElementNSPlus("TextSymbolizer"); 610 613 // add in optional Label 611 614 if(symbolizer.label != null) { 612 this.writeNode( node, "Label", symbolizer.label);615 this.writeNode("Label", symbolizer.label, node); 613 616 } 614 617 // add in optional Font 615 618 if(symbolizer.fontFamily != null || 616 619 symbolizer.fontSize != null) { 617 this.writeNode( node, "Font", symbolizer);620 this.writeNode("Font", symbolizer, node); 618 621 } 619 622 // add in optional Fill 620 623 if(symbolizer.fillColor != null || 621 624 symbolizer.fillOpacity != null) { 622 this.writeNode( node, "Fill", symbolizer);625 this.writeNode("Fill", symbolizer, node); 623 626 } 624 627 return node; 625 628 }, … … 628 631 // add in CssParameters 629 632 if(symbolizer.fontFamily) { 630 633 this.writeNode( 631 node, "CssParameter", 632 {symbolizer: symbolizer, key: "fontFamily"} 634 "CssParameter", 635 {symbolizer: symbolizer, key: "fontFamily"}, 636 node 633 637 ); 634 638 } 635 639 if(symbolizer.fontSize) { 636 640 this.writeNode( 637 node, "CssParameter", 638 {symbolizer: symbolizer, key: "fontSize"} 641 "CssParameter", 642 {symbolizer: symbolizer, key: "fontSize"}, 643 node 639 644 ); 640 645 } 641 646 return node; … … 652 657 last = item.indexOf("}"); 653 658 if(last > 0) { 654 659 this.writeNode( 655 node, "ogc:PropertyName", 656 {property: item.substring(0, last)} 660 "ogc:PropertyName", 661 {property: item.substring(0, last)}, 662 node 657 663 ); 658 664 node.appendChild( 659 665 this.createTextNode(item.substring(++last)) … … 669 675 }, 670 676 "PolygonSymbolizer": function(symbolizer) { 671 677 var node = this.createElementNSPlus("PolygonSymbolizer"); 672 this.writeNode( node, "Fill", symbolizer);673 this.writeNode( node, "Stroke", symbolizer);678 this.writeNode("Fill", symbolizer, node); 679 this.writeNode("Stroke", symbolizer, node); 674 680 return node; 675 681 }, 676 682 "Fill": function(symbolizer) { … … 681 687 // add in CssParameters 682 688 if(symbolizer.fillColor) { 683 689 this.writeNode( 684 node, "CssParameter", 685 {symbolizer: symbolizer, key: "fillColor"} 690 "CssParameter", 691 {symbolizer: symbolizer, key: "fillColor"}, 692 node 686 693 ); 687 694 } 688 695 if(symbolizer.fillOpacity) { 689 696 this.writeNode( 690 node, "CssParameter", 691 {symbolizer: symbolizer, key: "fillOpacity"} 697 "CssParameter", 698 {symbolizer: symbolizer, key: "fillOpacity"}, 699 node 692 700 ); 693 701 } 694 702 return node; 695 703 }, 696 704 "PointSymbolizer": function(symbolizer) { 697 705 var node = this.createElementNSPlus("PointSymbolizer"); 698 this.writeNode( node, "Graphic", symbolizer);706 this.writeNode("Graphic", symbolizer, node); 699 707 return node; 700 708 }, 701 709 "Graphic": function(symbolizer) { 702 710 var node = this.createElementNSPlus("Graphic"); 703 711 if(symbolizer.externalGraphic != undefined) { 704 this.writeNode( node, "ExternalGraphic", symbolizer);712 this.writeNode("ExternalGraphic", symbolizer, node); 705 713 } else if(symbolizer.graphicName) { 706 this.writeNode( node, "Mark", symbolizer);714 this.writeNode("Mark", symbolizer, node); 707 715 } 708 716 709 717 if(symbolizer.graphicOpacity != undefined) { 710 this.writeNode( node, "Opacity", symbolizer.graphicOpacity);718 this.writeNode("Opacity", symbolizer.graphicOpacity, node); 711 719 } 712 720 if(symbolizer.pointRadius != undefined) { 713 this.writeNode( node, "Size", symbolizer.pointRadius * 2);721 this.writeNode("Size", symbolizer.pointRadius * 2, node); 714 722 } 715 723 if(symbolizer.rotation != undefined) { 716 this.writeNode( node, "Rotation", symbolizer.rotation);724 this.writeNode("Rotation", symbolizer.rotation, node); 717 725 } 718 726 return node; 719 727 }, 720 728 "ExternalGraphic": function(symbolizer) { 721 729 var node = this.createElementNSPlus("ExternalGraphic"); 722 730 this.writeNode( 723 node, "OnlineResource", symbolizer.externalGraphic731 "OnlineResource", symbolizer.externalGraphic, node 724 732 ); 725 733 var format = symbolizer.graphicFormat || 726 734 this.getGraphicFormat(symbolizer.externalGraphic); 727 this.writeNode( node, "Format", format);735 this.writeNode("Format", format, node); 728 736 return node; 729 737 }, 730 738 "Mark": function(symbolizer) { 731 739 var node = this.createElementNSPlus("Mark"); 732 this.writeNode( node, "WellKnownName", symbolizer.graphicName);733 this.writeNode( node, "Fill", symbolizer);734 this.writeNode( node, "Stroke", symbolizer);740 this.writeNode("WellKnownName", symbolizer.graphicName, node); 741 this.writeNode("Fill", symbolizer, node); 742 this.writeNode("Stroke", symbolizer, node); 735 743 return node; 736 744 }, 737 745 "WellKnownName": function(name) { … … 770 778 } 771 779 }, 772 780 773 /**774 * Methods below this point are of general use for versioned XML parsers.775 * These are candidates for an abstract class.776 */777 778 /**779 * Method: getNamespacePrefix780 * Get the namespace prefix for a given uri from the <namespaces> object.781 *782 * Returns:783 * {String} A namespace prefix or null if none found.784 */785 getNamespacePrefix: function(uri) {786 var prefix = null;787 if(uri == null) {788 prefix = this.namespaces[this.defaultPrefix];789 } else {790 var gotPrefix = false;791 for(prefix in this.namespaces) {792 if(this.namespaces[prefix] == uri) {793 gotPrefix = true;794 break;795 }796 }797 if(!gotPrefix) {798 prefix = null;799 }800 }801 return prefix;802 },803 804 805 /**806 * Method: readChildNodes807 */808 readChildNodes: function(node, obj) {809 var children = node.childNodes;810 var child, group, reader, prefix, local;811 for(var i=0, len=children.length; i<len; ++i) {812 child = children[i];813 if(child.nodeType == 1) {814 prefix = this.getNamespacePrefix(child.namespaceURI);815 local = child.nodeName.split(":").pop();816 group = this.readers[prefix];817 if(group) {818 reader = group[local];819 if(reader) {820 reader.apply(this, [child, obj]);821 }822 }823 }824 }825 },826 827 /**828 * Method: writeNode829 * Shorthand for applying one of the named writers and appending the830 * results to a node. If a qualified name is not provided for the831 * second argument (and a local name is used instead), the namespace832 * of the parent node will be assumed.833 *834 * Parameters:835 * parent - {DOMElement} Result will be appended to this node.836 * name - {String} The name of a node to generate. If a qualified name837 * (e.g. "pre:Name") is used, the namespace prefix is assumed to be838 * in the <writers> group. If a local name is used (e.g. "Name") then839 * the namespace of the parent is assumed.840 * obj - {Object} Structure containing data for the writer.841 *842 * Returns:843 * {DOMElement} The child node.844 */845 writeNode: function(parent, name, obj) {846 var prefix, local;847  
