summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Format
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/tests/Format')
-rw-r--r--misc/openlayers/tests/Format/ArcXML.html277
-rw-r--r--misc/openlayers/tests/Format/ArcXML/Features.html69
-rw-r--r--misc/openlayers/tests/Format/Atom.html450
-rw-r--r--misc/openlayers/tests/Format/CQL.html364
-rw-r--r--misc/openlayers/tests/Format/CSWGetDomain.html23
-rw-r--r--misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.html56
-rw-r--r--misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.js18
-rw-r--r--misc/openlayers/tests/Format/CSWGetRecords.html23
-rw-r--r--misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.html88
-rw-r--r--misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.js50
-rw-r--r--misc/openlayers/tests/Format/EncodedPolyline.html372
-rw-r--r--misc/openlayers/tests/Format/Filter.html21
-rw-r--r--misc/openlayers/tests/Format/Filter/v1.html404
-rw-r--r--misc/openlayers/tests/Format/Filter/v1_0_0.html295
-rw-r--r--misc/openlayers/tests/Format/Filter/v1_1_0.html402
-rw-r--r--misc/openlayers/tests/Format/GML.html462
-rw-r--r--misc/openlayers/tests/Format/GML/cases.js232
-rw-r--r--misc/openlayers/tests/Format/GML/v2.html684
-rw-r--r--misc/openlayers/tests/Format/GML/v3.html828
-rw-r--r--misc/openlayers/tests/Format/GPX.html179
-rw-r--r--misc/openlayers/tests/Format/GeoJSON.html468
-rw-r--r--misc/openlayers/tests/Format/GeoRSS.html122
-rw-r--r--misc/openlayers/tests/Format/JSON.html53
-rw-r--r--misc/openlayers/tests/Format/KML.html1437
-rw-r--r--misc/openlayers/tests/Format/OGCExceptionReport.html100
-rw-r--r--misc/openlayers/tests/Format/OSM.html115
-rw-r--r--misc/openlayers/tests/Format/OWSCommon/v1_0_0.html34
-rw-r--r--misc/openlayers/tests/Format/OWSCommon/v1_1_0.html34
-rw-r--r--misc/openlayers/tests/Format/OWSContext/v0_3_1.html278
-rw-r--r--misc/openlayers/tests/Format/QueryStringFilter.html306
-rw-r--r--misc/openlayers/tests/Format/SLD.html36
-rw-r--r--misc/openlayers/tests/Format/SLD/v1_0_0.html1028
-rw-r--r--misc/openlayers/tests/Format/SLD/v1_0_0_GeoServer.html228
-rw-r--r--misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.html80
-rw-r--r--misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.js484
-rw-r--r--misc/openlayers/tests/Format/SOSGetFeatureOfInterest.html80
-rw-r--r--misc/openlayers/tests/Format/SOSGetObservation.html183
-rw-r--r--misc/openlayers/tests/Format/Text.html49
-rw-r--r--misc/openlayers/tests/Format/WCSCapabilities.html43
-rw-r--r--misc/openlayers/tests/Format/WCSCapabilities/v1.html87
-rw-r--r--misc/openlayers/tests/Format/WCSGetCoverage.html80
-rw-r--r--misc/openlayers/tests/Format/WFS.html81
-rw-r--r--misc/openlayers/tests/Format/WFSCapabilities.html43
-rw-r--r--misc/openlayers/tests/Format/WFSCapabilities/v1.html179
-rw-r--r--misc/openlayers/tests/Format/WFSDescribeFeatureType.html436
-rw-r--r--misc/openlayers/tests/Format/WFST.html23
-rw-r--r--misc/openlayers/tests/Format/WFST/v1.html455
-rw-r--r--misc/openlayers/tests/Format/WFST/v1_0_0.html135
-rw-r--r--misc/openlayers/tests/Format/WFST/v1_1_0.html236
-rw-r--r--misc/openlayers/tests/Format/WKT.html297
-rw-r--r--misc/openlayers/tests/Format/WMC.html315
-rw-r--r--misc/openlayers/tests/Format/WMC/v1.html266
-rw-r--r--misc/openlayers/tests/Format/WMC/v1_1_0.html86
-rw-r--r--misc/openlayers/tests/Format/WMSCapabilities.html20
-rw-r--r--misc/openlayers/tests/Format/WMSCapabilities/v1_1_1.html5209
-rw-r--r--misc/openlayers/tests/Format/WMSCapabilities/v1_1_1_WMSC.html348
-rw-r--r--misc/openlayers/tests/Format/WMSCapabilities/v1_3_0.html614
-rw-r--r--misc/openlayers/tests/Format/WMSDescribeLayer.html65
-rw-r--r--misc/openlayers/tests/Format/WMSGetFeatureInfo.html319
-rw-r--r--misc/openlayers/tests/Format/WMTSCapabilities.html20
-rw-r--r--misc/openlayers/tests/Format/WMTSCapabilities/v1_0_0.html1042
-rw-r--r--misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.html30
-rw-r--r--misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.js112
-rw-r--r--misc/openlayers/tests/Format/WPSDescribeProcess.html206
-rw-r--r--misc/openlayers/tests/Format/WPSExecute.html549
-rw-r--r--misc/openlayers/tests/Format/XLS/v1_1_0.html98
-rw-r--r--misc/openlayers/tests/Format/XML.html900
-rw-r--r--misc/openlayers/tests/Format/XML/VersionedOGC.html51
68 files changed, 22757 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Format/ArcXML.html b/misc/openlayers/tests/Format/ArcXML.html
new file mode 100644
index 0000000..ea7d273
--- /dev/null
+++ b/misc/openlayers/tests/Format/ArcXML.html
@@ -0,0 +1,277 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var axl_image_response = '<?xml version="1.0" encoding="UTF-8"?><ARCXML version="1.1"><RESPONSE><IMAGE><ENVELOPE minx="-2471.42857142857" miny="0" maxx="105671.428571429" maxy="75700" /><OUTPUT url="http://localhost/output/364826560.png" /></IMAGE></RESPONSE></ARCXML>';
+ var axl_feature_response = '<?xml version="1.0" encoding="Cp1252"?><ARCXML version="1.1"><RESPONSE><FEATURES><FEATURE><FIELDS><FIELD name="UNIQUE_ID" value="514504b5-0458-461d-b540-8e18a454f619" /><FIELD name="LABEL" value="LIBRARY" /><FIELD name="Y_COORD" value="39.57" /><FIELD name="X_COORD" value="-104.24" /><FIELD name="#SHAPE#" value="[Geometry]" /><FIELD name="OBJECTID" value="1" /><FIELD name="shape.area" value="0" /><FIELD name="shape.len" value="0" /></FIELDS></FEATURE><FEATURE><FIELDS><FIELD name="UNIQUE_ID" value="514504b5-0458-461d-b540-8e81a454f619" /><FIELD name="LABEL" value="LIBRARY2" /><FIELD name="Y_COORD" value="39.75" /><FIELD name="X_COORD" value="-104.42" /><FIELD name="#SHAPE#" value="[Geometry]" /><FIELD name="OBJECTID" value="2" /><FIELD name="shape.area" value="0" /><FIELD name="shape.len" value="0" /></FIELDS></FEATURE><FEATURECOUNT count="2" hasmore="false" /><ENVELOPE minx="-678853.220047791" miny="1810.22081371862" maxx="-678853.220047791" maxy="1810.22081371862"/></FEATURES></RESPONSE></ARCXML>';
+
+ //
+ // creating a new arcxml format creates an object that has a read and write function
+ //
+ function test_Format_ArcXML_constructor1(t) {
+ t.plan(4);
+
+ var format = new OpenLayers.Format.ArcXML();
+ t.ok(format instanceof OpenLayers.Format.ArcXML,
+ "new OpenLayers.Format.ArcXML returns object" );
+
+ t.ok(format.request, null, "no options creates a null request");
+
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ //
+ // creating a new arcxml format with a set of options for an image request
+ // creates a request child object, and a get_image grandchild.
+ //
+ function test_Format_ArcXML_constructor2(t) {
+ t.plan(6);
+
+ var options = {
+ requesttype:'image',
+ envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),
+ layers: [],
+ tileSize: new OpenLayers.Size( 256,256 ),
+ featureCoordSys: '4326',
+ filterCoordSys: '4326'
+ };
+
+ var format = new OpenLayers.Format.ArcXML( options );
+ t.ok(format instanceof OpenLayers.Format.ArcXML,
+ "new OpenLayers.Format.ArcXML returns object" );
+
+ t.ok(format.request instanceof OpenLayers.Format.ArcXML.Request,
+ "constructor with 'image' requesttype generates a request");
+ t.ok( format.request.get_image !== null, "get_image property exists" );
+ t.ok( format.request.get_feature === null, "get_feature property does not exists" );
+
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ //
+ // creating a new arcxml format with a set of options for a feature request
+ // creates a request child object, and a get_feature grandchild
+ //
+ function test_Format_ArcXML_constructor3(t) {
+ t.plan(6);
+
+ var options = {
+ requesttype:'feature'
+ };
+
+ var format = new OpenLayers.Format.ArcXML( options );
+ t.ok(format instanceof OpenLayers.Format.ArcXML,
+ "new OpenLayers.Format.ArcXML returns object" );
+
+ t.ok(format.request instanceof OpenLayers.Format.ArcXML.Request,
+ "constructor with 'feature' requesttype generates a request");
+ t.ok( format.request.get_feature !== null, "get_feature property exists" );
+ t.ok( format.request.get_image === null, "get_image property does not exists" );
+
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ //
+ // read in a known good axl image response
+ //
+ function test_Format_ArcXML_read1(t) {
+ t.plan(4);
+ var f = new OpenLayers.Format.ArcXML();
+ var response = f.read(axl_image_response);
+
+ t.ok(response !== null, "get_image response object is not null" );
+ t.ok(response.image !== null, "get_image image tag is not null");
+ t.ok(response.image.envelope !== null, "get_image image envelope tag is not null");
+ t.ok(response.image.output !== null, "get_image image output tag is not null");
+ }
+
+ //
+ // read in a known good axl feature response
+ //
+ function test_Format_ArcXML_read2(t) {
+ t.plan(10);
+ var f = new OpenLayers.Format.ArcXML();
+ var response = f.read(axl_feature_response);
+
+ t.ok(response !== null, "get_feature response object is not null" );
+ t.ok(response.features !== null, "get_feature features tag is not null");
+ t.ok(response.features.envelope !== null, "get_feature envelope tag is not null");
+ t.eq(response.features.featurecount, "2", "feature count is 2" );
+
+ // test the second feature parsed
+ // <FIELD name="UNIQUE_ID" value="514504b5-0458-461d-b540-8e81a454f619" />
+ // <FIELD name="LABEL" value="LIBRARY2" />
+ // <FIELD name="Y_COORD" value="39.75" />
+ // <FIELD name="X_COORD" value="-104.42" />
+ // <FIELD name="#SHAPE#" value="[Geometry]" />
+ // <FIELD name="OBJECTID" value="2" />
+ // <FIELD name="shape.area" value="0" />
+ // <FIELD name="shape.len" value="0" />
+ t.eq( response.features.feature[1].attributes['UNIQUE_ID'], "514504b5-0458-461d-b540-8e81a454f619", "field 1 for feature 2 is correct" );
+ t.eq( response.features.feature[1].attributes['LABEL'], "LIBRARY2", "field 2 for feature 2 is correct" );
+ t.eq( response.features.feature[1].attributes['Y_COORD'], "39.75", "field 3 for feature 2 is correct" );
+ t.eq( response.features.feature[1].attributes['X_COORD'], "-104.42", "field 4 for feature 2 is correct" );
+ t.eq( response.features.feature[1].attributes['#SHAPE#'], "[Geometry]", "field 5 for feature 2 is correct" );
+ t.eq( response.features.feature[1].attributes['OBJECTID'], "2", "field 6 for feature 2 is correct" );
+ }
+
+ //
+ // cause an error by parsing bad axl
+ //
+ function test_Format_ArcXML_parseerror(t) {
+ t.plan(1);
+ var f = new OpenLayers.Format.ArcXML();
+
+ try {
+ f.read( '<?xml version="1.0" encoding="Cp1252"?><ARCXML version="1.1"><NO END TAG>' );
+ t.fail("parsing failed to fail")
+ } catch (ex) {
+ t.ok( true, "Exception message indicates parsing error." );
+ }
+ }
+
+ //
+ // create an arcxml image request, and verify that it matches a known image request
+ //
+ function test_format_ArcXML_write1(t) {
+ var options = {
+ requesttype:'image',
+ envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),
+ layers: [],
+ tileSize: new OpenLayers.Size( 256,256 ),
+ featureCoordSys: '4326',
+ filterCoordSys: '4326'
+ };
+ var truth = '<ARCXML version="1.1"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id="4326"/><FILTERCOORDSYS id="4326"/><ENVELOPE minx="-180" miny="-90" maxx="180" maxy="90"/><IMAGESIZE height="256" width="256"/></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';
+ axl_write(t,options,truth);
+ }
+
+ //
+ // create an arcxml image request that specifies layer visibilities, and
+ // verify that it matches a known image request
+ //
+ function test_format_ArcXML_write2(t) {
+ var options = {
+ requesttype:'image',
+ envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),
+ layers: [{
+ id: "0",
+ visible: "true"
+ }],
+ tileSize: new OpenLayers.Size( 256,256 ),
+ featureCoordSys: '4326',
+ filterCoordSys: '4326'
+ };
+ var truth = '<ARCXML version="1.1"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id="4326"/><FILTERCOORDSYS id="4326"/><ENVELOPE minx="-180" miny="-90" maxx="180" maxy="90"/><IMAGESIZE height="256" width="256"/><LAYERLIST><LAYERDEF id="0" visible="true"/></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';
+ axl_write(t, options, truth );
+ }
+
+ //
+ // create an arcxml image request that performs a query for thematic mapping,
+ // and verify that it matches a known image request
+ //
+ function test_format_ArcXML_write3(t) {
+ var options = {
+ requesttype:'image',
+ envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),
+ layers: [{
+ id: "0",
+ visible: "true",
+ query: {
+ where: "COMPANY='AVENCIA'"
+ }
+ }],
+ tileSize: new OpenLayers.Size( 256,256 ),
+ featureCoordSys: '4326',
+ filterCoordSys: '4326'
+ };
+ var truth = '<ARCXML version="1.1"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id="4326"/><FILTERCOORDSYS id="4326"/><ENVELOPE minx="-180" miny="-90" maxx="180" maxy="90"/><IMAGESIZE height="256" width="256"/><LAYERLIST><LAYERDEF id="0" visible="true"><QUERY where="COMPANY=\'AVENCIA\'"/></LAYERDEF></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';
+ axl_write(t, options, truth );
+ }
+
+ //
+ // create an arcxml image request that performs a spatial query for thematic mapping,
+ // and verify that it matches a known image request
+ //
+ function test_format_ArcXML_write4(t) {
+ var options = {
+ requesttype:'image',
+ envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),
+ layers: [{
+ id: "0",
+ visible: "true",
+ query: {
+ spatialfilter: true,
+ where: "COMPANY='AVENCIA'"
+ }
+ }],
+ tileSize: new OpenLayers.Size( 256,256 ),
+ featureCoordSys: '4326',
+ filterCoordSys: '4326'
+ };
+ var truth = '<ARCXML version="1.1"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id="4326"/><FILTERCOORDSYS id="4326"/><ENVELOPE minx="-180" miny="-90" maxx="180" maxy="90"/><IMAGESIZE height="256" width="256"/><LAYERLIST><LAYERDEF id="0" visible="true"><SPATIALQUERY where="COMPANY=\'AVENCIA\'"/></LAYERDEF></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';
+ axl_write(t, options, truth );
+ }
+
+ //
+ // create an arcxml image request that performs a thematic map request, and
+ // verify that it matches a known image request.
+ //
+ function test_format_ArcXML_write5(t) {
+ var options = {
+ requesttype:'image',
+ envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),
+ layers: [{
+ id: "0",
+ visible: "true",
+ query: {
+ spatialfilter: true,
+ where: "COMPANY='AVENCIA'"
+ },
+ renderer: {
+ type: 'valuemap',
+ lookupfield: 'lookup',
+ ranges: [{
+ lower: 0,
+ upper: 10,
+ symbol: {
+ type: 'simplepolygon',
+ fillcolor: '0,0,0'
+ }
+ },{
+ lower: 10,
+ upper: 20,
+ symbol: {
+ type: 'simplepolygon',
+ fillcolor: '255,255,255'
+ }
+ }]
+ }
+ }],
+ tileSize: new OpenLayers.Size( 256,256 ),
+ featureCoordSys: '4326',
+ filterCoordSys: '4326'
+ };
+ var truth = '<ARCXML version="1.1"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id="4326"/><FILTERCOORDSYS id="4326"/><ENVELOPE minx="-180" miny="-90" maxx="180" maxy="90"/><IMAGESIZE height="256" width="256"/><LAYERLIST><LAYERDEF id="0" visible="true"><SPATIALQUERY where="COMPANY=\'AVENCIA\'"/><VALUEMAPRENDERER lookupfield="lookup"><RANGE lower="0" upper="10"><SIMPLEPOLYGONSYMBOL fillcolor="0,0,0"/></RANGE><RANGE lower="10" upper="20"><SIMPLEPOLYGONSYMBOL fillcolor="255,255,255"/></RANGE></VALUEMAPRENDERER></LAYERDEF></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';
+ axl_write(t, options, truth );
+ }
+
+ //
+ // helper function to write some axl, and compare it against a truth axl string
+ //
+ function axl_write(t, options, truth) {
+ t.plan(1);
+
+ var f = new OpenLayers.Format.ArcXML( options );
+ var arcxml = f.write();
+ t.eq( arcxml, truth, "ArcXML request is correct.");
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/ArcXML/Features.html b/misc/openlayers/tests/Format/ArcXML/Features.html
new file mode 100644
index 0000000..bd2f680
--- /dev/null
+++ b/misc/openlayers/tests/Format/ArcXML/Features.html
@@ -0,0 +1,69 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var axl_feature_response = '<?xml version="1.0" encoding="Cp1252"?><ARCXML version="1.1"><RESPONSE><FEATURES><FEATURE><FIELDS><FIELD name="UNIQUE_ID" value="514504b5-0458-461d-b540-8e18a454f619" /><FIELD name="LABEL" value="LIBRARY" /><FIELD name="Y_COORD" value="39.57" /><FIELD name="X_COORD" value="-104.24" /><FIELD name="#SHAPE#" value="[Geometry]" /><FIELD name="OBJECTID" value="1" /><FIELD name="shape.area" value="0" /><FIELD name="shape.len" value="0" /></FIELDS></FEATURE><FEATURE><FIELDS><FIELD name="UNIQUE_ID" value="514504b5-0458-461d-b540-8e81a454f619" /><FIELD name="LABEL" value="LIBRARY2" /><FIELD name="Y_COORD" value="39.75" /><FIELD name="X_COORD" value="-104.42" /><FIELD name="#SHAPE#" value="[Geometry]" /><FIELD name="OBJECTID" value="2" /><FIELD name="shape.area" value="0" /><FIELD name="shape.len" value="0" /></FIELDS></FEATURE><FEATURECOUNT count="2" hasmore="false" /><ENVELOPE minx="-678853.220047791" miny="1810.22081371862" maxx="-678853.220047791" maxy="1810.22081371862"/></FEATURES></RESPONSE></ARCXML>';
+
+ //
+ // creating a new arcxml features format creates an object that has a read and write function
+ //
+ function test_initialize(t) {
+ t.plan(3);
+
+ var format = new OpenLayers.Format.ArcXML.Features();
+ t.ok(format instanceof OpenLayers.Format.ArcXML.Features,
+ "new OpenLayers.Format.ArcXML.Features returns object" );
+
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ //
+ // read in a known good axl feature response
+ //
+ function test_read1(t) {
+ t.plan(8);
+ var f = new OpenLayers.Format.ArcXML.Features();
+ var features = f.read(axl_feature_response);
+
+ t.ok(features !== null, "features are not null" );
+ t.eq(features.length, 2, "feature count is 2" );
+
+ // test the second feature parsed
+ // <FIELD name="UNIQUE_ID" value="514504b5-0458-461d-b540-8e81a454f619" />
+ // <FIELD name="LABEL" value="LIBRARY2" />
+ // <FIELD name="Y_COORD" value="39.75" />
+ // <FIELD name="X_COORD" value="-104.42" />
+ // <FIELD name="#SHAPE#" value="[Geometry]" />
+ // <FIELD name="OBJECTID" value="2" />
+ // <FIELD name="shape.area" value="0" />
+ // <FIELD name="shape.len" value="0" />
+ t.eq( features[1].attributes['UNIQUE_ID'], "514504b5-0458-461d-b540-8e81a454f619", "field 1 for feature 2 is correct" );
+ t.eq( features[1].attributes['LABEL'], "LIBRARY2", "field 2 for feature 2 is correct" );
+ t.eq( features[1].attributes['Y_COORD'], "39.75", "field 3 for feature 2 is correct" );
+ t.eq( features[1].attributes['X_COORD'], "-104.42", "field 4 for feature 2 is correct" );
+ t.eq( features[1].attributes['#SHAPE#'], "[Geometry]", "field 5 for feature 2 is correct" );
+ t.eq( features[1].attributes['OBJECTID'], "2", "field 6 for feature 2 is correct" );
+ }
+
+ //
+ // cause an error by parsing bad axl
+ //
+ function test_parseerror(t) {
+ t.plan(1);
+ var f = new OpenLayers.Format.ArcXML.Features();
+
+ try {
+ f.read( '<?xml version="1.0" encoding="Cp1252"?><ARCXML version="1.1"><NO END TAG>' );
+ t.fail("reading didn't fail");
+ } catch (ex) {
+ t.eq( ex.message, "Error parsing the ArcXML request", "Exception message indicates parsing error." );
+ }
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/Atom.html b/misc/openlayers/tests/Format/Atom.html
new file mode 100644
index 0000000..71bccc5
--- /dev/null
+++ b/misc/openlayers/tests/Format/Atom.html
@@ -0,0 +1,450 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_constructor(t) {
+ t.plan(4);
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.Atom(options);
+ t.ok(format instanceof OpenLayers.Format.Atom,
+ "new OpenLayers.Format.GeoRSS returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ /* Reading tests */
+
+ function test_reproject_null(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.Atom({'internalProjection':new OpenLayers.Projection("EPSG:4326"), 'externalProjection': new OpenLayers.Projection("EPSG:4326")});
+ var data = parser.read(
+ // begin document
+ '<feed xmlns="http://www.w3.org/2005/Atom">' +
+ '<entry></entry>' +
+ '</feed>'
+ // end document
+ );
+ t.eq(
+ data.length, 1,
+ "Parsing items with null geometry and reprojection doesn't fail"
+ );
+ }
+
+ // read entry 1: basic entry, no categories or persons
+ function test_readentry1(t) {
+ t.plan(10);
+ var parser = new OpenLayers.Format.Atom();
+ var data = parser.read(
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ ' <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ ' <link href="http://example.com/blog/1" rel="alternate"/>' +
+ ' <summary>An Atom testing entry</summary>' +
+ ' <title>Atom test</title>' +
+ ' <updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>'
+ // end document
+ );
+ t.ok(data instanceof Array, "Read features");
+ var fx = data[0];
+ t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature");
+ t.eq(fx.geometry, null, "Geometry is null");
+ t.eq(
+ fx.fid,
+ "urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed",
+ "Read fid"
+ );
+ var attrib = fx.attributes;
+ t.eq(attrib.title, "Atom test", "Correct title attribute");
+ t.eq(
+ attrib.description,
+ "An Atom testing entry",
+ "Correct description attribute"
+ );
+ var atomAttrib = attrib.atom;
+ t.eq(
+ atomAttrib.links,
+ [{href: "http://example.com/blog/1", rel: "alternate"}],
+ "Correct links in atom namespace"
+ );
+ t.eq(
+ atomAttrib.summary,
+ "An Atom testing entry",
+ "Correct summary in atom namespace"
+ );
+ t.eq(
+ atomAttrib.title,
+ "Atom test",
+ "Correct title in atom namespace"
+ );
+ t.eq(
+ atomAttrib.updated,
+ "2009-06-02T10:00:00Z",
+ "Correct timestamp in atom namespace"
+ );
+ }
+
+ // read entry 2: with georss:where
+ function test_readentry2(t) {
+ t.plan(5);
+ var parser = new OpenLayers.Format.Atom();
+ var data = parser.read(
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ ' <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ ' <georss:where xmlns:georss="http://www.georss.org/georss">' +
+ ' <gml:Point xmlns:gml="http://www.opengis.net/gml">' +
+ ' <gml:pos>45.68 -111.04</gml:pos>' +
+ ' </gml:Point>' +
+ ' </georss:where>' +
+ '</entry>'
+ // end document
+ );
+ t.ok(data instanceof Array, "Read features");
+ var fx = data[0];
+ t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature");
+ t.ok(fx.geometry instanceof OpenLayers.Geometry.Point, "Read geometry");
+ t.eq(fx.geometry.x, -111.04, "Read x");
+ t.eq(fx.geometry.y, 45.68, "Read y");
+ }
+
+ // read entry 3: with georss:point
+ function test_readentry3(t) {
+ t.plan(5);
+ var parser = new OpenLayers.Format.Atom();
+ var data = parser.read(
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ ' <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ ' <georss:point xmlns:georss="http://www.georss.org/georss">45.68 -111.04</georss:point>' +
+ '</entry>'
+ // end document
+ );
+ t.ok(data instanceof Array, "Read features");
+ var fx = data[0];
+ t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature");
+ t.ok(fx.geometry instanceof OpenLayers.Geometry.Point, "Read geometry");
+ t.eq(fx.geometry.x, -111.04, "Read x");
+ t.eq(fx.geometry.y, 45.68, "Read y");
+ }
+
+ // read entry 4: basic entry, text content
+ function test_readentry4(t) {
+ t.plan(3);
+ var parser = new OpenLayers.Format.Atom();
+ var data = parser.read(
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ ' <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ ' <link href="http://example.com/blog/1" rel="alternate"/>' +
+ ' <summary>An Atom testing entry</summary>' +
+ ' <title>Atom test</title>' +
+ ' <updated>2009-06-02T10:00:00Z</updated>' +
+ ' <content type="text">Blah, blah, blah</content>' +
+ '</entry>'
+ // end document
+ );
+ t.ok(data instanceof Array, "Read features");
+ var fx = data[0];
+ var attrib = fx.attributes;
+ var atomAttrib = attrib.atom;
+ t.eq(
+ atomAttrib.content.type,
+ "text",
+ "Correct content.type in atom namespace"
+ );
+ t.eq(
+ atomAttrib.content.value,
+ "Blah, blah, blah",
+ "Correct content.value in atom namespace"
+ );
+ }
+
+ // read entry 5: basic entry, KML content
+ function test_readentry5(t) {
+ t.plan(3);
+ var parser = new OpenLayers.Format.Atom();
+ var data = parser.read(
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ ' <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ ' <link href="http://example.com/blog/1" rel="alternate"/>' +
+ ' <summary>An Atom testing entry</summary>' +
+ ' <title>Atom test</title>' +
+ ' <updated>2009-06-02T10:00:00Z</updated>' +
+ ' <content type="application/vnd.google-earth.kml+xml"><kml xmlns="http://earth.google.com/kml/2.0"><Folder><name>A folder</name><description>It\'s a folder</description></Folder></kml></content>' +
+ '</entry>'
+ // end document
+ );
+ t.ok(data instanceof Array, "Read features");
+ var fx = data[0];
+ var attrib = fx.attributes;
+ var atomAttrib = attrib.atom;
+ t.eq(
+ atomAttrib.content.type,
+ "application/vnd.google-earth.kml+xml",
+ "Correct content.type in atom namespace"
+ );
+ var node = atomAttrib.content.value;
+ var name = node.localName || node.nodeName.split(":").pop();
+ t.eq(
+ name,
+ "kml",
+ "Correct content.value in atom namespace"
+ );
+ }
+
+ // read feed 1
+ function test_readfeed1(t) {
+ t.plan(2);
+ var parser = new OpenLayers.Format.Atom();
+ var data = parser.read(
+ // begin document
+ '<feed xmlns="http://www.w3.org/2005/Atom">' +
+ ' <entry>' +
+ ' <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ ' </entry>' +
+ '</feed>'
+ // end document
+ );
+ t.ok(data instanceof Array, "Read features");
+ var fx = data[0];
+ t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature");
+ }
+
+ /* Writing tests */
+
+ // write entry 1: null geometry, no attributes
+ function test_writeentry1(t) {
+ t.plan(1);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<id>1</id>' +
+ '<title>untitled</title>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with id, no attributes'
+ );
+ }
+
+ // write entry 2: null geometry, well-known attributes
+ function test_writeentry2(t) {
+ t.plan(1);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature"});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<id>1</id>' +
+ '<summary>A testing feature</summary>' +
+ '<title>Test</title>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with id, well-known attributes'
+ );
+ }
+
+ // write entry 3: null geometry, Atom constructs to override
+ // well-known attributes
+ function test_writeentry3(t) {
+ t.plan(1);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z"}});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<id>1</id>' +
+ '<summary>An Atom testing feature</summary>' +
+ '<title>Atom test</title>' +
+ '<updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with Atom constructs overriding well-known atts'
+ );
+ }
+
+ // write entry 4: Atom categories
+ function test_writeentry4(t) {
+ t.plan(1);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z", categories: [{term: "blog", scheme: "http://example.com/terms", label: "A blog post"}]}});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<category term="blog" scheme="http://example.com/terms" label="A blog post"/>' +
+ '<id>1</id>' +
+ '<summary>An Atom testing feature</summary>' +
+ '<title>Atom test</title>' +
+ '<updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with Atom constructs and categories'
+ );
+ }
+
+ // write entry 5: Atom authors, contributors
+ function test_writeentry5(t) {
+ t.plan(1);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z", authors: [{name: "John Doe", uri: "http://example.com/people/jdoe", email: "jdoe@example.com"}], contributors: [{name: "Pikov Andropov", uri: "http://example.com/people/pandropov", email: "pandropov@example.com"}]}});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<author>' +
+ ' <name>John Doe</name>' +
+ ' <uri>http://example.com/people/jdoe</uri>' +
+ ' <email>jdoe@example.com</email>' +
+ '</author>' +
+ '<contributor>' +
+ ' <name>Pikov Andropov</name>' +
+ ' <uri>http://example.com/people/pandropov</uri>' +
+ ' <email>pandropov@example.com</email>' +
+ '</contributor>' +
+ '<id>1</id>' +
+ '<summary>An Atom testing feature</summary>' +
+ '<title>Atom test</title>' +
+ '<updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with Atom constructs and persons'
+ );
+ }
+
+ // write entry 6: Atom links
+ function test_writeentry6(t) {
+ t.plan(1);
+
+ // Feature attributes in Atom namespace
+ var atomAttrib = {
+ title: "Atom test",
+ summary: "An Atom testing feature",
+ updated: "2009-06-02T10:00:00Z",
+ links: [
+ { href: "http://example.com/blog/1", rel: "alternate" }
+ ]
+ };
+ var fx = new OpenLayers.Feature.Vector(null, {atom: atomAttrib});
+ fx.fid = 'urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed';
+
+ var writer = new OpenLayers.Format.Atom();
+ var data = writer.write(fx);
+
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ '<link href="http://example.com/blog/1" rel="alternate"/>' +
+ '<summary>An Atom testing feature</summary>' +
+ '<title>Atom test</title>' +
+ '<updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with Atom constructs and links'
+ );
+ }
+
+ // write out point -- just enough to see that we're getting the
+ // georss:where element with a Point. We'll trust GML.v3 to get the
+ // details right.
+ function test_writepoint(t) {
+ t.plan(1);
+
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var fx = new OpenLayers.Feature.Vector(point, {});
+ fx.fid = 'urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed';
+
+ var writer = new OpenLayers.Format.Atom();
+ var data = writer.write(fx);
+
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>' +
+ '<title>untitled</title>' +
+ '<georss:where xmlns:georss="http://www.georss.org/georss">' +
+ ' <gml:Point xmlns:gml="http://www.opengis.net/gml">' +
+ ' <gml:pos>45.68 -111.04</gml:pos>' +
+ ' </gml:Point>' +
+ '</georss:where>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with a point location'
+ );
+ }
+
+ // write entry 7: text type content
+ function test_writeentry7(t) {
+ t.plan(1);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z", content: {type: "text", value: "Blah, blah, blah"}}});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<content type="text">Blah, blah, blah</content>' +
+ '<id>1</id>' +
+ '<summary>An Atom testing feature</summary>' +
+ '<title>Atom test</title>' +
+ '<updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with Atom constructs overriding well-known atts'
+ );
+ }
+
+ // write entry 8: +xml type content
+ function test_writeentry8(t) {
+ t.plan(1);
+ var kml = new OpenLayers.Format.KML();
+ kml.foldersName = "A folder";
+ kml.foldersDesc = "It's a folder";
+ var kmlDoc = kml.createElementNS(kml.kmlns, "kml");
+ var kmlFolder = kml.createFolderXML();
+ kmlDoc.appendChild(kmlFolder);
+ var writer = new OpenLayers.Format.Atom();
+ var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z", content: {type: "application/vnd.google-earth.kml+xml", value: kmlDoc}}});
+ feature.fid = '1';
+ var data = writer.write(feature);
+ t.xml_eq(
+ data,
+ // begin document
+ '<entry xmlns="http://www.w3.org/2005/Atom">' +
+ '<content type="application/vnd.google-earth.kml+xml"><kml xmlns="http://earth.google.com/kml/2.0"><Folder><name>A folder</name><description>It\'s a folder</description></Folder></kml></content>' +
+ '<id>1</id>' +
+ '<summary>An Atom testing feature</summary>' +
+ '<title>Atom test</title>' +
+ '<updated>2009-06-02T10:00:00Z</updated>' +
+ '</entry>',
+ // end document
+ 'Writes an entry doc with Atom constructs overriding well-known atts'
+ );
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/CQL.html b/misc/openlayers/tests/Format/CQL.html
new file mode 100644
index 0000000..7b31eab
--- /dev/null
+++ b/misc/openlayers/tests/Format/CQL.html
@@ -0,0 +1,364 @@
+<html>
+ <head>
+ <script src="../OLLoader.js"></script>
+
+ <script type="text/javascript">
+
+function test_CQL_Constructor(t) {
+ t.plan(5);
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.CQL(options);
+ t.ok(format instanceof OpenLayers.Format.CQL,
+ "new OpenLayers.Format.CQL object");
+ t.eq(format.foo, "bar", "constructor sets options correctly")
+ t.eq(typeof format.read, 'function', 'format has a read function');
+ t.eq(typeof format.write, 'function', 'format has a write function');
+ t.eq(format.options, options, "format.options correctly set");
+}
+
+function test_Comparison_string(t) {
+ t.plan(5);
+ var test_cql, format, filter;
+ test_cql = "X >= 'B'";
+ format = new OpenLayers.Format.CQL();
+ filter = format.read(test_cql);
+ t.ok(filter instanceof OpenLayers.Filter.Comparison,
+ "Parsing a simple >= filter produces a Filter.Comparison");
+ t.eq(filter.type, OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
+ ">= parsed as Filter.Comparison.GREATER_THAN_OR_EQUAL_TO");
+ t.eq(filter.property, 'X',
+ "Property extracted from CQL text");
+ t.eq(filter.value, 'B',
+ "Value extracted from CQL text");
+
+
+ t.eq(format.write(filter), test_cql, "write returned test cql");
+}
+
+function test_read_whitespace(t) {
+ t.plan(4);
+ var cql = "TYPEDESC = 'BOE Numbered Plans'";
+ var format = new OpenLayers.Format.CQL();
+ var filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Comparison, "filter parsed correctly with whitespace in string");
+ t.eq(filter.property, 'TYPEDESC', "filter property parsed correctly");
+ t.eq(filter.value, 'BOE Numbered Plans', "value parsed correctly");
+ t.eq(filter.type, '==', 'filter type parsed correctly');
+}
+
+function test_read_escaped_quotes(t) {
+ t.plan(14);
+ var cql = "PROP = 'don''t worry' or PROP = 'value''s value' or PROP = 'foo'";
+ var format = new OpenLayers.Format.CQL();
+
+ var filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Logical, "filter type");
+ t.eq(filter.filters.length, 2, "filter children");
+
+ var f0 = filter.filters[0];
+ t.ok(f0 instanceof OpenLayers.Filter.Logical, "f0 type");
+ t.eq(f0.filters.length, 2, "f0 children");
+
+ var f00 = f0.filters[0];
+ t.eq(f00.property, "PROP", "f000 property");
+ t.eq(f00.type, "==", "f000 type");
+ t.eq(f00.value, "don't worry", "f000 value");
+
+ var f01 = f0.filters[1];
+ t.eq(f01.property, "PROP", "f001 property");
+ t.eq(f01.type, "==", "f001 type");
+ t.eq(f01.value, "value's value", "f001 value");
+
+ var f1 = filter.filters[1];
+ t.ok(f1 instanceof OpenLayers.Filter.Comparison, "f1 type");
+ t.eq(f1.property, "PROP", "f1 property");
+ t.eq(f1.type, "==", "f1 type");
+ t.eq(f1.value, "foo", "f1 value");
+}
+
+function test_write_escaped_quotes(t) {
+ t.plan(1);
+ var filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.OR,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "PROP",
+ value: "quot'd string"
+ }),
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "PROP",
+ value: "don't quote's"
+ })
+ ]
+ });
+ var format = new OpenLayers.Format.CQL();
+ var cql = format.write(filter);
+ t.eq(cql, "(PROP = 'quot''d string') OR (PROP = 'don''t quote''s')", "escaped");
+}
+
+function test_Comparison_number(t) {
+ t.plan(5);
+ var test_cql, format, filter;
+ test_cql = "X >= 10";
+ format = new OpenLayers.Format.CQL();
+ filter = format.read(test_cql);
+ t.ok(filter instanceof OpenLayers.Filter.Comparison,
+ "Parsing a simple >= filter produces a Filter.Comparison");
+ t.eq(filter.type, OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
+ ">= parsed as Filter.Comparison.GREATER_THAN_OR_EQUAL_TO");
+ t.eq(filter.property, 'X',
+ "Property extracted from CQL text");
+ t.eq(filter.value, 10,
+ "Value extracted from CQL text");
+
+
+ t.eq(format.write(filter), test_cql, "write returned test cql");
+}
+
+function test_Logical(t) {
+ t.plan(7);
+ var test_cql, format, filter;
+ test_cql = "X >= 'B' AND X < 'M'";
+ format = new OpenLayers.Format.CQL();
+ filter = format.read(test_cql);
+ t.ok(filter instanceof OpenLayers.Filter.Logical,
+ "Parsing ANDed filters produces a Filter.Logical");
+ t.eq(filter.type, OpenLayers.Filter.Logical.AND,
+ "AND parsed as Filter.Logical.AND");
+ t.eq(filter.filters.length, 2,
+ "AND Filter contains two subfilters");
+ t.ok(filter.filters[0] instanceof OpenLayers.Filter.Comparison,
+ "First sub-filter is a Filter.Comparison");
+ t.eq(filter.filters[0].type, OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
+ "First sub-filter is the first filter in the CQL text");
+ t.ok(filter.filters[1] instanceof OpenLayers.Filter.Comparison,
+ "Second sub-filter is a Filter.Comparison");
+ t.eq(filter.filters[1].type, OpenLayers.Filter.Comparison.LESS_THAN,
+ "Second sub-filter is the second filter in the CQL text");
+
+}
+
+function test_Logical_write(t) {
+ t.plan(1);
+ var cql = "(X >= 'B') AND (X < 'M')";
+ var format = new OpenLayers.Format.CQL();
+ var filter = format.read(cql);
+ t.eq(format.write(filter), cql, "write returned test cql");
+}
+
+function test_Logical_spatial(t) {
+ t.plan(9);
+ var test_cql, format, filter;
+ test_cql = "INTERSECTS(the_geom, POLYGON((-111 41,-115 41,-115 45,-110 45,-111 41))) AND CONTAINS(the_geom, POINT(-111 41))";
+ format = new OpenLayers.Format.CQL();
+ filter = format.read(test_cql);
+ t.ok(filter instanceof OpenLayers.Filter.Logical,
+ "Parsing ANDed filters produces a Filter.Logical");
+ t.eq(filter.type, OpenLayers.Filter.Logical.AND,
+ "AND parsed as Filter.Logical.AND");
+ t.eq(filter.filters.length, 2,
+ "AND Filter contains two subfilters");
+ t.ok(filter.filters[0] instanceof OpenLayers.Filter.Spatial,
+ "First sub-filter is a Filter.Spatial");
+ t.eq(filter.filters[0].type, OpenLayers.Filter.Spatial.INTERSECTS,
+ "First sub-filter is the first filter in the CQL text");
+ t.geom_eq(filter.filters[0].value, OpenLayers.Geometry.fromWKT("POLYGON((-111 41,-115 41,-115 45,-110 45,-111 41))"),
+ "First sub-filter is has correct geometry");
+ t.ok(filter.filters[1] instanceof OpenLayers.Filter.Spatial,
+ "Second sub-filter is a Filter.Comparison");
+ t.eq(filter.filters[1].type, OpenLayers.Filter.Spatial.CONTAINS,
+ "Second sub-filter is the second filter in the CQL text");
+ t.geom_eq(filter.filters[1].value, OpenLayers.Geometry.fromWKT("POINT(-111 41)"),
+ "Second sub-filter is has correct geometry");
+}
+
+function test_Logical_spatial_write(t) {
+ // TODO: remove this if extra parentheses are avoided by checking logical operator precedence
+ t.plan(1);
+ var cql = "(INTERSECTS(the_geom, POLYGON((-111 41,-115 41,-115 45,-110 45,-111 41)))) AND (CONTAINS(the_geom, POINT(-111 41)))";
+ var format = new OpenLayers.Format.CQL();
+ var filter = format.read(cql);
+ t.eq(format.write(filter), cql, "write returned test cql");
+}
+
+function test_Parentheticals(t) {
+ t.plan(2);
+ var format, cqlA, filterA, cqlB, filterB;
+ format = new OpenLayers.Format.CQL();
+ cqlA = "A = '1' AND B = '2' OR C = '3'";
+ cqlB = "A = '1' AND (B = '2' OR C = '3')";
+ filterA = format.read(cqlA);
+ filterB = format.read(cqlB);
+
+ t.ok(filterA instanceof OpenLayers.Filter.Logical &&
+ filterA.filters[0] instanceof OpenLayers.Filter.Logical &&
+ filterA.filters[1] instanceof OpenLayers.Filter.Comparison,
+ "Unparenthesized expression groups left to right");
+ t.ok(filterB instanceof OpenLayers.Filter.Logical &&
+ filterB.filters[0] instanceof OpenLayers.Filter.Comparison &&
+ filterB.filters[1] instanceof OpenLayers.Filter.Logical,
+ "Parenthesized expression groups as specified by parentheses");
+}
+
+function test_Parentheticals_write(t) {
+ // TODO: remove this if extra parentheses are avoided by checking logical operator precedence
+ t.plan(1);
+ var format = new OpenLayers.Format.CQL();
+ var cql = "(A = '1') AND ((B = '2') OR (C = '3'))";
+ var filter = format.read(cql);
+ t.eq(format.write(filter), cql, "write returned test cql");
+}
+
+function test_BBOX(t) {
+ t.plan(5);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "BBOX(the_geom,1,2,3,4)",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Spatial,
+ "Parsing BBOX expression produces Filter.Spatial");
+ t.eq(filter.type, OpenLayers.Filter.Spatial.BBOX,
+ "Spatial filter is a bbox filter");
+ t.eq(filter.property, "the_geom",
+ "Property name is as specified in CQL");
+ t.eq(filter.value.toBBOX(), "1,2,3,4",
+ "Value is as specified in CQL");
+
+ t.eq(format.write(filter), cql, "write returned test cql");
+
+}
+
+function test_INTERSECTS(t) {
+ t.plan(5);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "INTERSECTS(the_geom, POINT(1 2))",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Spatial,
+ "Parsing BBOX expression produces Filter.Spatial");
+ t.eq(filter.type, OpenLayers.Filter.Spatial.INTERSECTS,
+ "Spatial filter is an intersects filter");
+ t.eq(filter.property, "the_geom",
+ "Property name is as specified in CQL");
+ t.ok(filter.value instanceof OpenLayers.Geometry,
+ "Value is a geometry");
+
+ t.eq(format.write(filter), cql, "write returned test cql");
+
+}
+
+function test_WITHIN(t) {
+ t.plan(5);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "WITHIN(the_geom, POLYGON((1 2,3 4,5 6,3 8,1 6,1 2)))",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Spatial,
+ "Parsing BBOX expression produces Filter.Spatial");
+ t.eq(filter.type, OpenLayers.Filter.Spatial.WITHIN,
+ "Spatial filter is a within filter");
+ t.eq(filter.property, "the_geom",
+ "Property name is as specified in CQL");
+ t.ok(filter.value instanceof OpenLayers.Geometry,
+ "Value is a geometry");
+
+ t.eq(format.write(filter), cql, "write returned test cql");
+
+}
+
+function test_DWITHIN(t) {
+ t.plan(6);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "DWITHIN(the_geom, POINT(1 2), 6)",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Spatial,
+ "Parsing DWITHIN expression produces Filter.Spatial");
+ t.eq(filter.type, OpenLayers.Filter.Spatial.DWITHIN,
+ "Spatial filter is a DWITHIN filter");
+ t.eq(filter.property, "the_geom",
+ "Property name is as specified in CQL");
+ t.ok(filter.value instanceof OpenLayers.Geometry,
+ "Value is a geometry");
+ t.eq(filter.distance, 6,
+ "Distance is as specified in CQL");
+
+ t.eq(format.write(filter), cql, "write returned test cql");
+
+}
+
+function test_CONTAINS(t) {
+ t.plan(5);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "CONTAINS(the_geom, POINT(1 2))",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Spatial,
+ "Parsing BBOX expression produces Filter.Spatial");
+ t.eq(filter.type, OpenLayers.Filter.Spatial.CONTAINS,
+ "Spatial filter is a within filter");
+ t.eq(filter.property, "the_geom",
+ "Property name is as specified in CQL");
+ t.ok(filter.value instanceof OpenLayers.Geometry,
+ "Value is a geometry");
+
+ t.eq(format.write(filter), cql, "write returned test cql");
+
+}
+
+function test_NOT(t) {
+ t.plan(4);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "NOT X < 12",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Logical,
+ "Parsing NOT expression produces Logical.Not");
+ t.eq(filter.type, OpenLayers.Filter.Logical.NOT,
+ "Logical filter is a NOT filter");
+ t.eq(filter.filters[0].property, "X",
+ "Property name is as specified in CQL");
+ t.eq(filter.filters[0].value, 12, "Value is as specified in CQL");
+}
+
+function test_NOT_write(t) {
+ // TODO: remove this if extra parentheses are avoided by checking logical operator precedence
+ t.plan(1);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "NOT (X < 12)",
+ filter = format.read(cql);
+ t.eq(format.write(filter), cql, "write returned test cql");
+}
+
+function test_BETWEEN(t) {
+ t.plan(6);
+ var format = new OpenLayers.Format.CQL(),
+ cql = "A BETWEEN 0 AND 5",
+ filter = format.read(cql);
+ t.ok(filter instanceof OpenLayers.Filter.Comparison,
+ "Parsing BETWEEN expression produces Filter.Comparison");
+ t.eq(filter.type, OpenLayers.Filter.Comparison.BETWEEN,
+ "Comparison filter is a between filter");
+ t.eq(filter.property, "A",
+ "Property name is as specified in CQL");
+ t.eq(filter.lowerBoundary, 0, 'Lower boundary is as specified in CQL');
+ t.eq(filter.upperBoundary, 5, 'Upper bondary is as specified in CQL');
+
+ t.eq(format.write(filter), cql, "write returned test cql");
+
+}
+
+function test_NULL(t) {
+ t.plan(3);
+ var filter = new OpenLayers.Filter.Comparison({
+ property: "GEOM",
+ type: "NULL"
+ });
+ var format = new OpenLayers.Format.CQL();
+ var str = 'GEOM IS NULL';
+ t.eq(format.write(filter), str, "NULL filter written correctly");
+ filter = format.read(str);
+ t.eq(filter.type, OpenLayers.Filter.Comparison.IS_NULL, "filter type is correctly parsed");
+ t.eq(filter.property, "GEOM", "filter property is correctly parsed");
+}
+
+ </script>
+ </head>
+ <body></body>
+</html>
diff --git a/misc/openlayers/tests/Format/CSWGetDomain.html b/misc/openlayers/tests/Format/CSWGetDomain.html
new file mode 100644
index 0000000..1e37826
--- /dev/null
+++ b/misc/openlayers/tests/Format/CSWGetDomain.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.CSWGetDomain();
+ t.ok(format instanceof OpenLayers.Format.CSWGetDomain.v2_0_2, "constructor returns instance with default versioned format");
+
+ format = new OpenLayers.Format.CSWGetDomain({
+ version: "2.0.2"
+ });
+ t.ok(format instanceof OpenLayers.Format.CSWGetDomain.v2_0_2, "constructor returns instance with custom versioned format");
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:512px; height:256px"> </div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.html b/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.html
new file mode 100644
index 0000000..ea0be83
--- /dev/null
+++ b/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.html
@@ -0,0 +1,56 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script src="v2_0_2.js"></script>
+ <script type="text/javascript">
+
+ var format = new OpenLayers.Format.CSWGetDomain();
+
+ function test_write(t) {
+
+ t.plan(1);
+
+ var options = {
+ PropertyName: "type"
+ };
+
+ var result = format.write(options);
+
+ t.eq(result, csw_request, "check value returned by format " +
+ "CSWGetDomain: write method");
+
+ }
+
+
+ function test_read(t) {
+
+ t.plan(9);
+
+ var obj = format.read(csw_response);
+
+ var domainValues = obj.DomainValues;
+ // test getRecordsResponse object
+ t.ok(domainValues, "object contains DomainValues property");
+
+ // test DomainValues
+ t.eq(domainValues.length, 1, "object contains 1 object in DomainValues");
+ var domainValue = domainValues[0];
+ t.eq(domainValue.type, "csw:Record", "check value for attribute type");
+ t.eq(domainValue.PropertyName, "type", "check value for element PropertyName");
+ t.ok(domainValue.ListOfValues, "object contains ListOfValues property");
+
+ // test ListOfValues
+ t.eq(domainValue.ListOfValues.length, 2, "object contains 2 objects " +
+ "in ListOfValues");
+ var val = domainValue.ListOfValues[0];
+ t.ok(val.Value, "object contains Value property");
+ t.eq(val.Value.my_attr, "my_value", "check value for attribute my_attr");
+ t.eq(val.Value.value, "dataset", "check value for element Value");
+
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.js b/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.js
new file mode 100644
index 0000000..19e1ad0
--- /dev/null
+++ b/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.js
@@ -0,0 +1,18 @@
+var csw_request =
+'<csw:GetDomain xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" service="CSW" version="2.0.2">' +
+ '<csw:PropertyName>type</csw:PropertyName>' +
+'</csw:GetDomain>';
+
+var csw_response =
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<csw:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">' +
+ '<csw:DomainValues type="csw:Record">' +
+ '<csw:PropertyName>type</csw:PropertyName>' +
+ '<csw:ListOfValues>' +
+ '<csw:Value my_attr="my_value">dataset</csw:Value>' +
+ '<csw:Value>service</csw:Value>' +
+ '</csw:ListOfValues>' +
+ '</csw:DomainValues>' +
+'</csw:GetDomainResponse>'
+;
+
diff --git a/misc/openlayers/tests/Format/CSWGetRecords.html b/misc/openlayers/tests/Format/CSWGetRecords.html
new file mode 100644
index 0000000..2b8bc6b
--- /dev/null
+++ b/misc/openlayers/tests/Format/CSWGetRecords.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.CSWGetRecords();
+ t.ok(format instanceof OpenLayers.Format.CSWGetRecords.v2_0_2, "constructor returns instance with default versioned format");
+
+ format = new OpenLayers.Format.CSWGetRecords({
+ version: "2.0.2"
+ });
+ t.ok(format instanceof OpenLayers.Format.CSWGetRecords.v2_0_2, "constructor returns instance with custom versioned format");
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:512px; height:256px"> </div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.html b/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.html
new file mode 100644
index 0000000..07e1b96
--- /dev/null
+++ b/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.html
@@ -0,0 +1,88 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script src="v2_0_2.js"></script>
+ <script type="text/javascript">
+
+ var format = new OpenLayers.Format.CSWGetRecords();
+
+ function test_write(t) {
+
+ t.plan(1);
+
+ var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "my_prop",
+ value: "my_prop_value"
+ });
+
+ var options = {
+ "resultType": "results",
+ "startPosition": "10",
+ "maxRecords": "20",
+ "Query": {
+ "ElementSetName": {
+ "value": "brief"
+ },
+ "Constraint": {
+ "version": "1.1.0",
+ "Filter": filter
+ }
+ }
+ };
+
+ var result = format.write(options);
+
+ t.eq(result, csw_request, "check value returned by format " +
+ "CSWGetRecords: write method");
+
+ }
+
+
+ function test_read(t) {
+
+ t.plan(17);
+
+ var obj = format.read(csw_response);
+
+ var searchStatus = obj.SearchStatus;
+ var searchResults = obj.SearchResults;
+ var records = obj.records;
+ // test getRecordsResponse object
+ t.ok(searchStatus, "object contains SearchStatus property");
+ t.ok(searchResults, "object contains SearchResults property");
+ t.ok(records, "object contains records property");
+
+ // test SearchResults attributes
+ t.eq(searchResults.numberOfRecordsMatched, 10, "check value for SearchResults.numberOfRecordsMatched");
+ t.eq(searchResults.numberOfRecordsReturned, 2, "check value for SearchResults.numberOfRecordsReturned");
+ t.eq(searchResults.elementSet, "brief", "check value for SearchResults.elementSet");
+ t.eq(searchResults.nextRecord, 3, "check value for SearchResults.nextRecord");
+
+ // test records
+ t.eq(records.length, 2, "object contains 10 records");
+ var testRecord = records[0];
+ t.eq(testRecord.type, "BriefRecord", "check value for record.type");
+ t.eq(testRecord.title, [{value:"Sample title"}], "check value for record.title");
+
+ // test empty subject
+ t.eq(testRecord.subject, [], "Empty subject tags are ignored");
+
+ //test bbox
+ t.eq(testRecord.BoundingBox.length, 2, "object contains 2 BoundingBoxes");
+ var bbox = testRecord.BoundingBox[0];
+ t.ok(bbox, "object contains BoundingBox properties");
+ t.eq(bbox.crs, "::Lambert Azimuthal Projection", "check value for BoundingBox.crs");
+ t.eq(bbox.value, [156, -3, 37, 83], "check value for record.BoundingBox");
+
+ // test gninfo
+ testRecord = records[1];
+ t.ok(testRecord.gninfo, "object contains gninfo properties");
+ t.eq(testRecord.gninfo.schema, "iso19139", "check value for schema property in record.gninfo");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.js b/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.js
new file mode 100644
index 0000000..4763aef
--- /dev/null
+++ b/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.js
@@ -0,0 +1,50 @@
+var csw_request =
+'<csw:GetRecords xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" service="CSW" version="2.0.2" resultType="results" startPosition="10" maxRecords="20" xmlns:gmd="http://www.isotc211.org/2005/gmd">' +
+ '<csw:Query typeNames="csw:Record">' +
+ '<csw:ElementSetName>brief</csw:ElementSetName>' +
+ '<csw:Constraint version="1.1.0">' +
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsLike wildCard="*" singleChar="." escapeChar="!">' +
+ '<ogc:PropertyName>my_prop</ogc:PropertyName>' +
+ '<ogc:Literal>my_prop_value</ogc:Literal>' +
+ '</ogc:PropertyIsLike>' +
+ '</ogc:Filter>' +
+ '</csw:Constraint>' +
+ '</csw:Query>' +
+'</csw:GetRecords>';
+
+var csw_response =
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">' +
+ '<csw:SearchStatus timestamp="2009-06-08T12:03:34" />' +
+ '<csw:SearchResults numberOfRecordsMatched="10" numberOfRecordsReturned="2" elementSet="brief" nextRecord="3">' +
+ '<csw:BriefRecord xmlns:geonet="http://www.fao.org/geonetwork" xmlns:ows="http://www.opengis.net/ows" xmlns:dc="http://purl.org/dc/elements/1.1/">' +
+ '<dc:identifier>895ac38b-7aef-4a21-b593-b35a6fc7bba9</dc:identifier>' +
+ '<dc:title>Sample title</dc:title>' +
+ '<dc:subject />' +
+ '<dc:subject />' +
+ '<ows:BoundingBox crs="::Lambert Azimuthal Projection">' +
+ '<ows:LowerCorner>156 -3</ows:LowerCorner>' +
+ '<ows:UpperCorner>37 83</ows:UpperCorner>' +
+ '</ows:BoundingBox>' +
+ '<ows:BoundingBox crs="::WGS 1984">' +
+ '<ows:LowerCorner>51.1 -34.6</ows:LowerCorner>' +
+ '<ows:UpperCorner>-17.3 38.2</ows:UpperCorner>' +
+ '</ows:BoundingBox>' +
+ '</csw:BriefRecord>' +
+ '<csw:BriefRecord xmlns:geonet="http://www.fao.org/geonetwork" xmlns:ows="http://www.opengis.net/ows" xmlns:dc="http://purl.org/dc/elements/1.1/">' +
+ '<dc:identifier>8a7245c3-8546-42de-8e6f-8fb8b5fd1bc3</dc:identifier>' +
+ '<dc:title>Second record : sample title</dc:title>' +
+ '<ows:BoundingBox crs="::WGS 1984">' +
+ '<ows:LowerCorner>51.1 -34.6</ows:LowerCorner>' +
+ '<ows:UpperCorner>-17.3 38.2</ows:UpperCorner>' +
+ '</ows:BoundingBox>' +
+ '<geonet:info xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gml="http://www.opengis.net/gml">' +
+ '<id>859</id>' +
+ '<schema>iso19139</schema>' +
+ '</geonet:info>' +
+ '</csw:BriefRecord>' +
+ '</csw:SearchResults>' +
+'</csw:GetRecordsResponse>'
+;
+
diff --git a/misc/openlayers/tests/Format/EncodedPolyline.html b/misc/openlayers/tests/Format/EncodedPolyline.html
new file mode 100644
index 0000000..1466347
--- /dev/null
+++ b/misc/openlayers/tests/Format/EncodedPolyline.html
@@ -0,0 +1,372 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var flatPoints;
+ var floats, smallFloats, encodedFloats;
+ var signedIntegers, encodedSignedIntegers;
+ var unsignedIntegers, encodedUnsignedIntegers;
+
+ function resetTestingData() {
+ flatPoints = [38.50000, -120.20000,
+ 40.70000, -120.95000,
+ 43.25200, -126.45300];
+
+ floats = [0.00, 0.15, -0.01, -0.16, 0.16, 0.01];
+ smallFloats = [0.00000, 0.00015, -0.00001, -0.00016, 0.00016, 0.00001];
+ encodedFloats = '?]@^_@A';
+
+ signedIntegers = [0, 15, -1, -16, 16, 1];
+ encodedSignedIntegers = '?]@^_@A';
+
+ unsignedIntegers = [0, 30, 1, 31, 32, 2, 174];
+ encodedUnsignedIntegers = '?]@^_@AmD';
+ }
+
+ var basePoints = new Array(
+ new Array(3850000, -12020000),
+ new Array(4070000, -12095000),
+ new Array(4325200, -12645300)
+ );
+
+ var points = [
+ new OpenLayers.Geometry.Point(-120.200, 38.500),
+ new OpenLayers.Geometry.Point(-120.950, 40.700),
+ new OpenLayers.Geometry.Point(-126.453, 43.252)
+ ];
+
+ var singlePoint = new OpenLayers.Feature.Vector(points[0]);
+
+ var linestring = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.LineString(points)
+ );
+
+ var multipoint = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.MultiPoint(points)
+ );
+
+ var linearring = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.LinearRing(points)
+ );
+
+ var polygon = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing(points)
+ ])
+ );
+
+ var encoded = "_p~iF~ps|U_ulLnnqC_mqNvxq`@";
+
+ function test_Format_EncodedPolyline_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.EncodedPolyline(options);
+ t.ok(format instanceof OpenLayers.Format.EncodedPolyline,
+ "new OpenLayers.Format.EncodedPolyline returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ function test_Format_EncodedPolyline_read(t) {
+ t.plan(5);
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.ok(linestring.geometry.equals(format.read(encoded).geometry),
+ "format correctly reads encoded polyline");
+
+ format = new OpenLayers.Format.EncodedPolyline({
+ geometryType: "multipoint"
+ });
+ t.ok(multipoint.geometry.equals(format.read(encoded).geometry),
+ "format correctly reads encoded multipoint");
+
+ format.geometryType = "linearring";
+ t.ok(linearring.geometry.equals(format.read(encoded).geometry),
+ "format correctly reads encoded linearring");
+
+ format.geometryType = "polygon";
+ t.ok(polygon.geometry.equals(format.read(encoded).geometry),
+ "format correctly reads encoded polygon");
+
+ format.geometryType = "point";
+ t.ok(points[0].equals(format.read(encoded).geometry),
+ "format correctly reads encoded point");
+ }
+
+ function test_Format_EncodedPolyline_decode(t) {
+ t.plan(6);
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ var decodedPoints = format.decode(encoded, 2);
+ for (i in decodedPoints) {
+ var point = basePoints[i];
+ var decodedPoint = decodedPoints[i];
+ t.eq(parseInt(decodedPoint[0] * 1e5), point[0]);
+ t.eq(parseInt(decodedPoint[1] * 1e5), point[1]);
+ }
+ }
+
+ function test_Format_EncodedPolyline_write(t) {
+ t.plan(5);
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.write(linestring), encoded,
+ "format correctly writes encoded polyline");
+
+ t.eq(format.write(multipoint), encoded,
+ "format correctly writes encoded multipoint");
+
+ // Different output than encoded,
+ // because polygon closing point is included
+ t.eq(format.write(linearring),
+ "_p~iF~ps|U_ulLnnqC_mqNvxq`@~b_\\ghde@",
+ "format correctly writes encoded linearring");
+
+ t.eq(format.write(polygon),
+ "_p~iF~ps|U_ulLnnqC_mqNvxq`@~b_\\ghde@",
+ "format correctly writes encoded polygon");
+
+ t.eq(format.write(singlePoint), "_p~iF~ps|U",
+ "format correctly writes encoded point");
+ }
+
+ function test_Format_EncodedPolyline_encode(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encode(basePoints, 2, 1), encoded);
+ }
+
+ function test_encodeDeltas_returns_expected_value(t) {
+ t.plan(1);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeDeltas(flatPoints, 2), encoded);
+ }
+
+ function test_decodeDeltas_returns_expected_value(t) {
+ t.plan(1);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeDeltas(encoded, 2), flatPoints);
+ }
+
+
+
+ function test_encodeFloats_returns_expected_value(t) {
+ t.plan(3);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeFloats(smallFloats), encodedFloats);
+
+ resetTestingData();
+ t.eq(format.encodeFloats(smallFloats, 1e5), encodedFloats);
+
+ t.eq(format.encodeFloats(floats, 1e2), encodedFloats);
+ }
+
+ function test_decodeFloats_returns_expected_value(t) {
+ t.plan(3);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeFloats(encodedFloats), smallFloats);
+ t.eq(format.decodeFloats(encodedFloats, 1e5), smallFloats);
+ t.eq(format.decodeFloats(encodedFloats, 1e2), floats);
+ }
+
+
+
+ function test_encodeSignedIntegers_returns_expected_value(t) {
+ t.plan(1);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeSignedIntegers(
+ signedIntegers), encodedSignedIntegers);
+ }
+
+ function test_decodeSignedIntegers_returns_expected_value(t) {
+ t.plan(1);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeSignedIntegers(
+ encodedSignedIntegers), signedIntegers);
+ }
+
+
+
+ function test_encodeUnsignedIntegers_returns_expected_value(t) {
+ t.plan(1);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeUnsignedIntegers(
+ unsignedIntegers), encodedUnsignedIntegers);
+ }
+
+ function test_decodeUnsignedIntegers_returns_expected_value(t) {
+ t.plan(1);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeUnsignedIntegers(
+ encodedUnsignedIntegers), unsignedIntegers);
+ }
+
+
+
+ function test_encodeFloat_returns_expected_value(t) {
+ t.plan(12);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeFloat(0.00000), '?');
+ t.eq(format.encodeFloat(-0.00001), '@');
+ t.eq(format.encodeFloat(0.00001), 'A');
+ t.eq(format.encodeFloat(-0.00002), 'B');
+ t.eq(format.encodeFloat(0.00002), 'C');
+ t.eq(format.encodeFloat(0.00015), ']');
+ t.eq(format.encodeFloat(-0.00016), '^');
+
+ t.eq(format.encodeFloat(-0.1, 10), '@');
+ t.eq(format.encodeFloat(0.1, 10), 'A');
+
+ t.eq(format.encodeFloat(16 * 32 / 1e5), '__@');
+ t.eq(format.encodeFloat(16 * 32 * 32 / 1e5), '___@');
+
+ // from the "Encoded Polyline Algorithm Format" page at Google
+ t.eq(format.encodeFloat(-179.9832104), '`~oia@');
+ }
+
+ function test_decodeFloat_returns_expected_value(t) {
+ t.plan(12);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeFloat('?'), 0.00000);
+ t.eq(format.decodeFloat('@'), -0.00001);
+ t.eq(format.decodeFloat('A'), 0.00001);
+ t.eq(format.decodeFloat('B'), -0.00002);
+ t.eq(format.decodeFloat('C'), 0.00002);
+ t.eq(format.decodeFloat(']'), 0.00015);
+ t.eq(format.decodeFloat('^'), -0.00016);
+
+ t.eq(format.decodeFloat('@', 10), -0.1);
+ t.eq(format.decodeFloat('A', 10), 0.1);
+
+ t.eq(format.decodeFloat('__@'), 16 * 32 / 1e5);
+ t.eq(format.decodeFloat('___@'), 16 * 32 * 32 / 1e5);
+
+ // from the "Encoded Polyline Algorithm Format" page at Google
+ t.eq(format.decodeFloat('`~oia@'), -179.98321);
+ }
+
+
+
+ function test_encodeSignedInteger_returns_expected_value(t) {
+ t.plan(10);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeSignedInteger(0), '?');
+ t.eq(format.encodeSignedInteger(-1), '@');
+ t.eq(format.encodeSignedInteger(1), 'A');
+ t.eq(format.encodeSignedInteger(-2), 'B');
+ t.eq(format.encodeSignedInteger(2), 'C');
+ t.eq(format.encodeSignedInteger(15), ']');
+ t.eq(format.encodeSignedInteger(-16), '^');
+
+ t.eq(format.encodeSignedInteger(16), '_@');
+ t.eq(format.encodeSignedInteger(16 * 32), '__@');
+ t.eq(format.encodeSignedInteger(16 * 32 * 32), '___@');
+ }
+
+ function test_decodeSignedInteger_returns_expected_value(t) {
+ t.plan(10);
+ resetTestingData();
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeSignedInteger('?'), 0);
+ t.eq(format.decodeSignedInteger('@'), -1);
+ t.eq(format.decodeSignedInteger('A'), 1);
+ t.eq(format.decodeSignedInteger('B'), -2);
+ t.eq(format.decodeSignedInteger('C'), 2);
+ t.eq(format.decodeSignedInteger(']'), 15);
+ t.eq(format.decodeSignedInteger('^'), -16);
+
+ t.eq(format.decodeSignedInteger('__@'), 16 * 32);
+ t.eq(format.decodeSignedInteger('___@'), 16 * 32 * 32);
+ t.eq(format.decodeSignedInteger('_@'), 16);
+ }
+
+
+
+ function test_encodeUnsignedInteger_returns_expected_value(t) {
+ t.plan(10);
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.encodeUnsignedInteger(0), '?');
+ t.eq(format.encodeUnsignedInteger(1), '@');
+ t.eq(format.encodeUnsignedInteger(2), 'A');
+ t.eq(format.encodeUnsignedInteger(30), ']');
+ t.eq(format.encodeUnsignedInteger(31), '^');
+ t.eq(format.encodeUnsignedInteger(32), '_@');
+
+ t.eq(format.encodeUnsignedInteger(32 * 32), '__@');
+ t.eq(format.encodeUnsignedInteger(5 * 32 * 32), '__D');
+ t.eq(format.encodeUnsignedInteger(32 * 32 * 32), '___@');
+
+ // from the "Encoded Polyline Algorithm Format" page at Google
+ t.eq(format.encodeUnsignedInteger(174), 'mD');
+ }
+
+ function test_decodeUnsignedInteger_returns_expected_value(t) {
+ t.plan(10);
+
+ var format = new OpenLayers.Format.EncodedPolyline();
+
+ t.eq(format.decodeUnsignedInteger('?'), 0);
+ t.eq(format.decodeUnsignedInteger('@'), 1);
+ t.eq(format.decodeUnsignedInteger('A'), 2);
+ t.eq(format.decodeUnsignedInteger(']'), 30);
+ t.eq(format.decodeUnsignedInteger('^'), 31);
+ t.eq(format.decodeUnsignedInteger('_@'), 32);
+
+ t.eq(format.decodeUnsignedInteger('__@'), 32 * 32);
+ t.eq(format.decodeUnsignedInteger('__D'), 5 * 32 * 32);
+ t.eq(format.decodeUnsignedInteger('___@'), 32 * 32 * 32);
+
+ // from the "Encoded Polyline Algorithm Format" page at Google
+ t.eq(format.decodeUnsignedInteger('mD'), 174);
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/Filter.html b/misc/openlayers/tests/Format/Filter.html
new file mode 100644
index 0000000..69a0564
--- /dev/null
+++ b/misc/openlayers/tests/Format/Filter.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(3);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.Filter(options);
+ t.ok(format instanceof OpenLayers.Format.Filter,
+ "new OpenLayers.Format.Filter returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/Filter/v1.html b/misc/openlayers/tests/Format/Filter/v1.html
new file mode 100644
index 0000000..a862955
--- /dev/null
+++ b/misc/openlayers/tests/Format/Filter/v1.html
@@ -0,0 +1,404 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_PropertyIsBetween(t) {
+
+ t.plan(6);
+
+ var test_xml, parser, xml;
+
+ parser = new OpenLayers.Format.Filter.v1();
+ xml = new OpenLayers.Format.XML();
+
+ test_xml =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsBetween>' +
+ '<ogc:PropertyName>number</ogc:PropertyName>' +
+ '<ogc:LowerBoundary>' +
+ '<ogc:Literal>0</ogc:Literal>' +
+ '</ogc:LowerBoundary>' +
+ '<ogc:UpperBoundary>' +
+ '<ogc:Literal>100</ogc:Literal>' +
+ '</ogc:UpperBoundary>' +
+ '</ogc:PropertyIsBetween>' +
+ '</ogc:Filter>';
+
+ var filter = parser.read(xml.read(test_xml).documentElement);
+ t.eq(filter.type, OpenLayers.Filter.Comparison.BETWEEN,
+ "[0] read correct type");
+ t.eq(filter.lowerBoundary, 0,
+ "[0] record correct lower boundary value");
+ t.eq(filter.upperBoundary, 100,
+ "[0] record correct upper boundary value");
+
+ test_xml =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsBetween>' +
+ '<ogc:PropertyName>number</ogc:PropertyName>' +
+ '<ogc:LowerBoundary>0</ogc:LowerBoundary>' +
+ '<ogc:UpperBoundary>100</ogc:UpperBoundary>' +
+ '</ogc:PropertyIsBetween>' +
+ '</ogc:Filter>';
+
+ var filter = parser.read(xml.read(test_xml).documentElement);
+ t.eq(filter.type, OpenLayers.Filter.Comparison.BETWEEN,
+ "[1] read correct type");
+ t.eq(filter.lowerBoundary, 0,
+ "[1] record correct lower boundary value");
+ t.eq(filter.upperBoundary, 100,
+ "[1] record correct upper boundary value");
+ }
+
+ function test_PropertyIsNull(t) {
+
+ t.plan(3);
+
+ var format, test_xml, xml, filter, node;
+
+ format = new OpenLayers.Format.Filter.v1();
+
+ test_xml =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsNull>' +
+ '<ogc:PropertyName>prop</ogc:PropertyName>' +
+ '</ogc:PropertyIsNull>' +
+ '</ogc:Filter>';
+
+ // Test reading a PropertyIsNull filter from an XML doc
+ xml = new OpenLayers.Format.XML();
+ filter = format.read(xml.read(test_xml).documentElement);
+ t.eq(filter.type, OpenLayers.Filter.Comparison.IS_NULL,
+ "[0] read correct type");
+ t.eq(filter.property, 'prop',
+ "[0] record correct property name");
+
+ // Test writing a PropertyIsNull filter out to XML
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.IS_NULL,
+ property: "prop"
+ });
+ node = format.write(filter);
+ t.xml_eq(node, test_xml, "filter correctly written");
+
+ }
+
+ function test_Intersects(t) {
+
+ t.plan(4);
+
+ var str =
+ '<Filter xmlns="http://www.opengis.net/ogc">' +
+ '<Intersects>' +
+ '<PropertyName>Geometry</PropertyName>' +
+ '<gml:Polygon xmlns:gml="http://www.opengis.net/gml">' +
+ '<gml:outerBoundaryIs>' +
+ '<gml:LinearRing>' +
+ '<gml:coordinates decimal="." cs="," ts=" ">2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552</gml:coordinates>' +
+ '</gml:LinearRing>' +
+ '</gml:outerBoundaryIs>' +
+ '</gml:Polygon>' +
+ '</Intersects>' +
+ '</Filter>';
+
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ property: "Geometry",
+ value: OpenLayers.Geometry.fromWKT("POLYGON((2488789 289552, 2588789 289552, 2588789 389552, 2488789 389552, 2488789 289552))")
+ });
+
+ // test writing
+ var node = format.write(filter);
+ t.xml_eq(node, str, "filter correctly written");
+
+ // test reading
+ var doc = (new OpenLayers.Format.XML).read(str);
+ var got = format.read(doc.firstChild);
+ t.eq(got.type, filter.type, "read correct type");
+ t.eq(got.property, filter.property, "read correct property");
+ t.geom_eq(got.value, filter.value, "read correct value");
+
+ }
+
+ function test_Within(t) {
+
+ t.plan(4);
+
+ var str =
+ '<Filter xmlns="http://www.opengis.net/ogc">' +
+ '<Within>' +
+ '<PropertyName>Geometry</PropertyName>' +
+ '<gml:Polygon xmlns:gml="http://www.opengis.net/gml">' +
+ '<gml:outerBoundaryIs>' +
+ '<gml:LinearRing>' +
+ '<gml:coordinates decimal="." cs="," ts=" ">2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552</gml:coordinates>' +
+ '</gml:LinearRing>' +
+ '</gml:outerBoundaryIs>' +
+ '</gml:Polygon>' +
+ '</Within>' +
+ '</Filter>';
+
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.WITHIN,
+ property: "Geometry",
+ value: OpenLayers.Geometry.fromWKT("POLYGON((2488789 289552, 2588789 289552, 2588789 389552, 2488789 389552, 2488789 289552))")
+ });
+
+ // test writing
+ var node = format.write(filter);
+ t.xml_eq(node, str, "filter correctly written");
+
+ // test reading
+ var doc = (new OpenLayers.Format.XML).read(str);
+ var got = format.read(doc.firstChild);
+ t.eq(got.type, filter.type, "read correct type");
+ t.eq(got.property, filter.property, "read correct property");
+ t.geom_eq(got.value, filter.value, "read correct value");
+
+ }
+
+ function test_Contains(t) {
+
+ t.plan(4);
+
+ var str =
+ '<Filter xmlns="http://www.opengis.net/ogc">' +
+ '<Contains>' +
+ '<PropertyName>Geometry</PropertyName>' +
+ '<gml:Polygon xmlns:gml="http://www.opengis.net/gml">' +
+ '<gml:outerBoundaryIs>' +
+ '<gml:LinearRing>' +
+ '<gml:coordinates decimal="." cs="," ts=" ">2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552</gml:coordinates>' +
+ '</gml:LinearRing>' +
+ '</gml:outerBoundaryIs>' +
+ '</gml:Polygon>' +
+ '</Contains>' +
+ '</Filter>';
+
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.CONTAINS,
+ property: "Geometry",
+ value: OpenLayers.Geometry.fromWKT("POLYGON((2488789 289552, 2588789 289552, 2588789 389552, 2488789 389552, 2488789 289552))")
+ });
+
+ // test writing
+ var node = format.write(filter);
+ t.xml_eq(node, str, "filter correctly written");
+
+ // test reading
+ var doc = (new OpenLayers.Format.XML).read(str);
+ var got = format.read(doc.firstChild);
+ t.eq(got.type, filter.type, "read correct type");
+ t.eq(got.property, filter.property, "read correct property");
+ t.geom_eq(got.value, filter.value, "read correct value");
+
+ }
+
+ function test_logical_fid(t) {
+ // the Filter Encoding spec doesn't allow for FID filters inside logical filters
+ // however, to be liberal, we will write them without complaining
+ t.plan(3);
+
+ var filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.OR,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "person",
+ value: "me"
+ }),
+ new OpenLayers.Filter.FeatureId({fids: ["foo.1", "foo.2"]})
+ ]
+ });
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+
+ var got = format.write(filter);
+ var exp = readXML("LogicalFeatureId");
+ t.xml_eq(got, exp, "wrote FID filter in logical OR without complaint");
+
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "person",
+ value: "me"
+ }),
+ new OpenLayers.Filter.FeatureId({fids: ["foo.1", "foo.2"]})
+ ]
+ });
+ got = format.write(filter);
+ exp = readXML("LogicalFeatureIdAnd");
+ t.xml_eq(got, exp, "wrote FID filter in logical AND without complaint");
+
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.NOT,
+ filters: [
+ new OpenLayers.Filter.FeatureId({fids: ["foo.2"]})
+ ]
+ });
+ got = format.write(filter);
+ exp = readXML("LogicalFeatureIdNot");
+ t.xml_eq(got, exp, "wrote FID filter in logical NOT without complaint");
+ }
+
+ function test_between_literal(t) {
+ t.plan(3);
+
+ var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.BETWEEN,
+ property: "foo",
+ lowerBoundary: 1.0,
+ upperBoundary: 2.0
+ });
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+
+ var exp = format.read(readXML("BetweenLiteral"));
+
+ // confirm that reading works as expected
+ t.eq(exp.property, "foo", "property");
+ t.eq(exp.lowerBoundary, 1.0, "lowerBoundary");
+ t.eq(exp.upperBoundary, 2.0, "upperBoundary");
+ }
+
+
+ function test_date_writing(t) {
+ t.plan(1);
+
+ // ISO 8601: 2010-11-27T18:19:15.123Z
+ var start = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));
+
+ // ISO 8601: 2011-12-27T18:19:15.123Z
+ var end = new Date(Date.UTC(2011, 11, 27, 18, 19, 15, 123));
+
+ var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.BETWEEN,
+ property: "when",
+ lowerBoundary: start,
+ upperBoundary: end
+ });
+
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+
+ var got = format.write(filter);
+ var exp = readXML("BetweenDates");
+ t.xml_eq(got, exp, "comparison filter with dates");
+ }
+
+
+ function test_custom_date_writing(t) {
+ t.plan(1);
+
+ // ISO 8601: 2010-11-27T18:19:15.123Z
+ var start = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));
+
+ // ISO 8601: 2011-12-27T18:19:15.123Z
+ var end = new Date(Date.UTC(2011, 11, 27, 18, 19, 15, 123));
+
+ var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.BETWEEN,
+ property: "when",
+ lowerBoundary: start,
+ upperBoundary: end
+ });
+
+ var format = new OpenLayers.Format.Filter({
+ encodeLiteral: function(value) {
+ // return just the date and not the time portion
+ return OpenLayers.Date.toISOString(value).split("T").shift();
+ }
+ });
+
+ var got = format.write(filter);
+ var exp = readXML("CustomBetweenDates");
+ t.xml_eq(got, exp, "comparison filter with dates");
+ }
+
+
+ function readXML(id) {
+ var xml = document.getElementById(id).firstChild.nodeValue;
+ return new OpenLayers.Format.XML().read(xml).documentElement;
+ }
+
+
+ </script>
+</head>
+<body>
+
+<div id="LogicalFeatureId"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:Or>
+ <ogc:PropertyIsLike wildCard="*" singleChar="." escape="!">
+ <ogc:PropertyName>person</ogc:PropertyName>
+ <ogc:Literal>me</ogc:Literal>
+ </ogc:PropertyIsLike>
+ <ogc:FeatureId fid="foo.1"/>
+ <ogc:FeatureId fid="foo.2"/>
+ </ogc:Or>
+</ogc:Filter>
+--></div>
+<div id="LogicalFeatureIdAnd"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:And>
+ <ogc:PropertyIsLike wildCard="*" singleChar="." escape="!">
+ <ogc:PropertyName>person</ogc:PropertyName>
+ <ogc:Literal>me</ogc:Literal>
+ </ogc:PropertyIsLike>
+ <ogc:FeatureId fid="foo.1"/>
+ <ogc:FeatureId fid="foo.2"/>
+ </ogc:And>
+</ogc:Filter>
+--></div>
+<div id="LogicalFeatureIdNot"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:Not>
+ <ogc:FeatureId fid="foo.2"/>
+ </ogc:Not>
+</ogc:Filter>
+--></div>
+<div id="BetweenLiteral"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsBetween>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:LowerBoundary>
+ <ogc:Literal>1.0</ogc:Literal>
+ </ogc:LowerBoundary>
+ <ogc:UpperBoundary>
+ <ogc:Literal>2.0</ogc:Literal>
+ </ogc:UpperBoundary>
+ </ogc:PropertyIsBetween>
+</ogc:Filter>
+--></div>
+<div id="BetweenDates"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsBetween>
+ <ogc:PropertyName>when</ogc:PropertyName>
+ <ogc:LowerBoundary>
+ <ogc:Literal>2010-11-27T18:19:15.123Z</ogc:Literal>
+ </ogc:LowerBoundary>
+ <ogc:UpperBoundary>
+ <ogc:Literal>2011-12-27T18:19:15.123Z</ogc:Literal>
+ </ogc:UpperBoundary>
+ </ogc:PropertyIsBetween>
+</ogc:Filter>
+--></div>
+<div id="CustomBetweenDates"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsBetween>
+ <ogc:PropertyName>when</ogc:PropertyName>
+ <ogc:LowerBoundary>
+ <ogc:Literal>2010-11-27</ogc:Literal>
+ </ogc:LowerBoundary>
+ <ogc:UpperBoundary>
+ <ogc:Literal>2011-12-27</ogc:Literal>
+ </ogc:UpperBoundary>
+ </ogc:PropertyIsBetween>
+</ogc:Filter>
+--></div>
+
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/Filter/v1_0_0.html b/misc/openlayers/tests/Format/Filter/v1_0_0.html
new file mode 100644
index 0000000..876723f
--- /dev/null
+++ b/misc/openlayers/tests/Format/Filter/v1_0_0.html
@@ -0,0 +1,295 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var test_xml =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:Or>' +
+ '<ogc:PropertyIsBetween>' +
+ '<ogc:PropertyName>number</ogc:PropertyName>' +
+ '<ogc:LowerBoundary>' +
+ '<ogc:Literal>1064866676</ogc:Literal>' +
+ '</ogc:LowerBoundary>' +
+ '<ogc:UpperBoundary>' +
+ '<ogc:Literal>1065512599</ogc:Literal>' +
+ '</ogc:UpperBoundary>' +
+ '</ogc:PropertyIsBetween>' +
+ '<ogc:PropertyIsLike wildCard="*" singleChar="." escape="!">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>*dog.food!*good</ogc:Literal>' +
+ '</ogc:PropertyIsLike>' +
+ '<ogc:Not>' +
+ '<ogc:PropertyIsLessThanOrEqualTo>' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Literal>5000</ogc:Literal>' +
+ '</ogc:PropertyIsLessThanOrEqualTo>' +
+ '</ogc:Not>' +
+ '</ogc:Or>' +
+ '</ogc:Filter>';
+
+ function test_read(t) {
+ t.plan(3);
+
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+ var xml = new OpenLayers.Format.XML();
+ var filter = parser.read(xml.read(test_xml).documentElement);
+
+ t.ok(filter instanceof OpenLayers.Filter.Logical, "instance of correct class");
+ t.eq(filter.type, OpenLayers.Filter.Logical.OR, "correct type");
+ t.eq(filter.filters.length, 3, "correct number of child filters");
+ }
+
+ function test_write(t) {
+ t.plan(1);
+
+ // read first - testing that write produces the ogc:Filter element above
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+ var xml = new OpenLayers.Format.XML();
+ var filter = parser.read(xml.read(test_xml).documentElement);
+
+ var node = parser.write(filter);
+ t.xml_eq(node, test_xml, "filter correctly written");
+
+ }
+
+ function test_BBOX(t) {
+ t.plan(1);
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ property: "the_geom",
+ value: new OpenLayers.Bounds(-180, -90, 180, 90),
+ projection: "EPSG:4326"
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:BBOX>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
+ '<gml:coordinates decimal="." cs="," ts=" ">-180,-90 180,90</gml:coordinates>' +
+ '</gml:Box>' +
+ '</ogc:BBOX>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+ var node = parser.write(filter);
+
+ t.xml_eq(node, out, "bbox correctly written");
+ }
+
+ function test_BBOX_noGeometryName(t) {
+ t.plan(1);
+ // WFS 1.0.0 does not allow BBOX filters without property, but
+ // GeoServer accepts them.
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(-180, -90, 180, 90),
+ projection: "EPSG:4326"
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:BBOX>' +
+ '<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
+ '<gml:coordinates decimal="." cs="," ts=" ">-180,-90 180,90</gml:coordinates>' +
+ '</gml:Box>' +
+ '</ogc:BBOX>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+ var node = parser.write(filter);
+
+ t.xml_eq(node, out, "bbox correctly written");
+ }
+
+ function test_DWithin(t) {
+
+ t.plan(6);
+
+ var str =
+ '<Filter xmlns="http://www.opengis.net/ogc">' +
+ '<DWithin>' +
+ '<PropertyName>Geometry</PropertyName>' +
+ '<gml:Point xmlns:gml="http://www.opengis.net/gml">' +
+ '<gml:coordinates decimal="." cs="," ts=" ">2488789,289552</gml:coordinates>' +
+ '</gml:Point>' +
+ '<Distance units="m">1000</Distance>' +
+ '</DWithin>' +
+ '</Filter>';
+
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ property: "Geometry",
+ value: new OpenLayers.Geometry.Point(2488789,289552),
+ distance: 1000,
+ distanceUnits: "m"
+ });
+
+ // test writing
+ var node = format.write(filter);
+ t.xml_eq(node, str, "filter correctly written");
+
+ // test reading
+ var doc = (new OpenLayers.Format.XML).read(str);
+ var got = format.read(doc.firstChild);
+ t.eq(got.type, filter.type, "read correct type");
+ t.eq(got.property, filter.property, "read correct property");
+ t.geom_eq(got.value, filter.value, "read correct value");
+ t.eq(got.distance, filter.distance, "read correct distance");
+ t.eq(got.distanceUnits, filter.distanceUnits, "read correct distance units");
+
+ }
+
+ function test_Intersects(t) {
+
+ t.plan(4);
+
+ var str =
+ '<Filter xmlns="http://www.opengis.net/ogc">' +
+ '<Intersects>' +
+ '<PropertyName>Geometry</PropertyName>' +
+ '<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
+ '<gml:coordinates decimal="." cs="," ts=" ">-180,-90 180,90</gml:coordinates>' +
+ '</gml:Box>' +
+ '</Intersects>' +
+ '</Filter>';
+
+ var format = new OpenLayers.Format.Filter.v1_0_0();
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ property: "Geometry",
+ value: new OpenLayers.Bounds(-180, -90, 180, 90),
+ projection: "EPSG:4326"
+ });
+
+ // test writing
+ var node = format.write(filter);
+ t.xml_eq(node, str, "filter correctly written");
+
+ // test reading
+ var doc = (new OpenLayers.Format.XML).read(str);
+ var got = format.read(doc.firstChild);
+ t.eq(got.type, filter.type, "read correct type");
+ t.eq(got.property, filter.property, "read correct property");
+ t.eq(got.value.toArray(), filter.value.toArray(), "read correct value");
+
+ }
+
+ function test_FilterFunctions(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+
+ //test spatial intersects with filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ value: new OpenLayers.Filter.Function({
+ name : 'querySingle',
+ params: ['sf:restricted', 'the_geom', 'cat=3']
+ })
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:Intersects>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="querySingle">' +
+ '<ogc:Literal>sf:restricted</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>cat=3</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Intersects>' +
+ '</ogc:Filter>';
+
+
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial intersect filter with functions correctly written");
+
+ //test logical filter with custom function
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
+ property: "FOO",
+ value: new OpenLayers.Filter.Function({
+ name : 'customFunction',
+ params : ['param1', 'param2']
+ })
+ })
+ ]
+ });
+
+ out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:And>' +
+ '<ogc:PropertyIsNotEqualTo>' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Function name="customFunction">' +
+ '<ogc:Literal>param1</ogc:Literal>' +
+ '<ogc:Literal>param2</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:PropertyIsNotEqualTo>' +
+ '</ogc:And>' +
+ '</ogc:Filter>';
+
+ node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "comparison filter with filter functions correctly written");
+
+ }
+
+ function test_NestedFilterFunctions(t) {
+ t.plan(1);
+
+ //test spatial dwithin with nested filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ value: new OpenLayers.Filter.Function({
+ name : 'collectGeometries',
+ params: [
+ new OpenLayers.Filter.Function({
+ name : 'queryCollection',
+ params: ['sf:roads', 'the_geom', 'INCLUDE']
+ })
+ ]
+ }),
+ distanceUnits: "meters",
+ distance: 200
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:DWithin>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="collectGeometries">' +
+ '<ogc:Function name="queryCollection">' +
+ '<ogc:Literal>sf:roads</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>INCLUDE</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Function>' +
+ '<ogc:Distance units="meters">200</ogc:Distance>' +
+ '</ogc:DWithin>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_0_0();
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial dwithin filter with nested functions correctly written");
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/Filter/v1_1_0.html b/misc/openlayers/tests/Format/Filter/v1_1_0.html
new file mode 100644
index 0000000..68d1ec1
--- /dev/null
+++ b/misc/openlayers/tests/Format/Filter/v1_1_0.html
@@ -0,0 +1,402 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var test_xml =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:Or>' +
+ '<ogc:PropertyIsBetween>' +
+ '<ogc:PropertyName>number</ogc:PropertyName>' +
+ '<ogc:LowerBoundary>' +
+ '<ogc:Literal>1064866676</ogc:Literal>' +
+ '</ogc:LowerBoundary>' +
+ '<ogc:UpperBoundary>' +
+ '<ogc:Literal>1065512599</ogc:Literal>' +
+ '</ogc:UpperBoundary>' +
+ '</ogc:PropertyIsBetween>' +
+ '<ogc:PropertyIsLike wildCard="*" singleChar="." escapeChar="!">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>*dog.food!*good</ogc:Literal>' +
+ '</ogc:PropertyIsLike>' +
+ '<ogc:Not>' +
+ '<ogc:PropertyIsLessThanOrEqualTo>' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Literal>5000</ogc:Literal>' +
+ '</ogc:PropertyIsLessThanOrEqualTo>' +
+ '</ogc:Not>' +
+ '<ogc:PropertyIsEqualTo matchCase="true">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '<ogc:PropertyIsEqualTo matchCase="false">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Or>' +
+ '</ogc:Filter>';
+
+ function test_read(t) {
+ t.plan(3);
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var xml = new OpenLayers.Format.XML();
+ var filter = parser.read(xml.read(test_xml).documentElement);
+
+ t.ok(filter instanceof OpenLayers.Filter.Logical, "instance of correct class");
+ t.eq(filter.type, OpenLayers.Filter.Logical.OR, "correct type");
+ t.eq(filter.filters.length, 5, "correct number of child filters");
+ }
+
+ function test_write(t) {
+ t.plan(1);
+
+ // read first - testing that write produces the ogc:Filter element above
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var xml = new OpenLayers.Format.XML();
+ var filter = parser.read(xml.read(test_xml).documentElement);
+
+ var node = parser.write(filter);
+ t.xml_eq(node, test_xml, "filter correctly written");
+
+ }
+
+ function test_matchCase(t) {
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var xml = new OpenLayers.Format.XML();
+
+ var cases = [{
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsEqualTo>' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>',
+ exp: true
+ }, {
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsEqualTo matchCase="1">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>',
+ exp: true
+ }, {
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsEqualTo matchCase="true">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>',
+ exp: true
+ }, {
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsEqualTo matchCase="0">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>',
+ exp: false
+ }, {
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsEqualTo matchCase="0">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>',
+ exp: false
+ }, {
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsNotEqualTo matchCase="true">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsNotEqualTo>' +
+ '</ogc:Filter>',
+ exp: true
+ }, {
+ str:
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:PropertyIsNotEqualTo matchCase="false">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>dog</ogc:Literal>' +
+ '</ogc:PropertyIsNotEqualTo>' +
+ '</ogc:Filter>',
+ exp: false
+ }];
+
+ t.plan(cases.length);
+
+ var filter, c;
+ for(var i=0; i<cases.length; ++i) {
+ c = cases[i];
+ filter = parser.read(xml.read(c.str).documentElement);
+ t.eq(filter.matchCase, c.exp, "case " + i);
+ }
+
+ }
+
+ function test_BBOX(t) {
+ t.plan(1);
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ property: "the_geom",
+ value: new OpenLayers.Bounds(-180, -90, 180, 90),
+ projection: "EPSG:4326"
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:BBOX>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
+ '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +
+ '<gml:upperCorner>180 90</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</ogc:BBOX>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var node = parser.write(filter);
+
+ t.xml_eq(node, out, "bbox correctly written");
+ }
+
+ function test_BBOX_noGeometryName(t) {
+ t.plan(1);
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(-180, -90, 180, 90),
+ projection: "EPSG:4326"
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:BBOX>' +
+ '<gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
+ '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +
+ '<gml:upperCorner>180 90</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</ogc:BBOX>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var node = parser.write(filter);
+
+ t.xml_eq(node, out, "bbox correctly written");
+ }
+
+
+ function test_Intersects(t) {
+
+ t.plan(4);
+
+ var str =
+ '<Filter xmlns="http://www.opengis.net/ogc">' +
+ '<Intersects>' +
+ '<PropertyName>Geometry</PropertyName>' +
+ '<gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326">' +
+ '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +
+ '<gml:upperCorner>180 90</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</Intersects>' +
+ '</Filter>';
+
+ var format = new OpenLayers.Format.Filter.v1_1_0();
+ var filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ property: "Geometry",
+ value: new OpenLayers.Bounds(-180, -90, 180, 90),
+ projection: "EPSG:4326"
+ });
+
+ // test writing
+ var node = format.write(filter);
+ t.xml_eq(node, str, "filter correctly written");
+
+ // test reading
+ var doc = (new OpenLayers.Format.XML).read(str);
+ var got = format.read(doc.firstChild);
+ t.eq(got.type, filter.type, "read correct type");
+ t.eq(got.property, filter.property, "read correct property");
+ t.eq(got.value.toArray(), filter.value.toArray(), "read correct value");
+
+ }
+
+ function test_FilterFunctions(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+
+ //test spatial intersects with filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.INTERSECTS,
+ value: new OpenLayers.Filter.Function({
+ name : 'querySingle',
+ params: ['sf:restricted', 'the_geom', 'cat=3']
+ })
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:Intersects>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="querySingle">' +
+ '<ogc:Literal>sf:restricted</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>cat=3</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Intersects>' +
+ '</ogc:Filter>';
+
+
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial intersect filter with functions correctly written");
+
+ //test logical filter with custom function
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
+ matchCase: false,
+ property: "FOO",
+ value: new OpenLayers.Filter.Function({
+ name : 'customFunction',
+ params : ['param1', 'param2']
+ })
+ })
+ ]
+ });
+
+ out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:And>' +
+ '<ogc:PropertyIsNotEqualTo matchCase="false">' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Function name="customFunction">' +
+ '<ogc:Literal>param1</ogc:Literal>' +
+ '<ogc:Literal>param2</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:PropertyIsNotEqualTo>' +
+ '</ogc:And>' +
+ '</ogc:Filter>';
+
+ node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "comparison filter with filter functions correctly written");
+
+ }
+
+ function test_NestedFilterFunctions(t) {
+ t.plan(1);
+
+ //test spatial dwithin with nested filter function
+ var filter = new OpenLayers.Filter.Spatial({
+ property: 'the_geom',
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ value: new OpenLayers.Filter.Function({
+ name : 'collectGeometries',
+ params: [
+ new OpenLayers.Filter.Function({
+ name : 'queryCollection',
+ params: ['sf:roads', 'the_geom', 'INCLUDE']
+ })
+ ]
+ }),
+ distanceUnits: "meters",
+ distance: 200
+ });
+
+ var out =
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:DWithin>' +
+ '<ogc:PropertyName>the_geom</ogc:PropertyName>' +
+ '<ogc:Function name="collectGeometries">' +
+ '<ogc:Function name="queryCollection">' +
+ '<ogc:Literal>sf:roads</ogc:Literal>' +
+ '<ogc:Literal>the_geom</ogc:Literal>' +
+ '<ogc:Literal>INCLUDE</ogc:Literal>' +
+ '</ogc:Function>' +
+ '</ogc:Function>' +
+ '<ogc:Distance units="meters">200</ogc:Distance>' +
+ '</ogc:DWithin>' +
+ '</ogc:Filter>';
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var node = parser.write(filter);
+
+ //test writer
+ t.xml_eq(node, out, "spatial dwithin filter with nested functions correctly written");
+ }
+
+ function test_write_like_matchcase(t) {
+ t.plan(1);
+
+ var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "person",
+ value: "*me*",
+ matchCase: false
+ });
+
+ var format = new OpenLayers.Format.Filter.v1_1_0();
+
+ var got = format.write(filter);
+ var exp = readXML("LikeMatchCase");
+ t.xml_eq(got, exp, "wrote matchCase attribute on PropertyIsLike");
+ }
+
+ function readXML(id) {
+ var xml = document.getElementById(id).firstChild.nodeValue;
+ return new OpenLayers.Format.XML().read(xml).documentElement;
+ }
+
+ function test_SortBy(t) {
+ t.plan(1);
+
+ var out =
+ '<ogc:SortBy xmlns:ogc="http://www.opengis.net/ogc">'+
+ '<ogc:SortProperty>'+
+ '<ogc:PropertyName>Title</ogc:PropertyName>'+
+ '<ogc:SortOrder>ASC</ogc:SortOrder>'+
+ '</ogc:SortProperty>'+
+ '<ogc:SortProperty>'+
+ '<ogc:PropertyName>Relevance</ogc:PropertyName>'+
+ '<ogc:SortOrder>DESC</ogc:SortOrder>'+
+ '</ogc:SortProperty>'+
+ '</ogc:SortBy>';
+
+ var parser = new OpenLayers.Format.Filter.v1_1_0();
+ var node = parser.writers['ogc'].SortBy.call(parser, [{
+ "property": 'Title',
+ "order": "ASC"
+ },{
+ "property": 'Relevance',
+ "order": "DESC"
+ }]);
+
+ t.xml_eq(node, out, "Check SortBy");
+ }
+ </script>
+</head>
+<body>
+<div id="LikeMatchCase"><!--
+<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsLike wildCard="*" singleChar="." escapeChar="!" matchCase="false">
+ <ogc:PropertyName>person</ogc:PropertyName>
+ <ogc:Literal>*me*</ogc:Literal>
+ </ogc:PropertyIsLike>
+</ogc:Filter>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/GML.html b/misc/openlayers/tests/Format/GML.html
new file mode 100644
index 0000000..43b8fbd
--- /dev/null
+++ b/misc/openlayers/tests/Format/GML.html
@@ -0,0 +1,462 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_Format_GML_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.GML(options);
+ t.ok(format instanceof OpenLayers.Format.GML,
+ "new OpenLayers.Format.GML returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+ function test_Format_GML_getFid(t) {
+ t.plan(2);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[1]);
+ t.eq(data[0].fid, '221', 'fid on polygons set correctly (with whitespace)');
+ t.eq(data[1].fid, '8', 'fid on linestrings set correctly with whitespace');
+ }
+ function test_Format_GML_no_clobber(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[1]);
+ t.eq(window.i, undefined,
+ "i is undefined in window scope after reading.");
+ }
+ function test_Format_GML_read_3d(t) {
+ t.plan(2);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[0]);
+ t.eq(data[0].geometry.getBounds().toBBOX(), "-1254041.389712,250906.951598,-634517.119991,762236.29408", "Reading 3d content returns geometry with correct bounds (no 0,0)");
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Reading 3d content returns polygon geometry");
+ }
+ function test_Format_GML_write_geoms(t) {
+ t.plan(5);
+ var parser = new OpenLayers.Format.GML();
+
+ var point = shell_start + serialize_geoms['point'] + shell_end;
+ data = parser.read(point);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, point, "Point geometry round trips correctly.");
+
+ var linestring = shell_start + serialize_geoms['linestring'] + shell_end;
+ data = parser.read(linestring);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, linestring, "Line geometry round trips correctly.");
+
+ var polygon = shell_start + serialize_geoms['polygon'] + shell_end;
+ data = parser.read(polygon);
+ var output = parser.write(data);
+ output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, polygon, "Poly geometry round trips correctly.");
+
+ var multipoint = shell_start + serialize_geoms['multipoint'] + shell_end;
+ data = parser.read(multipoint);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, multipoint, "MultiPoint geometry round trips correctly.");
+
+ var multilinestring = shell_start + serialize_geoms['multilinestring'] + shell_end;
+ data = parser.read(multilinestring);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, multilinestring, "MultiLine geometry round trips correctly.");
+
+ }
+ function test_Format_GML_read_point_geom(t) {
+ t.plan(3);
+
+ var point = shell_start + geoms['point'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(point);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Point", "Point GML returns correct classname");
+ t.eq(data[0].geometry.x, 1, "x coord correct");
+ t.eq(data[0].geometry.y, 2, "y coord correct");
+ }
+ function test_Format_GML_read_linestring_geom(t) {
+ t.plan(5);
+
+ var line = shell_start + geoms['linestring'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(line);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.LineString", "LineString GML returns correct classname");
+ t.eq(data[0].geometry.components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[1].y, 5, "second y coord correct");
+ }
+ function test_Format_GML_read_polygon_geom(t) {
+ t.plan(7);
+
+ var polygon = shell_start + geoms['polygon'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(polygon);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Polygon GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components.length, 1, "rings length correct");
+ }
+ function test_Format_GML_read_multipoint_geom(t) {
+ t.plan(6);
+
+ var multipoint = shell_start + geoms['multipoint'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(multipoint);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPoint", "MultiPoint GML returns correct classname");
+ t.eq(data[0].geometry.components[0].x, 1, "x coord correct");
+ t.eq(data[0].geometry.components[0].y, 2, "y coord correct");
+ t.eq(data[0].geometry.components.length, 2, "length correct");
+ t.eq(data[0].geometry.components[1].x, 4, "x coord correct");
+ t.eq(data[0].geometry.components[1].y, 5, "y coord correct");
+ }
+ function test_Format_GML_read_multilinestring_geom(t) {
+ t.plan(6);
+
+ var multilinestring = shell_start + geoms['multilinestring'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(multilinestring);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.MultiLineString", "MultiLineString GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 2, "length correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "y coord correct");
+
+ }
+ function test_Format_GML_read_polygon_with_holes_geom(t) {
+ t.plan(12);
+
+ var polygon_with_holes = shell_start + geoms['polygon_with_holes'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(polygon_with_holes);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Polygon GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components[1].components[0].x, 11, "first x coord correct");
+ t.eq(data[0].geometry.components[1].components[0].y, 12, "first y coord correct");
+ t.eq(data[0].geometry.components[1].components[1].x, 14, "second x coord correct");
+ t.eq(data[0].geometry.components[1].components[1].y, 15, "second y coord correct");
+ t.eq(data[0].geometry.components[1].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components.length, 2, "rings length correct");
+ }
+ function test_Format_GML_read_attributes(t) {
+ t.plan(3);
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(test_content[0]);
+ t.eq(data[0].attributes['NAME'], "WY", "Simple Attribute data is read correctly.");
+ t.eq(data[0].attributes['LONGNAME'], "Wyoming", "Attribute data is read from CDATA node correctly.");
+ t.ok(data[0].attributes['EMPTYATTR'] === null, "Attribute set to null for empty element.");
+ }
+ function test_Format_GML_read_envelope_geom(t) {
+ t.plan(13);
+
+ var envelope = shell_start + geoms['envelope'] + shell_end;
+ var parser = new OpenLayers.Format.GML();
+ data = parser.read(envelope);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Envelope GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 0, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 1, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 20, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 1, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components[2].x, 20, "third x coord correct");
+ t.eq(data[0].geometry.components[0].components[2].y, 21, "third y coord correct");
+ t.eq(data[0].geometry.components[0].components[3].x, 0, "fouth x coord correct");
+ t.eq(data[0].geometry.components[0].components[3].y, 21, "fourth y coord correct");
+ t.eq(data[0].geometry.components[0].components[4].x, 0, "fifth x coord correct");
+ t.eq(data[0].geometry.components[0].components[4].y, 1, "fifth y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 5, "coords length correct");
+ t.eq(data[0].geometry.components.length, 1, "rings length correct");
+ }
+ ///////////////////////////////////////////////////////////////
+ // tests the y x order of gml point
+ /////////////////////////////////////////////////////////////
+ function test_Format_GML_read_point_geom_yx(t) {
+ t.plan(3);
+
+ var point = shell_start + geoms_yx['point'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(point);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Point", "Point GML returns correct classname");
+ t.eq(data[0].geometry.x, 1, "x coord correct");
+ t.eq(data[0].geometry.y, 2, "y coord correct");
+ }
+ function test_Format_GML_read_linestring_geom_yx(t) {
+ t.plan(5);
+
+ var line = shell_start + geoms_yx['linestring'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(line);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.LineString", "LineString GML returns correct classname");
+ t.eq(data[0].geometry.components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[1].y, 5, "second y coord correct");
+ }
+ function test_Format_GML_read_polygon_geom_yx(t) {
+ t.plan(7);
+
+ var polygon = shell_start + geoms_yx['polygon'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(polygon);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Polygon GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components.length, 1, "rings length correct");
+ }
+ function test_Format_GML_read_multipoint_geom_yx(t) {
+ t.plan(6);
+
+ var multipoint = shell_start + geoms_yx['multipoint'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(multipoint);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPoint", "MultiPoint GML returns correct classname");
+ t.eq(data[0].geometry.components[0].x, 1, "x coord correct");
+ t.eq(data[0].geometry.components[0].y, 2, "y coord correct");
+ t.eq(data[0].geometry.components.length, 2, "length correct");
+ t.eq(data[0].geometry.components[1].x, 4, "x coord correct");
+ t.eq(data[0].geometry.components[1].y, 5, "y coord correct");
+ }
+ function test_Format_GML_read_multilinestring_geom_yx(t) {
+ t.plan(6);
+
+ var multilinestring = shell_start + geoms_yx['multilinestring'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(multilinestring);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.MultiLineString", "MultiLineString GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 2, "length correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "y coord correct");
+
+ }
+ function test_Format_GML_read_polygon_with_holes_geom_yx(t) {
+ t.plan(12);
+
+ var polygon_with_holes = shell_start + geoms_yx['polygon_with_holes'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(polygon_with_holes);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Polygon GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 1, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 2, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 4, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 5, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components[1].components[0].x, 11, "first x coord correct");
+ t.eq(data[0].geometry.components[1].components[0].y, 12, "first y coord correct");
+ t.eq(data[0].geometry.components[1].components[1].x, 14, "second x coord correct");
+ t.eq(data[0].geometry.components[1].components[1].y, 15, "second y coord correct");
+ t.eq(data[0].geometry.components[1].components.length, 4, "coords length correct");
+ t.eq(data[0].geometry.components.length, 2, "rings length correct");
+ }
+
+ function test_Format_GML_read_envelope_geom_yx(t) {
+ t.plan(13);
+
+ var envelope = shell_start + geoms_yx['envelope'] + shell_end;
+ var parser = new OpenLayers.Format.GML({'xy':false});
+ data = parser.read(envelope);
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Envelope GML returns correct classname");
+ t.eq(data[0].geometry.components[0].components[0].x, 0, "first x coord correct");
+ t.eq(data[0].geometry.components[0].components[0].y, 1, "first y coord correct");
+ t.eq(data[0].geometry.components[0].components[1].x, 20, "second x coord correct");
+ t.eq(data[0].geometry.components[0].components[1].y, 1, "second y coord correct");
+ t.eq(data[0].geometry.components[0].components[2].x, 20, "third x coord correct");
+ t.eq(data[0].geometry.components[0].components[2].y, 21, "third y coord correct");
+ t.eq(data[0].geometry.components[0].components[3].x, 0, "fouth x coord correct");
+ t.eq(data[0].geometry.components[0].components[3].y, 21, "fourth y coord correct");
+ t.eq(data[0].geometry.components[0].components[4].x, 0, "fifth x coord correct");
+ t.eq(data[0].geometry.components[0].components[4].y, 1, "fifth y coord correct");
+ t.eq(data[0].geometry.components[0].components.length, 5, "coords length correct");
+ t.eq(data[0].geometry.components.length, 1, "rings length correct");
+ }
+
+ function test_Format_GML_write_geoms_yx(t) {
+ t.plan(5);
+ var parser = new OpenLayers.Format.GML({'xy':false});
+
+ var point_xy = shell_start + serialize_geoms['point'] + shell_end;
+ var point = shell_start + serialize_geoms_yx['point'] + shell_end;
+ data = parser.read(point);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, point_xy, "Point geometry round trips correctly.");
+
+ var linestring_xy = shell_start + serialize_geoms['linestring'] + shell_end;
+ var linestring = shell_start + serialize_geoms_yx['linestring'] + shell_end;
+ data = parser.read(linestring);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, linestring_xy, "Line geometry round trips correctly.");
+
+ var polygon_xy = shell_start + serialize_geoms['polygon'] + shell_end;
+ var polygon = shell_start + serialize_geoms_yx['polygon'] + shell_end;
+ data = parser.read(polygon);
+ var output = parser.write(data);
+ output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, polygon_xy, "Poly geometry round trips correctly.");
+
+ var multipoint_xy = shell_start + serialize_geoms['multipoint'] + shell_end;
+ var multipoint = shell_start + serialize_geoms_yx['multipoint'] + shell_end;
+ data = parser.read(multipoint);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, multipoint_xy, "MultiPoint geometry round trips correctly.");
+
+ var multilinestring_xy = shell_start + serialize_geoms['multilinestring'] + shell_end;
+ var multilinestring = shell_start + serialize_geoms_yx['multilinestring'] + shell_end;
+ data = parser.read(multilinestring);
+ var output = parser.write(data);
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, multilinestring_xy, "MultiLine geometry round trips correctly.");
+ }
+
+ function test_buildGeometryNode_bounds(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.GML();
+ var bounds = new OpenLayers.Bounds(-180, -90, 180, 90);
+ var output, expect;
+
+ // test that bounds are written as gml:Box
+ var output = parser.buildGeometryNode(bounds);
+ var expect = '<gml:Box xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="." cs="," ts=" ">-180,-90 180,90</gml:coordinates></gml:Box>';
+ t.xml_eq(output, expect, "[xy true] Bounds correctly written as gml:Box");
+ }
+
+ function test_parseFeatureBox(t) {
+ t.plan(8);
+ var parser = new OpenLayers.Format.GML();
+ var xmlparser = new OpenLayers.Format.XML();
+
+ var data = xmlparser.read(test_box[0]);
+ var feature = parser.parseFeature(data);
+ t.ok(feature.bounds instanceof OpenLayers.Bounds,
+ "got bounds object for feature.bounds when with boundedBy Box, without geometry");
+ t.eq(feature.geometry, null, 'geometry is null for a feature with boundedBy Box, but no geometry');
+
+ var data = xmlparser.read(test_box[1]);
+ feature = parser.parseFeature(data);
+ t.eq(feature.bounds, null,
+ "feature is null when without boundedBy Box, with Box geometry");
+ t.ok(feature.geometry instanceof OpenLayers.Geometry.Polygon,
+ "got polygon object for feature.geometry when without boundedBy Box, with Box geometry");
+
+ data = xmlparser.read(test_box[2]);
+ feature = parser.parseFeature(data);
+ t.eq(feature.bounds, null,
+ "feature.bounds is null when without boundedBy Box, without geometry");
+ t.eq(feature.geometry, null, 'geometry is null when without boundedBy Box, without geometry');
+
+ data = xmlparser.read(test_box[3]);
+ feature = parser.parseFeature(data);
+ t.ok(feature.bounds instanceof OpenLayers.Bounds,
+ "got bounds object for feature.bounds when with boundedBy Box, with Box geometry");
+ t.ok(feature.geometry instanceof OpenLayers.Geometry.Polygon,
+ "got polygon object for feature.geometry when with boundedBy Box, with Box geometry");
+ }
+
+ var test_box = [
+ // with boundedBy Box, without geometry
+ '<Sentiers_littoraux_feature><gml:boundedBy xmlns:gml="http://www.opengis.net/gml"><gml:Box srsName="EPSG:2154"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></gml:boundedBy><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>',
+ // without boundedBy Box, with Box geometry
+ '<Sentiers_littoraux_feature><msGeometry><gml:Box srsName="EPSG:2154" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></msGeometry><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>',
+ // without boundedBy, without geometry
+ '<Sentiers_littoraux_feature><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>',
+ // with boundedBy Box, with Box geometry
+ '<Sentiers_littoraux_feature><msGeometry><gml:Box srsName="EPSG:2154" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></msGeometry><gml:boundedBy xmlns:gml="http://www.opengis.net/gml"><gml:Box srsName="EPSG:2154"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></gml:boundedBy><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>'];
+
+ var test_content = ['<?xml version="1.0" encoding="utf-8" ?>\n<ogr:FeatureCollection\n xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n xsi:schemaLocation="http://ogr.maptools.org/ testoutput.xsd"\n xmlns:ogr="http://ogr.maptools.org/"\n xmlns:gml="http://www.opengis.net/gml">\n <gml:boundedBy>\n <gml:Box>\n <gml:coord><gml:X>-1254041.389711702</gml:X><gml:Y>250906.9515983529</gml:Y></gml:coord>\n <gml:coord><gml:X>-634517.1199908922</gml:X><gml:Y>762236.2940800377</gml:Y></gml:coord>\n </gml:Box>\n </gml:boundedBy> \n <gml:featureMember>\n <ogr:states fid="F0">\n <ogr:geometryProperty><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-634517.11999089224,691849.77929356066,0 -653761.64509297756,471181.53429472551,0 -673343.60852865304,250906.9515983529,0 -1088825.734430399,299284.85108220269,0 -1254041.3897117018,324729.27754874947,0 -1235750.4212498858,434167.33911316615,0 -1190777.7803201093,704392.96327195223,0 -1181607.835811228,762236.29408003774,0 -634517.11999089224,691849.77929356066,0</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>\n <ogr:NAME>WY</ogr:NAME>\n <ogr:EMPTYATTR/><ogr:LONGNAME><![CDATA[Wyoming]]></ogr:LONGNAME>\n </ogr:states>\n </gml:featureMember>\n</ogr:FeatureCollection>\n',
+ '<wfs:FeatureCollection' +
+ ' xmlns:fs="http://example.com/featureserver"' +
+ ' xmlns:wfs="http://www.opengis.net/wfs"' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' xmlns:ogc="http://www.opengis.net/ogc"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+ ' xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd">' +
+ ' ' +
+ '' +
+ ' <gml:featureMember>' +
+ ' \n<fs:scribble fid="221">' +
+ ' <fs:geometry>' +
+ ' <gml:Polygon>' +
+ ' ' +
+ ' <gml:outerBoundaryIs><gml:LinearRing>' +
+ ' <gml:coordinates>149.105072021,-35.1816558838 149.100608826,-35.1844024658 149.098892212,-35.1898956299 149.105072021,-35.1816558838</gml:coordinates>' +
+ ' </gml:LinearRing></gml:outerBoundaryIs>' +
+ ' ' +
+ ' </gml:Polygon>' +
+ ' </fs:geometry>' +
+ ' <fs:title>random test features</fs:title>' +
+ ' </fs:scribble>' +
+ '</gml:featureMember> ' +
+ ' <gml:featureMember><fs:scribble fid="8"> <fs:geometry> <gml:Point><gml:coordinates>-81.38671875,27.0703125</gml:coordinates></gml:Point> </fs:geometry> ' +
+ ' <fs:down>south</fs:down><fs:title>Florida</fs:title> </fs:scribble></gml:featureMember>' +
+ '</wfs:FeatureCollection>'
+ ];
+
+ var shell_start = '<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"><gml:featureMember xmlns:gml="http://www.opengis.net/gml"><feature:features xmlns:feature="http://mapserver.gis.umn.edu/mapserver" fid="221"><feature:geometry>';
+ if (OpenLayers.BROWSER_NAME == "opera") {
+ shell_start = '<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"><gml:featureMember xmlns:gml="http://www.opengis.net/gml"><feature:features fid="221" xmlns:feature="http://mapserver.gis.umn.edu/mapserver"><feature:geometry>';
+ }
+ var shell_end = '</feature:geometry></feature:features></gml:featureMember></wfs:FeatureCollection>';
+ var serialize_geoms = {
+ 'point': '<gml:Point><gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates></gml:Point>',
+ 'linestring': '<gml:LineString><gml:coordinates decimal="." cs="," ts=" ">1,2 4,5</gml:coordinates></gml:LineString>',
+ 'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates decimal="." cs="," ts=" ">1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',
+ 'multipoint': '<gml:MultiPoint><gml:pointMember><gml:Point><gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates decimal="." cs="," ts=" ">4,5</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>',
+ 'multilinestring': '<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:coordinates decimal="." cs="," ts=" ">1,2 4,5</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates decimal="." cs="," ts=" ">11,12 14,15</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>'
+ };
+ var geoms = {
+ 'point': '<gml:Point><gml:coordinates>1,2,3</gml:coordinates></gml:Point>',
+ 'linestring': '<gml:LineString><gml:coordinates>1,2,3 4,5,6</gml:coordinates></gml:LineString>',
+ 'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',
+ 'polygon_with_holes': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>11,12 14,15 13,16 11,12</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>',
+ 'multipoint': '<gml:MultiPoint><gml:Point><gml:coordinates>1,2,3</gml:coordinates></gml:Point><gml:Point><gml:coordinates>4,5,6</gml:coordinates></gml:Point></gml:MultiPoint>',
+ 'multilinestring': '<gml:MultiLineString><gml:LineString><gml:coordinates>1,2,3 4,5,6</gml:coordinates></gml:LineString><gml:LineString><gml:coordinates>11,12,13 14,15,16</gml:coordinates></gml:LineString></gml:MultiLineString>',
+ 'envelope': '<gml:Envelope><gml:lowerCorner>0 1</gml:lowerCorner><gml:upperCorner>20 21</gml:upperCorner></gml:Envelope>' // ,
+ // 'multipolygon_with_holes': '<gml:MultiPolygon><gml:Polygon><gml:outerBoundaryIs>1,2 4,5 3,6 1,2</gml:outerBoundaryIs><gml:innerBoundaryIs>11,12 14,15 13,16 11,12</gml:innerBoundaryIs></gml:Polygon><gml:Polygon><gml:outerBoundaryIs>101,102 104,105 103,106 101,102</gml:outerBoundaryIs><gml:innerBoundaryIs>111,112 114,115 113,116 111,112</gml:innerBoundaryIs></gml:Polygon></gml:MultiPolygon>'
+ };
+
+
+//
+// The following data has the (x y) reordered to (y x), in 3 dimensions it goes from (x y z) to (y x z)
+//
+
+ var serialize_geoms_yx = {
+ 'point': '<gml:Point><gml:coordinates decimal="." cs="," ts=" ">2,1</gml:coordinates></gml:Point>',
+ 'linestring': '<gml:LineString><gml:coordinates decimal="." cs="," ts=" ">2,1 5,4</gml:coordinates></gml:LineString>',
+ 'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates decimal="." cs="," ts=" ">2,1 5,4 6,3 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',
+ 'multipoint': '<gml:MultiPoint><gml:pointMember><gml:Point><gml:coordinates decimal="." cs="," ts=" ">2,1</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates decimal="." cs="," ts=" ">5,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>',
+ 'multilinestring': '<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:coordinates decimal="." cs="," ts=" ">2,1 5,4</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates decimal="." cs="," ts=" ">12,11 15,14</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>'
+ };
+ var geoms_yx = {
+ 'point': '<gml:Point><gml:coordinates>2,1,3</gml:coordinates></gml:Point>',
+ 'linestring': '<gml:LineString><gml:coordinates>2,1,3 5,4,6</gml:coordinates></gml:LineString>',
+ 'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,1 5,4 6,3 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',
+ 'polygon_with_holes': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,1 5,4 6,3 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>12,11 15,14 16,13 12,11</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>',
+ 'multipoint': '<gml:MultiPoint><gml:Point><gml:coordinates>2,1,3</gml:coordinates></gml:Point><gml:Point><gml:coordinates>5,4,6</gml:coordinates></gml:Point></gml:MultiPoint>',
+ 'multilinestring': '<gml:MultiLineString><gml:LineString><gml:coordinates>2,1,3 5,4,6</gml:coordinates></gml:LineString><gml:LineString><gml:coordinates>12,11,13 15,14,16</gml:coordinates></gml:LineString></gml:MultiLineString>',
+ 'envelope': '<gml:Envelope><gml:lowerCorner>1 0</gml:lowerCorner><gml:upperCorner>21 20</gml:upperCorner></gml:Envelope>'
+ };
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/GML/cases.js b/misc/openlayers/tests/Format/GML/cases.js
new file mode 100644
index 0000000..88499cd
--- /dev/null
+++ b/misc/openlayers/tests/Format/GML/cases.js
@@ -0,0 +1,232 @@
+var xml = new OpenLayers.Format.XML();
+function readXML(file) {
+ return xml.read(document.getElementById(file).firstChild.nodeValue);
+}
+
+var cases = {
+
+ "v2/point-coord.xml": new OpenLayers.Geometry.Point(1, 2),
+
+ "v2/point-coordinates.xml": new OpenLayers.Geometry.Point(1, 2),
+
+ "v2/linestring-coord.xml": new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4)
+ ]),
+
+ "v2/linestring-coordinates.xml": new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4)
+ ]),
+
+ "v2/linearring-coord.xml": new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+
+ "v2/linearring-coordinates.xml": new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+
+ "v2/polygon-coord.xml": new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(4, 5),
+ new OpenLayers.Geometry.Point(6, 7),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(7, 8),
+ new OpenLayers.Geometry.Point(3, 4)
+ ])
+ ]),
+
+ "v2/polygon-coordinates.xml": new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(4, 5),
+ new OpenLayers.Geometry.Point(6, 7),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(7, 8),
+ new OpenLayers.Geometry.Point(3, 4)
+ ])
+ ]),
+
+ "v2/multipoint-coord.xml": new OpenLayers.Geometry.MultiPoint([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(3, 4)
+ ]),
+
+ "v2/multipoint-coordinates.xml": new OpenLayers.Geometry.MultiPoint([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(3, 4)
+ ]),
+
+ "v2/multilinestring-coord.xml": new OpenLayers.Geometry.MultiLineString([
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(4, 5)
+ ])
+ ]),
+
+ "v2/multilinestring-coordinates.xml": new OpenLayers.Geometry.MultiLineString([
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(4, 5)
+ ])
+ ]),
+
+ "v2/multipolygon-coord.xml": new OpenLayers.Geometry.MultiPolygon([
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(4, 5),
+ new OpenLayers.Geometry.Point(6, 7),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(7, 8),
+ new OpenLayers.Geometry.Point(3, 4)
+ ])
+ ]),
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ])
+ ])
+ ]),
+
+ "v2/multipolygon-coordinates.xml": new OpenLayers.Geometry.MultiPolygon([
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(4, 5),
+ new OpenLayers.Geometry.Point(6, 7),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(7, 8),
+ new OpenLayers.Geometry.Point(3, 4)
+ ])
+ ]),
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ])
+ ])
+ ]),
+
+ "v2/geometrycollection-coordinates.xml": new OpenLayers.Geometry.Collection([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4)
+ ]),
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1, 2),
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(1, 2)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(2, 3),
+ new OpenLayers.Geometry.Point(4, 5),
+ new OpenLayers.Geometry.Point(6, 7),
+ new OpenLayers.Geometry.Point(2, 3)
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(3, 4),
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(7, 8),
+ new OpenLayers.Geometry.Point(3, 4)
+ ])
+ ])
+ ]),
+
+ "v2/box-coord.xml": new OpenLayers.Bounds(1, 2, 3, 4),
+
+ "v2/box-coordinates.xml": new OpenLayers.Bounds(1, 2, 3, 4),
+
+ "v3/linestring3d.xml": new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 2, 3),
+ new OpenLayers.Geometry.Point(4, 5, 6)
+ ])
+
+};
+
+// some cases for v3 use the same geometries
+OpenLayers.Util.extend(cases, {
+ "v3/point.xml": cases["v2/point-coordinates.xml"],
+ "v3/linestring.xml": cases["v2/linestring-coordinates.xml"],
+ "v3/curve.xml": cases["v2/linestring-coordinates.xml"],
+ "v3/polygon.xml": cases["v2/polygon-coordinates.xml"],
+ "v3/surface.xml": cases["v2/polygon-coordinates.xml"],
+ "v3/multipoint-singular.xml": cases["v2/multipoint-coordinates.xml"],
+ "v3/multipoint-plural.xml": cases["v2/multipoint-coordinates.xml"],
+ "v3/multilinestring-singular.xml": cases["v2/multilinestring-coordinates.xml"],
+ "v3/multilinestring-plural.xml": cases["v2/multilinestring-coordinates.xml"],
+ "v3/multicurve-singular.xml": cases["v2/multilinestring-coordinates.xml"],
+ "v3/multicurve-curve.xml": cases["v2/multilinestring-coordinates.xml"],
+ "v3/multipolygon-singular.xml": cases["v2/multipolygon-coordinates.xml"],
+ "v3/multipolygon-plural.xml": cases["v2/multipolygon-coordinates.xml"],
+ "v3/multisurface-singular.xml": cases["v2/multipolygon-coordinates.xml"],
+ "v3/multisurface-plural.xml": cases["v2/multipolygon-coordinates.xml"],
+ "v3/multisurface-surface.xml": cases["v2/multipolygon-coordinates.xml"],
+ "v3/envelope.xml": cases["v2/box-coordinates.xml"]
+}); \ No newline at end of file
diff --git a/misc/openlayers/tests/Format/GML/v2.html b/misc/openlayers/tests/Format/GML/v2.html
new file mode 100644
index 0000000..8857d05
--- /dev/null
+++ b/misc/openlayers/tests/Format/GML/v2.html
@@ -0,0 +1,684 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script src="cases.js"></script>
+ <script type="text/javascript">
+
+ function test_readNode_geometry(t) {
+ var files = [
+ "v2/point-coord.xml", "v2/point-coordinates.xml",
+ "v2/linestring-coord.xml", "v2/linestring-coordinates.xml",
+ "v2/polygon-coord.xml", "v2/polygon-coordinates.xml",
+ "v2/multipoint-coord.xml", "v2/multipoint-coordinates.xml",
+ "v2/multilinestring-coord.xml", "v2/multilinestring-coordinates.xml",
+ "v2/multipolygon-coord.xml", "v2/multipolygon-coordinates.xml",
+ "v2/geometrycollection-coordinates.xml"
+ ];
+
+ var len = files.length;
+ t.plan(len);
+
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "feature",
+ featureNS: "http://example.com/feature"
+ });
+ var file, doc, expect, out;
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ expect = cases[file];
+ if(expect) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ out = format.readNode(doc.documentElement);
+ if(out.components && out.components.length == 1) {
+ t.geom_eq(out.components[0], expect, "[" + file + "] geometry read");
+ } else {
+ t.fail("[" + file + "] gml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+
+ }
+
+ function test_readNode_bounds(t) {
+ var files = ["v2/box-coord.xml", "v2/box-coordinates.xml"];
+
+ var len = files.length;
+ t.plan(len);
+
+ var file, doc, expect, got;
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "feature",
+ featureNS: "http://example.com/feature"
+ });
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ expect = cases[file];
+ if(expect) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ out = format.readNode(doc.documentElement);
+ if(out.components && out.components.length == 1) {
+ got = out.components[0];
+ if(got instanceof OpenLayers.Bounds) {
+ t.ok(out.components[0].equals(expect), "[" + file + "] bounds read")
+ } else {
+ t.fail("[" + file + "] expected a bounds, got " + got);
+ }
+ } else {
+ t.fail("[" + file + "] gml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+
+ }
+
+ function test_writeNode_geometry(t) {
+ // we only care to write the 'coordinates' variant of GML 2
+ var files = [
+ "v2/point-coordinates.xml",
+ "v2/linestring-coordinates.xml",
+ "v2/polygon-coordinates.xml",
+ "v2/multipoint-coordinates.xml",
+ "v2/multilinestring-coordinates.xml",
+ "v2/multipolygon-coordinates.xml",
+ "v2/geometrycollection-coordinates.xml"
+ ];
+
+ var len = files.length;
+ t.plan(len);
+
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "feature",
+ featureNS: "http://example.com/feature",
+ srsName: "foo" // GML geometry collections require srsName, we only write if provided
+ });
+ var file, geom, doc, node;
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ geom = cases[file];
+ if(geom) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ node = format.writeNode("feature:_geometry", geom);
+ t.xml_eq(node.firstChild, doc.documentElement, "[" + file + "] geometry written");
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+ }
+
+ function test_writeNode_bounds(t) {
+ // we only care to write the 'coordinates' variant of GML 2
+ var files = [
+ "v2/box-coordinates.xml"
+ ];
+
+ var len = files.length;
+ t.plan(len);
+
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "feature",
+ featureNS: "http://example.com/feature",
+ srsName: "foo" // GML box does not require srsName, we only write if provided
+ });
+ var file, bounds, doc, node;
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ bounds = cases[file];
+ if(bounds) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ node = format.writeNode("gml:Box", bounds);
+ t.xml_eq(node, doc.documentElement, "[" + file + "] bounds written");
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+ }
+
+ function test_read(t) {
+ t.plan(8);
+ var doc = readXML("v2/topp-states.xml");
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom"
+ });
+ var features = format.read(doc.documentElement);
+
+ t.eq(features.length, 3, "read 3 features");
+ var feature = features[0];
+ t.eq(feature.fid, "states.1", "read fid");
+ t.eq(feature.geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon",
+ "read multipolygon geometry");
+ var attributes = feature.attributes;
+ t.eq(attributes["STATE_NAME"], "Illinois", "read STATE_NAME");
+ t.eq(attributes["STATE_FIPS"], "17", "read STATE_FIPS");
+ t.eq(attributes["SUB_REGION"], "E N Cen", "read SUB_REGION");
+ t.eq(attributes["STATE_ABBR"], "IL", "read STATE_ABBR");
+ t.eq(attributes["LAND_KM"], "143986.61", "read LAND_KM");
+ }
+
+ function test_read_autoconfig(t) {
+ t.plan(5);
+ var doc = readXML("v2/topp-states.xml");
+ var format = new OpenLayers.Format.GML.v2();
+ var features = format.read(doc.documentElement);
+
+ t.eq(features.length, 3, "read 3 features");
+ var feature = features[0];
+ t.eq(feature.fid, "states.1", "read fid");
+ t.eq(feature.geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon",
+ "read multipolygon geometry");
+ t.eq(format.featureType, "states", "featureType correctly auto-configured");
+ t.eq(format.featureNS, "http://www.openplans.org/topp", "featureNS correctly auto-configured");
+ }
+
+ function test_boundedBy(t) {
+ t.plan(5);
+
+ var doc = readXML("v2/boundedBy.xml");
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom",
+ xy: false
+ });
+ var features = format.read(doc.documentElement);
+ var bounds = features[0].bounds;
+
+ t.ok(bounds instanceof OpenLayers.Bounds, "feature given a bounds");
+ t.eq(bounds.left.toFixed(2), "-91.52", "bounds left correct");
+ t.eq(bounds.bottom.toFixed(2), "36.99", "bounds bottom correct");
+ t.eq(bounds.right.toFixed(2), "-87.51", "bounds right correct");
+ t.eq(bounds.top.toFixed(2), "42.51", "bounds top correct");
+ }
+
+ function test_write(t) {
+ t.plan(1);
+ var doc = readXML("v2/topp-states.xml");
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom",
+ schemaLocation: "http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&version=1.0.0&request=DescribeFeatureType&typeName=topp:states http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd",
+ srsName: "http://www.opengis.net/gml/srs/epsg.xml#4326"
+ });
+ var features = format.read(doc.documentElement);
+
+ var got = format.write(features);
+ t.xml_eq(got, doc.documentElement, "wfs:FeatureCollection round trip");
+
+ }
+
+ function test_multipleTypenames(t) {
+ t.plan(5);
+ var doc = readXML("v2/multipletypenames.xml");
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: ["LKUNSTWERK", "PKUNSTWERK", "VKUNSTWERK"],
+ featureNS: "http://mapserver.gis.umn.edu/mapserver",
+ geometry_name: "geometry"
+ });
+ var features = format.read(doc.documentElement);
+ t.eq(features.length, 3, "Expected 3 features from GML containing multiple typenames");
+ t.eq(features[0].type, "VKUNSTWERK", "First feature type is from the VKUNSTWERK typename");
+ t.eq(features[1].type, "LKUNSTWERK", "Second feature type is from the LKUNSTWERK typename");
+ t.eq(features[2].type, "PKUNSTWERK", "Third feature type is from the PKUNSTWERK typename");
+ t.eq(features[0].namespace, "http://mapserver.gis.umn.edu/mapserver", "Namespace is set correctly on feature");
+ }
+
+ function test_noGeom(t) {
+ t.plan(7);
+ var doc = readXML("v2/nogeom.xml");
+ var format = new OpenLayers.Format.GML.v2({
+ featureType: "DEPARTEMENT",
+ featureNS: "http://server.fr/geoserver/loc"
+ });
+ var features = format.read(doc.documentElement);
+ t.eq(features.length, 2, "Expected 2 features from GML with no geom");
+ var feature = features[0];
+ t.ok(feature.geometry == null, "feature 0 has no geometry");
+ var bounds = feature.bounds;
+ t.ok(bounds && (bounds instanceof OpenLayers.Bounds), "feature 0 has been assigned bounds");
+ t.eq(bounds.left, 209565, "bounds left correct");
+ t.eq(bounds.bottom, 6785323, "bounds bottom correct");
+ t.eq(bounds.right, 337568, "bounds right correct");
+ t.eq(bounds.top, 6885985, "bounds top correct");
+ }
+
+ </script>
+</head>
+<body>
+<div id="v2/point-coord.xml"><!--
+<gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+</gml:Point>
+--></div>
+<div id="v2/point-coordinates.xml"><!--
+<gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+</gml:Point>
+--></div>
+<div id="v2/linestring-coord.xml"><!--
+<gml:LineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+</gml:LineString>
+--></div>
+<div id="v2/linestring-coordinates.xml"><!--
+<gml:LineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4</gml:coordinates>
+</gml:LineString>
+--></div>
+<div id="v2/polygon-coord.xml"><!--
+<gml:Polygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>5</gml:X>
+ <gml:Y>6</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>4</gml:X>
+ <gml:Y>5</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>6</gml:X>
+ <gml:Y>7</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>5</gml:X>
+ <gml:Y>6</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>7</gml:X>
+ <gml:Y>8</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+</gml:Polygon>
+--></div>
+<div id="v2/polygon-coordinates.xml"><!--
+<gml:Polygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4 5,6 1,2</gml:coordinates>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">2,3 4,5 6,7 2,3</gml:coordinates>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4 5,6 7,8 3,4</gml:coordinates>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+</gml:Polygon>
+--></div>
+<div id="v2/multipoint-coord.xml"><!--
+<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ </gml:Point>
+ </gml:pointMember>
+</gml:MultiPoint>
+--></div>
+<div id="v2/multipoint-coordinates.xml"><!--
+<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">2,3</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+</gml:MultiPoint>
+--></div>
+<div id="v2/multilinestring-coord.xml"><!--
+<gml:MultiLineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ </gml:LineString>
+ </gml:lineStringMember>
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>4</gml:X>
+ <gml:Y>5</gml:Y>
+ </gml:coord>
+ </gml:LineString>
+ </gml:lineStringMember>
+</gml:MultiLineString>
+--></div>
+<div id="v2/multilinestring-coordinates.xml"><!--
+<gml:MultiLineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 2,3</gml:coordinates>
+ </gml:LineString>
+ </gml:lineStringMember>
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4 4,5</gml:coordinates>
+ </gml:LineString>
+ </gml:lineStringMember>
+</gml:MultiLineString>
+--></div>
+<div id="v2/multipolygon-coord.xml"><!--
+<gml:MultiPolygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>5</gml:X>
+ <gml:Y>6</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>4</gml:X>
+ <gml:Y>5</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>6</gml:X>
+ <gml:Y>7</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>5</gml:X>
+ <gml:Y>6</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>7</gml:X>
+ <gml:Y>8</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ </gml:Polygon>
+ </gml:polygonMember>
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>5</gml:X>
+ <gml:Y>6</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ </gml:Polygon>
+ </gml:polygonMember>
+</gml:MultiPolygon>
+--></div>
+<div id="v2/multipolygon-coordinates.xml"><!--
+<gml:MultiPolygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4 5,6 1,2</gml:coordinates>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">2,3 4,5 6,7 2,3</gml:coordinates>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4 5,6 7,8 3,4</gml:coordinates>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ </gml:Polygon>
+ </gml:polygonMember>
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4 5,6 1,2</gml:coordinates>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ </gml:Polygon>
+ </gml:polygonMember>
+</gml:MultiPolygon>
+--></div>
+<div id="v2/geometrycollection-coordinates.xml"><!--
+<gml:GeometryCollection xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:geometryMember>
+ <gml:Point srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </gml:geometryMember>
+ <gml:geometryMember>
+ <gml:LineString srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4</gml:coordinates>
+ </gml:LineString>
+ </gml:geometryMember>
+ <gml:geometryMember>
+ <gml:Polygon srsName="foo">
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4 5,6 1,2</gml:coordinates>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">2,3 4,5 6,7 2,3</gml:coordinates>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ <gml:innerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4 5,6 7,8 3,4</gml:coordinates>
+ </gml:LinearRing>
+ </gml:innerBoundaryIs>
+ </gml:Polygon>
+ </gml:geometryMember>
+</gml:GeometryCollection>
+--></div>
+<div id="v2/box-coord.xml"><!--
+<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+</gml:Box>
+--></div>
+<div id="v2/box-coordinates.xml"><!--
+<gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4</gml:coordinates>
+</gml:Box>
+--></div>
+<div id="v2/linearring-coord.xml"><!--
+<gml:LinearRing xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>5</gml:X>
+ <gml:Y>6</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+</gml:LinearRing>
+--></div>
+<div id="v2/linearring-coordinates.xml"><!--
+<gml:LinearRing xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4 5,6 1,2</gml:coordinates>
+</gml:LinearRing>
+--></div>
+<div id="v2/topp-states.xml"><!--
+<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd"><gml:featureMember><topp:states fid="states.1"><topp:the_geom><gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">37.5101,-88.0711 37.4761,-88.0871 37.4421,-88.3111 37.4091,-88.3591 37.4201,-88.4191 37.4001,-88.4671 37.2961,-88.5111 37.2571,-88.5011 37.2051,-88.4501 37.1561,-88.4221 37.0981,-88.4501 37.0721,-88.4761 37.0681,-88.4901 37.0641,-88.5171 37.0721,-88.5591 37.1091,-88.6141 37.1351,-88.6881 37.1411,-88.7391 37.1521,-88.7461 37.2021,-88.8631 37.2181,-88.9321 37.2201,-88.9931 37.1851,-89.0651 37.1121,-89.1161 37.0931,-89.1461 37.0641,-89.1691 37.0251,-89.1741 36.9981,-89.1501 36.9881,-89.1291 36.9861,-89.1931 37.0281,-89.2101 37.0411,-89.2371 37.0871,-89.2641 37.0911,-89.2841 37.0851,-89.3031 37.0601,-89.3091 37.0271,-89.2641 37.0081,-89.2621 36.9991,-89.2821 37.0091,-89.3101 37.0491,-89.3821 37.0991,-89.3791 37.1371,-89.4231 37.1651,-89.4401 37.2241,-89.4681 37.2531,-89.4651 37.2561,-89.4891 37.2761,-89.5131 37.3041,-89.5131 37.3291,-89.5001 37.3391,-89.4681 37.3551,-89.4351 37.4111,-89.4271 37.4531,-89.4531 37.4911,-89.4941 37.5711,-89.5241 37.6151,-89.5131 37.6501,-89.5191 37.6791,-89.5131 37.6941,-89.5211 37.7061,-89.5811 37.7451,-89.6661 37.7831,-89.6751 37.8041,-89.6911 37.8401,-89.7281 37.9051,-89.8511 37.9051,-89.8611 37.8911,-89.8661 37.8751,-89.9001 37.8781,-89.9371 37.9111,-89.9781 37.9631,-89.9581 37.9691,-90.0101 37.9931,-90.0411 38.0321,-90.1191 38.0531,-90.1341 38.0881,-90.2071 38.1221,-90.2541 38.1661,-90.2891 38.1881,-90.3361 38.2341,-90.3641 38.3231,-90.3691 38.3651,-90.3581 38.3901,-90.3391 38.4271,-90.3011 38.5181,-90.2651 38.5321,-90.2611 38.5621,-90.2401 38.6101,-90.1831 38.6581,-90.1831 38.7001,-90.2021 38.7231,-90.1961 38.7731,-90.1631 38.7851,-90.1351 38.8001,-90.1211 38.8301,-90.1131 38.8531,-90.1321 38.9141,-90.2431 38.9241,-90.2781 38.9241,-90.3191 38.9621,-90.4131 38.9591,-90.4691 38.8911,-90.5301 38.8711,-90.5701 38.8801,-90.6271 38.9351,-90.6681 39.0371,-90.7061 39.0581,-90.7071 39.0931,-90.6901 39.1441,-90.7161 39.1951,-90.7181 39.2241,-90.7321 39.2471,-90.7381 39.2961,-90.7791 39.3501,-90.8501 39.4001,-90.9471 39.4441,-91.0361 39.4731,-91.0641 39.5281,-91.0931 39.5521,-91.1561 39.6001,-91.2031 39.6851,-91.3171 39.7241,-91.3671 39.7611,-91.3731 39.8031,-91.3811 39.8631,-91.4491 39.8851,-91.4501 39.9011,-91.4341 39.9211,-91.4301 39.9461,-91.4471 40.0051,-91.4871 40.0661,-91.5041 40.1341,-91.5161 40.2001,-91.5061 40.2511,-91.4981 40.3091,-91.4861 40.3711,-91.4481 40.3861,-91.4181 40.3921,-91.3851 40.4021,-91.3721 40.4471,-91.3851 40.5031,-91.3741 40.5281,-91.3821 40.5471,-91.4121 40.5721,-91.4111 40.6031,-91.3751 40.6391,-91.2621 40.6431,-91.2141 40.6561,-91.1621 40.6821,-91.1291 40.7051,-91.1191 40.7611,-91.0921 40.8331,-91.0881 40.8791,-91.0491 40.9231,-90.9831 40.9501,-90.9601 41.0701,-90.9541 41.1041,-90.9571 41.1441,-90.9901 41.1651,-91.0181 41.1761,-91.0561 41.2311,-91.1011 41.2671,-91.1021 41.3341,-91.0731 41.4011,-91.0551 41.4231,-91.0271 41.4311,-91.0001 41.4211,-90.9491 41.4441,-90.8441 41.4491,-90.7791 41.4501,-90.7081 41.4621,-90.6581 41.5091,-90.6001 41.5251,-90.5401 41.5271,-90.4541 41.5431,-90.4341 41.5671,-90.4231 41.5861,-90.3481 41.6021,-90.3391 41.6491,-90.3411 41.7221,-90.3261 41.7561,-90.3041 41.7811,-90.2551 41.8061,-90.1951 41.9301,-90.1541 41.9831,-90.1421 42.0331,-90.1501 42.0611,-90.1681 42.1031,-90.1661 42.1201,-90.1761 42.1221,-90.1911 42.1591,-90.2301 42.1971,-90.3231 42.2101,-90.3671 42.2421,-90.4071 42.2631,-90.4171 42.3401,-90.4271 42.3601,-90.4411 42.3881,-90.4911 42.4211,-90.5631 42.4601,-90.6051 42.4751,-90.6481 42.4941,-90.6511 42.5091,-90.6381 42.5081,-90.4191 42.5041,-89.9231 42.5031,-89.8341 42.4971,-89.4001 42.4971,-89.3591 42.4901,-88.9391 42.4901,-88.7641 42.4891,-88.7061 42.4911,-88.2971 42.4891,-88.1941 42.4891,-87.7971 42.3141,-87.8361 42.1561,-87.7601 42.0591,-87.6701 41.8471,-87.6121 41.7231,-87.5291 41.4691,-87.5321 41.3011,-87.5321 41.1731,-87.5311 41.0091,-87.5321 40.7451,-87.5321 40.4941,-87.5371 40.4831,-87.5351 40.1661,-87.5351 39.8871,-87.5351 39.6091,-87.5351 39.4771,-87.5381 39.3501,-87.5401 39.3381,-87.5971 39.3071,-87.6251 39.2971,-87.6101 39.2811,-87.6151 39.2581,-87.6061 39.2481,-87.5841 39.2081,-87.5881 39.1981,-87.5941 39.1961,-87.6071 39.1681,-87.6441 39.1461,-87.6701 39.1301,-87.6591 39.1131,-87.6621 39.1031,-87.6311 39.0881,-87.6301 39.0841,-87.6121 39.0621,-87.5851 38.9951,-87.5811 38.9941,-87.5911 38.9771,-87.5471 38.9631,-87.5331 38.9311,-87.5301 38.9041,-87.5391 38.8691,-87.5591 38.8571,-87.5501 38.7951,-87.5071 38.7761,-87.5191 38.7691,-87.5081 38.7361,-87.5081 38.6851,-87.5431 38.6721,-87.5881 38.6421,-87.6251 38.6221,-87.6281 38.5991,-87.6191 38.5931,-87.6401 38.5731,-87.6521 38.5471,-87.6721 38.5151,-87.6511 38.5001,-87.6531 38.5041,-87.6791 38.4811,-87.6921 38.4661,-87.7561 38.4571,-87.7581 38.4451,-87.7381 38.4171,-87.7481 38.3781,-87.7841 38.3521,-87.8341 38.2861,-87.8501 38.2851,-87.8631 38.3161,-87.8741 38.3151,-87.8831 38.3001,-87.8881 38.2811,-87.9141 38.3021,-87.9131 38.3041,-87.9251 38.2411,-87.9801 38.2341,-87.9861 38.2001,-87.9771 38.1711,-87.9321 38.1571,-87.9311 38.1361,-87.9501 38.1311,-87.9731 38.1031,-88.0181 38.0921,-88.0121 38.0961,-87.9641 38.0731,-87.9751 38.0541,-88.0341 38.0451,-88.0431 38.0381,-88.0411 38.0331,-88.0211 38.0081,-88.0291 37.9751,-88.0211 37.9561,-88.0421 37.9341,-88.0411 37.9291,-88.0641 37.944,-88.0781 37.9231,-88.084 37.9171,-88.0301 37.9051,-88.0261 37.8961,-88.0441 37.9061,-88.1001 37.8951,-88.1011 37.8671,-88.0751 37.8431,-88.0341 37.8271,-88.0421 37.8311,-88.0891 37.8171,-88.0861 37.8051,-88.0351 37.7351,-88.0721 37.7001,-88.1331 37.6601,-88.1591 37.6281,-88.1571 37.5831,-88.1341 37.5101,-88.0711</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.1431E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states></gml:featureMember><gml:featureMember><topp:states fid="states.2"><topp:the_geom><gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">38.9661,-77.0081 38.8891,-76.9111 38.7881,-77.0451 38.8131,-77.0351 38.8291,-77.0451 38.8381,-77.0401 38.8621,-77.0391 38.8861,-77.0671 38.9151,-77.0781 38.9321,-77.1221 38.9931,-77.0421 38.9661,-77.0081</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>District of Columbia</topp:STATE_NAME><topp:STATE_FIPS>11</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DC</topp:STATE_ABBR><topp:LAND_KM>159.055</topp:LAND_KM><topp:WATER_KM>17.991</topp:WATER_KM><topp:PERSONS>606900.0</topp:PERSONS><topp:FAMILIES>122087.0</topp:FAMILIES><topp:HOUSHOLD>249634.0</topp:HOUSHOLD><topp:MALE>282970.0</topp:MALE><topp:FEMALE>323930.0</topp:FEMALE><topp:WORKERS>229975.0</topp:WORKERS><topp:DRVALONE>106694.0</topp:DRVALONE><topp:CARPOOL>36621.0</topp:CARPOOL><topp:PUBTRANS>111422.0</topp:PUBTRANS><topp:EMPLOYED>303994.0</topp:EMPLOYED><topp:UNEMPLOY>23442.0</topp:UNEMPLOY><topp:SERVICE>65498.0</topp:SERVICE><topp:MANUAL>22407.0</topp:MANUAL><topp:P_MALE>0.466</topp:P_MALE><topp:P_FEMALE>0.534</topp:P_FEMALE><topp:SAMP_POP>72696.0</topp:SAMP_POP></topp:states></gml:featureMember><gml:featureMember><topp:states fid="states.3"><topp:the_geom><gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">38.5571,-75.7071 38.6491,-75.7111 38.8301,-75.7241 39.1411,-75.7521 39.2471,-75.7611 39.2951,-75.7641 39.3831,-75.7721 39.7231,-75.7911 39.7241,-75.7751 39.7741,-75.7451 39.8201,-75.6951 39.8381,-75.6441 39.8401,-75.5831 39.8261,-75.4701 39.7981,-75.4201 39.7891,-75.4121 39.7781,-75.4281 39.7631,-75.4601 39.7411,-75.4751 39.7191,-75.4761 39.7141,-75.4891 39.6121,-75.6101 39.5661,-75.5621 39.4631,-75.5901 39.3661,-75.5151 39.2571,-75.4021 39.0731,-75.3971 39.0121,-75.3241 38.9451,-75.3071 38.8081,-75.1901 38.7991,-75.0831 38.4491,-75.0451 38.4491,-75.0681 38.4501,-75.0931 38.4551,-75.3501 38.4631,-75.6991 38.5571,-75.7071</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Delaware</topp:STATE_NAME><topp:STATE_FIPS>10</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DE</topp:STATE_ABBR><topp:LAND_KM>5062.456</topp:LAND_KM><topp:WATER_KM>1385.022</topp:WATER_KM><topp:PERSONS>666168.0</topp:PERSONS><topp:FAMILIES>175867.0</topp:FAMILIES><topp:HOUSHOLD>247497.0</topp:HOUSHOLD><topp:MALE>322968.0</topp:MALE><topp:FEMALE>343200.0</topp:FEMALE><topp:WORKERS>247566.0</topp:WORKERS><topp:DRVALONE>258087.0</topp:DRVALONE><topp:CARPOOL>42968.0</topp:CARPOOL><topp:PUBTRANS>8069.0</topp:PUBTRANS><topp:EMPLOYED>335147.0</topp:EMPLOYED><topp:UNEMPLOY>13945.0</topp:UNEMPLOY><topp:SERVICE>87973.0</topp:SERVICE><topp:MANUAL>44140.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>102776.0</topp:SAMP_POP></topp:states></gml:featureMember></wfs:FeatureCollection>
+--></div>
+<div id="v2/boundedBy.xml"><!--
+<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openplans.org/topp http://publicus.opengeo.org:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/wfs http://publicus.opengeo.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd"><gml:featureMember><topp:states fid="states.1"><gml:boundedBy><gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">36.9861,-91.5161 42.5091,-87.5071</gml:coordinates></gml:Box></gml:boundedBy><topp:the_geom><gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">37.5101,-88.0711 37.4761,-88.0871 37.4421,-88.3111 37.4091,-88.3591 37.4201,-88.4191 37.4001,-88.4671 37.2961,-88.5111 37.2571,-88.5011 37.2051,-88.4501 37.1561,-88.4221 37.0981,-88.4501 37.0721,-88.4761 37.0681,-88.4901 37.0641,-88.5171 37.0721,-88.5591 37.1091,-88.6141 37.1351,-88.6881 37.1411,-88.7391 37.1521,-88.7461 37.2021,-88.8631 37.2181,-88.9321 37.2201,-88.9931 37.1851,-89.0651 37.1121,-89.1161 37.0931,-89.1461 37.0641,-89.1691 37.0251,-89.1741 36.9981,-89.1501 36.9881,-89.1291 36.9861,-89.1931 37.0281,-89.2101 37.0411,-89.2371 37.0871,-89.2641 37.0911,-89.2841 37.0851,-89.3031 37.0601,-89.3091 37.0271,-89.2641 37.0081,-89.2621 36.9991,-89.2821 37.0091,-89.3101 37.0491,-89.3821 37.0991,-89.3791 37.1371,-89.4231 37.1651,-89.4401 37.2241,-89.4681 37.2531,-89.4651 37.2561,-89.4891 37.2761,-89.5131 37.3041,-89.5131 37.3291,-89.5001 37.3391,-89.4681 37.3551,-89.4351 37.4111,-89.4271 37.4531,-89.4531 37.4911,-89.4941 37.5711,-89.5241 37.6151,-89.5131 37.6501,-89.5191 37.6791,-89.5131 37.6941,-89.5211 37.7061,-89.5811 37.7451,-89.6661 37.7831,-89.6751 37.8041,-89.6911 37.8401,-89.7281 37.9051,-89.8511 37.9051,-89.8611 37.8911,-89.8661 37.8751,-89.9001 37.8781,-89.9371 37.9111,-89.9781 37.9631,-89.9581 37.9691,-90.0101 37.9931,-90.0411 38.0321,-90.1191 38.0531,-90.1341 38.0881,-90.2071 38.1221,-90.2541 38.1661,-90.2891 38.1881,-90.3361 38.2341,-90.3641 38.3231,-90.3691 38.3651,-90.3581 38.3901,-90.3391 38.4271,-90.3011 38.5181,-90.2651 38.5321,-90.2611 38.5621,-90.2401 38.6101,-90.1831 38.6581,-90.1831 38.7001,-90.2021 38.7231,-90.1961 38.7731,-90.1631 38.7851,-90.1351 38.8001,-90.1211 38.8301,-90.1131 38.8531,-90.1321 38.9141,-90.2431 38.9241,-90.2781 38.9241,-90.3191 38.9621,-90.4131 38.9591,-90.4691 38.8911,-90.5301 38.8711,-90.5701 38.8801,-90.6271 38.9351,-90.6681 39.0371,-90.7061 39.0581,-90.7071 39.0931,-90.6901 39.1441,-90.7161 39.1951,-90.7181 39.2241,-90.7321 39.2471,-90.7381 39.2961,-90.7791 39.3501,-90.8501 39.4001,-90.9471 39.4441,-91.0361 39.4731,-91.0641 39.5281,-91.0931 39.5521,-91.1561 39.6001,-91.2031 39.6851,-91.3171 39.7241,-91.3671 39.7611,-91.3731 39.8031,-91.3811 39.8631,-91.4491 39.8851,-91.4501 39.9011,-91.4341 39.9211,-91.4301 39.9461,-91.4471 40.0051,-91.4871 40.0661,-91.5041 40.1341,-91.5161 40.2001,-91.5061 40.2511,-91.4981 40.3091,-91.4861 40.3711,-91.4481 40.3861,-91.4181 40.3921,-91.3851 40.4021,-91.3721 40.4471,-91.3851 40.5031,-91.3741 40.5281,-91.3821 40.5471,-91.4121 40.5721,-91.4111 40.6031,-91.3751 40.6391,-91.2621 40.6431,-91.2141 40.6561,-91.1621 40.6821,-91.1291 40.7051,-91.1191 40.7611,-91.0921 40.8331,-91.0881 40.8791,-91.0491 40.9231,-90.9831 40.9501,-90.9601 41.0701,-90.9541 41.1041,-90.9571 41.1441,-90.9901 41.1651,-91.0181 41.1761,-91.0561 41.2311,-91.1011 41.2671,-91.1021 41.3341,-91.0731 41.4011,-91.0551 41.4231,-91.0271 41.4311,-91.0001 41.4211,-90.9491 41.4441,-90.8441 41.4491,-90.7791 41.4501,-90.7081 41.4621,-90.6581 41.5091,-90.6001 41.5251,-90.5401 41.5271,-90.4541 41.5431,-90.4341 41.5671,-90.4231 41.5861,-90.3481 41.6021,-90.3391 41.6491,-90.3411 41.7221,-90.3261 41.7561,-90.3041 41.7811,-90.2551 41.8061,-90.1951 41.9301,-90.1541 41.9831,-90.1421 42.0331,-90.1501 42.0611,-90.1681 42.1031,-90.1661 42.1201,-90.1761 42.1221,-90.1911 42.1591,-90.2301 42.1971,-90.3231 42.2101,-90.3671 42.2421,-90.4071 42.2631,-90.4171 42.3401,-90.4271 42.3601,-90.4411 42.3881,-90.4911 42.4211,-90.5631 42.4601,-90.6051 42.4751,-90.6481 42.4941,-90.6511 42.5091,-90.6381 42.5081,-90.4191 42.5041,-89.9231 42.5031,-89.8341 42.4971,-89.4001 42.4971,-89.3591 42.4901,-88.9391 42.4901,-88.7641 42.4891,-88.7061 42.4911,-88.2971 42.4891,-88.1941 42.4891,-87.7971 42.3141,-87.8361 42.1561,-87.7601 42.0591,-87.6701 41.8471,-87.6121 41.7231,-87.5291 41.4691,-87.5321 41.3011,-87.5321 41.1731,-87.5311 41.0091,-87.5321 40.7451,-87.5321 40.4941,-87.5371 40.4831,-87.5351 40.1661,-87.5351 39.8871,-87.5351 39.6091,-87.5351 39.4771,-87.5381 39.3501,-87.5401 39.3381,-87.5971 39.3071,-87.6251 39.2971,-87.6101 39.2811,-87.6151 39.2581,-87.6061 39.2481,-87.5841 39.2081,-87.5881 39.1981,-87.5941 39.1961,-87.6071 39.1681,-87.6441 39.1461,-87.6701 39.1301,-87.6591 39.1131,-87.6621 39.1031,-87.6311 39.0881,-87.6301 39.0841,-87.6121 39.0621,-87.5851 38.9951,-87.5811 38.9941,-87.5911 38.9771,-87.5471 38.9631,-87.5331 38.9311,-87.5301 38.9041,-87.5391 38.8691,-87.5591 38.8571,-87.5501 38.7951,-87.5071 38.7761,-87.5191 38.7691,-87.5081 38.7361,-87.5081 38.6851,-87.5431 38.6721,-87.5881 38.6421,-87.6251 38.6221,-87.6281 38.5991,-87.6191 38.5931,-87.6401 38.5731,-87.6521 38.5471,-87.6721 38.5151,-87.6511 38.5001,-87.6531 38.5041,-87.6791 38.4811,-87.6921 38.4661,-87.7561 38.4571,-87.7581 38.4451,-87.7381 38.4171,-87.7481 38.3781,-87.7841 38.3521,-87.8341 38.2861,-87.8501 38.2851,-87.8631 38.3161,-87.8741 38.3151,-87.8831 38.3001,-87.8881 38.2811,-87.9141 38.3021,-87.9131 38.3041,-87.9251 38.2411,-87.9801 38.2341,-87.9861 38.2001,-87.9771 38.1711,-87.9321 38.1571,-87.9311 38.1361,-87.9501 38.1311,-87.9731 38.1031,-88.0181 38.0921,-88.0121 38.0961,-87.9641 38.0731,-87.9751 38.0541,-88.0341 38.0451,-88.0431 38.0381,-88.0411 38.0331,-88.0211 38.0081,-88.0291 37.9751,-88.0211 37.9561,-88.0421 37.9341,-88.0411 37.9291,-88.0641 37.944,-88.0781 37.9231,-88.084 37.9171,-88.0301 37.9051,-88.0261 37.8961,-88.0441 37.9061,-88.1001 37.8951,-88.1011 37.8671,-88.0751 37.8431,-88.0341 37.8271,-88.0421 37.8311,-88.0891 37.8171,-88.0861 37.8051,-88.0351 37.7351,-88.0721 37.7001,-88.1331 37.6601,-88.1591 37.6281,-88.1571 37.5831,-88.1341 37.5101,-88.0711</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.1431E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states></gml:featureMember></wfs:FeatureCollection>
+--></div>
+<div id="v2/multipletypenames.xml"><!--
+<?xml version='1.0' encoding="ISO-8859-1" ?><wfs:FeatureCollection xmlns:rws="http://mapserver.gis.umn.edu/mapserver" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd http://mapserver.gis.umn.edu/mapserver http://intranet.rijkswaterstaat.nl/services/geoservices/kerngisnat_utre?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=VKUNSTWERK,LKUNSTWERK,PKUNSTWERK&amp;OUTPUTFORMAT=XMLSCHEMA"> <gml:boundedBy> <gml:Box srsName="EPSG:28992"> <gml:coordinates>134503.789000,455332.337000 135149.909000,455893.926000</gml:coordinates> </gml:Box> </gml:boundedBy> <gml:featureMember> <rws:VKUNSTWERK fid="VKUNSTWERK.16"> <gml:boundedBy> <gml:Box srsName="EPSG:28992"> <gml:coordinates>134949.571000,455438.845000 134978.799000,455471.762000</gml:coordinates> </gml:Box> </gml:boundedBy> <rws:geometry> <gml:MultiPolygon srsName="EPSG:28992"> <gml:polygonMember> <gml:Polygon> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>134974.191000,455471.587000 134973.974000,455471.762000 134973.558000,455471.248000 134973.579000,455471.230000 134963.143000,455458.768000 134962.787000,455458.653000 134960.514000,455456.003000 134960.440000,455455.539000 134950.207000,455443.320000 134950.158000,455443.360000 134949.571000,455442.638000 134949.810000,455442.462000 134951.417000,455441.223000 134951.435000,455441.209000 134954.158000,455439.108000 134954.507000,455438.845000 134955.000000,455439.420000 134954.954000,455439.458000 134965.046000,455451.520000 134965.568000,455451.606000 134968.159000,455454.642000 134968.120000,455455.195000 134978.294000,455467.355000 134978.330000,455467.326000 134978.799000,455467.881000 134978.598000,455468.042000 134975.885000,455470.224000 134974.191000,455471.587000 </gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> <gml:innerBoundaryIs> <gml:LinearRing> <gml:coordinates>134960.590000,455455.163000 134963.589000,455458.755000 134973.756000,455470.929000 134973.836000,455471.019000 134974.216000,455471.445000 134975.807000,455470.163000 134978.485000,455468.005000 134978.077000,455467.534000 134978.015000,455467.462000 134967.969000,455455.479000 134964.782000,455451.678000 134954.705000,455439.660000 134954.622000,455439.561000 134954.271000,455439.152000 134951.498000,455441.284000 134949.973000,455442.456000 134950.452000,455443.023000 134950.501000,455443.081000 134960.590000,455455.163000 </gml:coordinates> </gml:LinearRing> </gml:innerBoundaryIs> </gml:Polygon> </gml:polygonMember> </gml:MultiPolygon> </rws:geometry> <rws:OBJECTID>16</rws:OBJECTID> <rws:OBJECTSUBCATEGORIE>31</rws:OBJECTSUBCATEGORIE> </rws:VKUNSTWERK> </gml:featureMember> <gml:featureMember> <rws:LKUNSTWERK fid="LKUNSTWERK.14"> <gml:boundedBy> <gml:Box srsName="EPSG:28992"> <gml:coordinates>135080.966000,455332.337000 135149.909000,455390.384000</gml:coordinates> </gml:Box> </gml:boundedBy> <rws:geometry> <gml:MultiLineString srsName="EPSG:28992"> <gml:lineStringMember> <gml:LineString> <gml:coordinates>135080.966000,455390.384000 135096.654000,455377.009000 135109.082000,455366.755000 135122.769000,455355.276000 135141.565000,455339.633000 135149.909000,455332.337000 </gml:coordinates> </gml:LineString> </gml:lineStringMember> </gml:MultiLineString> </rws:geometry> <rws:OBJECTID>14</rws:OBJECTID> <rws:OBJECTSUBCATEGORIE>30</rws:OBJECTSUBCATEGORIE> </rws:LKUNSTWERK> </gml:featureMember> <gml:featureMember> <rws:PKUNSTWERK fid="PKUNSTWERK.29"> <gml:boundedBy> <gml:Box srsName="EPSG:28992"> <gml:coordinates>134832.017000,455596.187000 134832.017000,455596.187000</gml:coordinates> </gml:Box> </gml:boundedBy> <rws:geometry> <gml:MultiPoint srsName="EPSG:28992"> <gml:pointMember> <gml:Point> <gml:coordinates>134832.017000,455596.187000</gml:coordinates> </gml:Point> </gml:pointMember> </gml:MultiPoint> </rws:geometry> <rws:OBJECTID>29</rws:OBJECTID> <rws:OBJECTSUBCATEGORIE>30</rws:OBJECTSUBCATEGORIE> </rws:PKUNSTWERK> </gml:featureMember></wfs:FeatureCollection>
+--></div>
+<div id="v2/nogeom.xml"><!--
+<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:loc="http://server.fr/geoserver/loc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://server.fr:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd http://server.fr/geoserver/loc http://server.fr:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=loc:DEPARTEMENT"><gml:boundedBy><gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#2154"><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">199373,6704170 337568,6885985</gml:coordinates></gml:Box></gml:boundedBy><gml:featureMember><loc:DEPARTEMENT fid="DEPARTEMENT.1"><gml:boundedBy><gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#2154"><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">209565,6785323 337568,6885985</gml:coordinates></gml:Box></gml:boundedBy><loc:NOM_DEPT>COTES-D'ARMOR</loc:NOM_DEPT></loc:DEPARTEMENT></gml:featureMember><gml:featureMember><loc:DEPARTEMENT fid="DEPARTEMENT.3"><gml:boundedBy><gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#2154"><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">199373,6704170 323518,6807542</gml:coordinates></gml:Box></gml:boundedBy><loc:NOM_DEPT>MORBIHAN</loc:NOM_DEPT></loc:DEPARTEMENT></gml:featureMember></wfs:FeatureCollection>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/GML/v3.html b/misc/openlayers/tests/Format/GML/v3.html
new file mode 100644
index 0000000..92f2154
--- /dev/null
+++ b/misc/openlayers/tests/Format/GML/v3.html
@@ -0,0 +1,828 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script src="cases.js"></script>
+ <script type="text/javascript">
+
+ function test_readNode_geometry(t) {
+ var files = [
+ "v2/point-coord.xml", "v2/point-coordinates.xml",
+ "v2/linestring-coord.xml", "v2/linestring-coordinates.xml",
+ "v2/multipoint-coord.xml", "v2/multipoint-coordinates.xml",
+ "v2/multilinestring-coord.xml", "v2/multilinestring-coordinates.xml",
+ "v3/point.xml", "v3/linestring.xml", "v3/linestring3d.xml",
+ "v3/curve.xml", "v3/polygon.xml", "v3/surface.xml",
+ "v3/multipoint-singular.xml", "v3/multipoint-plural.xml",
+ "v3/multilinestring-singular.xml", "v3/multilinestring-plural.xml",
+ "v3/multicurve-singular.xml", "v3/multicurve-curve.xml",
+ "v3/multipolygon-singular.xml", "v3/multipolygon-plural.xml",
+ "v3/multisurface-singular.xml", "v3/multisurface-plural.xml",
+ "v3/multisurface-surface.xml"
+ ];
+
+ var len = files.length;
+ t.plan(len);
+
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "feature",
+ featureNS: "http://example.com/feature"
+ });
+ var file, doc, expect, out;
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ expect = cases[file];
+ if(expect) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ out = format.readNode(doc.documentElement);
+ if(out.components && out.components.length == 1) {
+ t.geom_eq(out.components[0], expect, "[" + file + "] geometry read");
+ } else {
+ t.fail("[" + file + "] gml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+
+ }
+
+ function test_read_setGeometryName(t) {
+ t.plan(1);
+ var doc = readXML("v3/topp-states-gml.xml");
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: null
+ });
+ var features = format.read(doc.documentElement);
+
+ t.eq(format.geometryName, "the_geom", "geometryName set when parsing features");
+ }
+
+ function test_readNode_bounds(t) {
+ var files = ["v3/envelope.xml"];
+
+ var len = files.length;
+ t.plan(len);
+
+ var file, doc, expect, got;
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "feature",
+ featureNS: "http://example.com/feature"
+ });
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ expect = cases[file];
+ if(expect) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ out = format.readNode(doc.documentElement);
+ if(out.components && out.components.length == 1) {
+ got = out.components[0];
+ if(got instanceof OpenLayers.Bounds) {
+ t.ok(out.components[0].equals(expect), "[" + file + "] bounds read")
+ } else {
+ t.fail("[" + file + "] expected a bounds, got " + got);
+ }
+ } else {
+ t.fail("[" + file + "] gml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+
+ }
+
+ function test_writeNode_geometry(t) {
+ // we only care to write the 'pos' and 'posList' variants of GML 3 - conforming with simple features profile
+ var files = [
+ {path: "v3/point.xml"},
+ {path: "v3/linestring.xml"},
+ {path: "v3/curve.xml", options: {curve: true}},
+ {path: "v3/polygon.xml"},
+ {path: "v3/surface.xml", options: {surface: true}},
+ {path: "v3/multipoint-singular.xml"},
+ {path: "v3/multilinestring-singular.xml", options: {multiCurve: false}},
+ {path: "v3/multicurve-singular.xml"},
+ {path: "v3/multicurve-curve.xml", options: {curve: true}},
+ {path: "v3/multipolygon-singular.xml", options: {multiSurface: false}},
+ {path: "v3/multisurface-singular.xml"},
+ {path: "v3/multisurface-surface.xml", options: {surface: true}}
+ ];
+
+ var len = files.length;
+ t.plan(len);
+
+ var defaults = {
+ featureType: "feature",
+ featureNS: "http://example.com/feature",
+ srsName: "foo" // GML geometry collections require srsName, we only write if provided
+ };
+
+ var format, options, file, geom, doc, node;
+ for(var i=0; i<len; ++i) {
+ file = files[i].path;
+ geom = cases[file];
+ if(geom) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ options = OpenLayers.Util.extend({}, defaults);
+ if(files[i].options) {
+ OpenLayers.Util.extend(options, files[i].options);
+ }
+ format = new OpenLayers.Format.GML.v3(options);
+ node = format.writeNode("feature:_geometry", geom);
+ t.xml_eq(node.firstChild, doc.documentElement, "[" + file + "] geometry written");
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+ }
+
+ function test_writeNode_bounds(t) {
+ var files = [
+ "v3/envelope.xml"
+ ];
+
+ var len = files.length;
+ t.plan(len);
+
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "feature",
+ featureNS: "http://example.com/feature",
+ srsName: "foo" // GML envelopes require srsName, we only write if provided
+ });
+ var file, bounds, doc, node;
+ for(var i=0; i<len; ++i) {
+ file = files[i];
+ bounds = cases[file];
+ if(bounds) {
+ doc = readXML(file);
+ if(doc && doc.documentElement) {
+ node = format.writeNode("gml:Envelope", bounds);
+ t.xml_eq(node, doc.documentElement, "[" + file + "] bounds written");
+ } else {
+ t.fail("[" + file + "] xml parsing");
+ }
+ } else {
+ t.fail("[" + file + "] case not found");
+ }
+ }
+ }
+
+ function test_boundedBy(t) {
+ t.plan(5);
+
+ var doc = readXML("v3/topp-states-wfs.xml");
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom",
+ xy: false
+ });
+ var features = format.read(doc.documentElement);
+ var bounds = features[0].bounds;
+
+ t.ok(bounds instanceof OpenLayers.Bounds, "feature given a bounds");
+ t.eq(bounds.left.toFixed(2), "-91.52", "bounds left correct");
+ t.eq(bounds.bottom.toFixed(2), "36.99", "bounds bottom correct");
+ t.eq(bounds.right.toFixed(2), "-87.51", "bounds right correct");
+ t.eq(bounds.top.toFixed(2), "42.51", "bounds top correct");
+ }
+
+ function test_read(t) {
+ t.plan(8);
+ var doc = readXML("v3/topp-states-wfs.xml");
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom",
+ xy: false
+ });
+ var features = format.read(doc.documentElement);
+
+ t.eq(features.length, 3, "read 3 features");
+ var feature = features[0];
+ t.eq(feature.fid, "states.1", "read fid");
+ t.eq(feature.geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon",
+ "read multipolygon geometry");
+ var attributes = feature.attributes;
+ t.eq(attributes["STATE_NAME"], "Illinois", "read STATE_NAME");
+ t.eq(attributes["STATE_FIPS"], "17", "read STATE_FIPS");
+ t.eq(attributes["SUB_REGION"], "E N Cen", "read SUB_REGION");
+ t.eq(attributes["STATE_ABBR"], "IL", "read STATE_ABBR");
+ t.eq(attributes["LAND_KM"], "143986.61", "read LAND_KM");
+ }
+
+ function test_read_autoconfig(t) {
+ t.plan(7);
+ var doc = readXML("v3/topp-states-wfs.xml");
+ var format = new OpenLayers.Format.GML.v3();
+ var features = format.read(doc.documentElement);
+
+ t.eq(features.length, 3, "read 3 features");
+ var feature = features[0];
+ t.eq(feature.fid, "states.1", "read fid");
+ t.eq(feature.geometry.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon",
+ "read multipolygon geometry");
+ t.eq(format.featureType, "states", "featureType correctly auto-configured");
+ t.eq(format.featureNS, "http://www.openplans.org/topp", "featureNS correctly auto-configured");
+
+ t.eq(format.autoConfig, true, "autoConfig set to true");
+ format.autoConfig = false;
+ format.read(doc.documentElement);
+ t.eq(format.autoConfig, false, "now that featureNS is set, the format does not auto-configure again");
+ }
+
+ function test_emptyAttribute(t) {
+ t.plan(4);
+ var str =
+ '<gml:featureMembers xmlns:gml="http://www.opengis.net/gml">' +
+ '<topp:gnis_pop gml:id="gnis_pop.148604" xmlns:topp="http://www.openplans.org/topp">' +
+ '<gml:name>Aflu</gml:name>' +
+ '<topp:the_geom>' +
+ '<gml:Point srsName="urn:x-ogc:def:crs:EPSG:4326">' +
+ '<gml:pos>34.12 2.09</gml:pos>' +
+ '</gml:Point>' +
+ '</topp:the_geom>' +
+ '<topp:population>84683</topp:population>' +
+ '<topp:country>Algeria</topp:country>' +
+ '<topp:type>place</topp:type>' +
+ '<topp:name>Aflu</topp:name>' +
+ '<topp:empty></topp:empty>' +
+ '</topp:gnis_pop>' +
+ '</gml:featureMembers>';
+
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "gnis_pop",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom"
+ });
+
+ var features = format.read(str);
+ t.eq(features.length, 1, "read one feature");
+ var attr = features[0].attributes;
+ t.eq(attr.name, "Aflu", "correctly read attribute value");
+ t.eq(attr.foo, undefined, "bogus attribute is undefined");
+ t.eq(attr.empty, "", "empty attribute value is empty string");
+ }
+
+ function test_repeatedName(t) {
+ // test that if an attribute name matches the featureType, all goes well
+ t.plan(2);
+ var doc = readXML("v3/repeated-name.xml");
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "zoning",
+ featureNS: "http://opengeo.org/#medford",
+ geometryName: "the_geom",
+ xy: false
+ });
+ var features = format.read(doc.documentElement);
+
+ t.eq(features.length, 1, "read one feature");
+ var atts = features[0].attributes;
+ t.eq(atts.zoning, "I-L", "correct zoning attribute on zoning feature type");
+
+ }
+
+ function test_write(t) {
+ t.plan(1);
+ var doc = readXML("v3/topp-states-gml.xml");
+ var format = new OpenLayers.Format.GML.v3({
+ featureType: "states",
+ featureNS: "http://www.openplans.org/topp",
+ geometryName: "the_geom",
+ srsName: "urn:x-ogc:def:crs:EPSG:4326",
+ xy: false,
+ schemaLocation: "http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&version=1.1.0&request=DescribeFeatureType&typeName=topp:states http://www.opengis.net/gml http://schemas.opengis.net/gml/3.2.1/gml.xsd"
+ });
+ var features = format.read(doc.documentElement);
+
+ var got = format.write(features);
+ t.xml_eq(got, doc.documentElement, "gml:featureMembers round trip");
+ }
+
+ </script>
+</head>
+<body>
+<div id="v3/envelope.xml"><!--
+<gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lowerCorner>1 2</gml:lowerCorner>
+ <gml:upperCorner>3 4</gml:upperCorner>
+</gml:Envelope>
+--></div>
+<div id="v3/linearring.xml"><!--
+<gml:LinearRing xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+</gml:LinearRing>
+--></div>
+<div id="v3/linestring.xml"><!--
+<gml:LineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:posList>1 2 3 4</gml:posList>
+</gml:LineString>
+--></div>
+<div id="v3/linestring3d.xml"><!--
+<gml:LineString xmlns:gml="http://www.opengis.net/gml" srsName="foo" srsDimension="3">
+ <gml:posList>1 2 3 4 5 6</gml:posList>
+</gml:LineString>
+--></div>
+<div id="v3/curve.xml"><!--
+<gml:Curve xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:segments>
+ <gml:LineStringSegment>
+ <gml:posList>1 2 3 4</gml:posList>
+ </gml:LineStringSegment>
+ </gml:segments>
+</gml:Curve>
+--></div>
+<div id="v3/multilinestring-plural.xml"><!--
+<gml:MultiLineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lineStringMembers>
+ <gml:LineString>
+ <gml:posList>1 2 2 3</gml:posList>
+ </gml:LineString>
+ <gml:LineString>
+ <gml:posList>3 4 4 5</gml:posList>
+ </gml:LineString>
+ </gml:lineStringMembers>
+</gml:MultiLineString>
+--></div>
+<div id="v3/multilinestring-singular.xml"><!--
+<gml:MultiLineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:posList>1 2 2 3</gml:posList>
+ </gml:LineString>
+ </gml:lineStringMember>
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:posList>3 4 4 5</gml:posList>
+ </gml:LineString>
+ </gml:lineStringMember>
+</gml:MultiLineString>
+--></div>
+<div id="v3/multicurve-singular.xml"><!--
+<gml:MultiCurve xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:curveMember>
+ <gml:LineString>
+ <gml:posList>1 2 2 3</gml:posList>
+ </gml:LineString>
+ </gml:curveMember>
+ <gml:curveMember>
+ <gml:LineString>
+ <gml:posList>3 4 4 5</gml:posList>
+ </gml:LineString>
+ </gml:curveMember>
+</gml:MultiCurve>
+--></div>
+<div id="v3/multicurve-curve.xml"><!--
+<gml:MultiCurve xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:curveMember>
+ <gml:Curve>
+ <gml:segments>
+ <gml:LineStringSegment>
+ <gml:posList>1 2 2 3</gml:posList>
+ </gml:LineStringSegment>
+ </gml:segments>
+ </gml:Curve>
+ </gml:curveMember>
+ <gml:curveMember>
+ <gml:Curve>
+ <gml:segments>
+ <gml:LineStringSegment>
+ <gml:posList>3 4 4 5</gml:posList>
+ </gml:LineStringSegment>
+ </gml:segments>
+ </gml:Curve>
+ </gml:curveMember>
+</gml:MultiCurve>
+--></div>
+<div id="v3/multipoint-plural.xml"><!--
+<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pointMembers>
+ <gml:Point>
+ <gml:pos>1 2</gml:pos>
+ </gml:Point>
+ <gml:Point>
+ <gml:pos>2 3</gml:pos>
+ </gml:Point>
+ <gml:Point>
+ <gml:pos>3 4</gml:pos>
+ </gml:Point>
+ </gml:pointMembers>
+</gml:MultiPoint>
+--></div>
+<div id="v3/multipoint-singular.xml"><!--
+<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:pos>1 2</gml:pos>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:pos>2 3</gml:pos>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:pos>3 4</gml:pos>
+ </gml:Point>
+ </gml:pointMember>
+</gml:MultiPoint>
+--></div>
+<div id="v3/multipolygon-plural.xml"><!--
+<gml:MultiPolygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:polygonMembers>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ </gml:Polygon>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ </gml:Polygon>
+ </gml:polygonMembers>
+</gml:MultiPolygon>
+--></div>
+<div id="v3/multipolygon-singular.xml"><!--
+<gml:MultiPolygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ </gml:Polygon>
+ </gml:polygonMember>
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ </gml:Polygon>
+ </gml:polygonMember>
+</gml:MultiPolygon>
+--></div>
+<div id="v3/multisurface-plural.xml"><!--
+<gml:MultiSurface xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:surfaceMembers>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ </gml:Polygon>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ </gml:Polygon>
+ </gml:surfaceMembers>
+</gml:MultiSurface>
+--></div>
+<div id="v3/multisurface-singular.xml"><!--
+<gml:MultiSurface xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:surfaceMember>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ </gml:Polygon>
+ </gml:surfaceMember>
+ <gml:surfaceMember>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ </gml:Polygon>
+ </gml:surfaceMember>
+</gml:MultiSurface>
+--></div>
+<div id="v3/multisurface-surface.xml"><!--
+<gml:MultiSurface xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:surfaceMember>
+ <gml:Surface>
+ <gml:patches>
+ <gml:PolygonPatch interpolation="planar">
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ </gml:PolygonPatch>
+ </gml:patches>
+ </gml:Surface>
+ </gml:surfaceMember>
+ <gml:surfaceMember>
+ <gml:Surface>
+ <gml:patches>
+ <gml:PolygonPatch interpolation="planar">
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ </gml:PolygonPatch>
+ </gml:patches>
+ </gml:Surface>
+ </gml:surfaceMember>
+</gml:MultiSurface>
+--></div>
+<div id="v3/point.xml"><!--
+<gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pos>1 2</gml:pos>
+</gml:Point>
+--></div>
+<div id="v3/polygon.xml"><!--
+<gml:Polygon xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+</gml:Polygon>
+--></div>
+<div id="v3/surface.xml"><!--
+<gml:Surface xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:patches>
+ <gml:PolygonPatch interpolation="planar">
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>1 2 3 4 5 6 1 2</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>2 3 4 5 6 7 2 3</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ <gml:interior>
+ <gml:LinearRing>
+ <gml:posList>3 4 5 6 7 8 3 4</gml:posList>
+ </gml:LinearRing>
+ </gml:interior>
+ </gml:PolygonPatch>
+ </gml:patches>
+</gml:Surface>
+--></div>
+<div id="v3/topp-states-gml.xml"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<gml:featureMembers xsi:schemaLocation="http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/gml http://schemas.opengis.net/gml/3.2.1/gml.xsd" xmlns:topp="http://www.openplans.org/topp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml"><topp:states fid="states.1"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.5101 -88.0711 37.4761 -88.0871 37.4421 -88.3111 37.4091 -88.3591 37.4201 -88.4191 37.4001 -88.4671 37.2961 -88.5111 37.2571 -88.5011 37.2051 -88.4501 37.1561 -88.4221 37.0981 -88.4501 37.0721 -88.4761 37.0681 -88.4901 37.0641 -88.5171 37.0721 -88.5591 37.1091 -88.6141 37.1351 -88.6881 37.1411 -88.7391 37.1521 -88.7461 37.2021 -88.8631 37.2181 -88.9321 37.2201 -88.9931 37.1851 -89.0651 37.1121 -89.1161 37.0931 -89.1461 37.0641 -89.1691 37.0251 -89.1741 36.9981 -89.1501 36.9881 -89.1291 36.9861 -89.1931 37.0281 -89.2101 37.0411 -89.2371 37.0871 -89.2641 37.0911 -89.2841 37.0851 -89.3031 37.0601 -89.3091 37.0271 -89.2641 37.0081 -89.2621 36.9991 -89.2821 37.0091 -89.3101 37.0491 -89.3821 37.0991 -89.3791 37.1371 -89.4231 37.1651 -89.4401 37.2241 -89.4681 37.2531 -89.4651 37.2561 -89.4891 37.2761 -89.5131 37.3041 -89.5131 37.3291 -89.5001 37.3391 -89.4681 37.3551 -89.4351 37.4111 -89.4271 37.4531 -89.4531 37.4911 -89.4941 37.5711 -89.5241 37.6151 -89.5131 37.6501 -89.5191 37.6791 -89.5131 37.6941 -89.5211 37.7061 -89.5811 37.7451 -89.6661 37.7831 -89.6751 37.8041 -89.6911 37.8401 -89.7281 37.9051 -89.8511 37.9051 -89.8611 37.8911 -89.8661 37.8751 -89.9001 37.8781 -89.9371 37.9111 -89.9781 37.9631 -89.9581 37.9691 -90.0101 37.9931 -90.0411 38.0321 -90.1191 38.0531 -90.1341 38.0881 -90.2071 38.1221 -90.2541 38.1661 -90.2891 38.1881 -90.3361 38.2341 -90.3641 38.3231 -90.3691 38.3651 -90.3581 38.3901 -90.3391 38.4271 -90.3011 38.5181 -90.2651 38.5321 -90.2611 38.5621 -90.2401 38.6101 -90.1831 38.6581 -90.1831 38.7001 -90.2021 38.7231 -90.1961 38.7731 -90.1631 38.7851 -90.1351 38.8001 -90.1211 38.8301 -90.1131 38.8531 -90.1321 38.9141 -90.2431 38.9241 -90.2781 38.9241 -90.3191 38.9621 -90.4131 38.9591 -90.4691 38.8911 -90.5301 38.8711 -90.5701 38.8801 -90.6271 38.9351 -90.6681 39.0371 -90.7061 39.0581 -90.7071 39.0931 -90.6901 39.1441 -90.7161 39.1951 -90.7181 39.2241 -90.7321 39.2471 -90.7381 39.2961 -90.7791 39.3501 -90.8501 39.4001 -90.9471 39.4441 -91.0361 39.4731 -91.0641 39.5281 -91.0931 39.5521 -91.1561 39.6001 -91.2031 39.6851 -91.3171 39.7241 -91.3671 39.7611 -91.3731 39.8031 -91.3811 39.8631 -91.4491 39.8851 -91.4501 39.9011 -91.4341 39.9211 -91.4301 39.9461 -91.4471 40.0051 -91.4871 40.0661 -91.5041 40.1341 -91.5161 40.2001 -91.5061 40.2511 -91.4981 40.3091 -91.4861 40.3711 -91.4481 40.3861 -91.4181 40.3921 -91.3851 40.4021 -91.3721 40.4471 -91.3851 40.5031 -91.3741 40.5281 -91.3821 40.5471 -91.4121 40.5721 -91.4111 40.6031 -91.3751 40.6391 -91.2621 40.6431 -91.2141 40.6561 -91.1621 40.6821 -91.1291 40.7051 -91.1191 40.7611 -91.0921 40.8331 -91.0881 40.8791 -91.0491 40.9231 -90.9831 40.9501 -90.9601 41.0701 -90.9541 41.1041 -90.9571 41.1441 -90.9901 41.1651 -91.0181 41.1761 -91.0561 41.2311 -91.1011 41.2671 -91.1021 41.3341 -91.0731 41.4011 -91.0551 41.4231 -91.0271 41.4311 -91.0001 41.4211 -90.9491 41.4441 -90.8441 41.4491 -90.7791 41.4501 -90.7081 41.4621 -90.6581 41.5091 -90.6001 41.5251 -90.5401 41.5271 -90.4541 41.5431 -90.4341 41.5671 -90.4231 41.5861 -90.3481 41.6021 -90.3391 41.6491 -90.3411 41.7221 -90.3261 41.7561 -90.3041 41.7811 -90.2551 41.8061 -90.1951 41.9301 -90.1541 41.9831 -90.1421 42.0331 -90.1501 42.0611 -90.1681 42.1031 -90.1661 42.1201 -90.1761 42.1221 -90.1911 42.1591 -90.2301 42.1971 -90.3231 42.2101 -90.3671 42.2421 -90.4071 42.2631 -90.4171 42.3401 -90.4271 42.3601 -90.4411 42.3881 -90.4911 42.4211 -90.5631 42.4601 -90.6051 42.4751 -90.6481 42.4941 -90.6511 42.5091 -90.6381 42.5081 -90.4191 42.5041 -89.9231 42.5031 -89.8341 42.4971 -89.4001 42.4971 -89.3591 42.4901 -88.9391 42.4901 -88.7641 42.4891 -88.7061 42.4911 -88.2971 42.4891 -88.1941 42.4891 -87.7971 42.3141 -87.8361 42.1561 -87.7601 42.0591 -87.6701 41.8471 -87.6121 41.7231 -87.5291 41.4691 -87.5321 41.3011 -87.5321 41.1731 -87.5311 41.0091 -87.5321 40.7451 -87.5321 40.4941 -87.5371 40.4831 -87.5351 40.1661 -87.5351 39.8871 -87.5351 39.6091 -87.5351 39.4771 -87.5381 39.3501 -87.5401 39.3381 -87.5971 39.3071 -87.6251 39.2971 -87.6101 39.2811 -87.6151 39.2581 -87.6061 39.2481 -87.5841 39.2081 -87.5881 39.1981 -87.5941 39.1961 -87.6071 39.1681 -87.6441 39.1461 -87.6701 39.1301 -87.6591 39.1131 -87.6621 39.1031 -87.6311 39.0881 -87.6301 39.0841 -87.6121 39.0621 -87.5851 38.9951 -87.5811 38.9941 -87.5911 38.9771 -87.5471 38.9631 -87.5331 38.9311 -87.5301 38.9041 -87.5391 38.8691 -87.5591 38.8571 -87.5501 38.7951 -87.5071 38.7761 -87.5191 38.7691 -87.5081 38.7361 -87.5081 38.6851 -87.5431 38.6721 -87.5881 38.6421 -87.6251 38.6221 -87.6281 38.5991 -87.6191 38.5931 -87.6401 38.5731 -87.6521 38.5471 -87.6721 38.5151 -87.6511 38.5001 -87.6531 38.5041 -87.6791 38.4811 -87.6921 38.4661 -87.7561 38.4571 -87.7581 38.4451 -87.7381 38.4171 -87.7481 38.3781 -87.7841 38.3521 -87.8341 38.2861 -87.8501 38.2851 -87.8631 38.3161 -87.8741 38.3151 -87.8831 38.3001 -87.8881 38.2811 -87.9141 38.3021 -87.9131 38.3041 -87.9251 38.2411 -87.9801 38.2341 -87.9861 38.2001 -87.9771 38.1711 -87.9321 38.1571 -87.9311 38.1361 -87.9501 38.1311 -87.9731 38.1031 -88.0181 38.0921 -88.0121 38.0961 -87.9641 38.0731 -87.9751 38.0541 -88.0341 38.0451 -88.0431 38.0381 -88.0411 38.0331 -88.0211 38.0081 -88.0291 37.9751 -88.0211 37.9561 -88.0421 37.9341 -88.0411 37.9291 -88.0641 37.944 -88.0781 37.9231 -88.084 37.9171 -88.0301 37.9051 -88.0261 37.8961 -88.0441 37.9061 -88.1001 37.8951 -88.1011 37.8671 -88.0751 37.8431 -88.0341 37.8271 -88.0421 37.8311 -88.0891 37.8171 -88.0861 37.8051 -88.0351 37.7351 -88.0721 37.7001 -88.1331 37.6601 -88.1591 37.6281 -88.1571 37.5831 -88.1341 37.5101 -88.0711</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.1431E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states><topp:states fid="states.2"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.9661 -77.0081 38.8891 -76.9111 38.7881 -77.0451 38.8131 -77.0351 38.8291 -77.0451 38.8381 -77.0401 38.8621 -77.0391 38.8861 -77.0671 38.9151 -77.0781 38.9321 -77.1221 38.9931 -77.0421 38.9661 -77.0081</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>District of Columbia</topp:STATE_NAME><topp:STATE_FIPS>11</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DC</topp:STATE_ABBR><topp:LAND_KM>159.055</topp:LAND_KM><topp:WATER_KM>17.991</topp:WATER_KM><topp:PERSONS>606900.0</topp:PERSONS><topp:FAMILIES>122087.0</topp:FAMILIES><topp:HOUSHOLD>249634.0</topp:HOUSHOLD><topp:MALE>282970.0</topp:MALE><topp:FEMALE>323930.0</topp:FEMALE><topp:WORKERS>229975.0</topp:WORKERS><topp:DRVALONE>106694.0</topp:DRVALONE><topp:CARPOOL>36621.0</topp:CARPOOL><topp:PUBTRANS>111422.0</topp:PUBTRANS><topp:EMPLOYED>303994.0</topp:EMPLOYED><topp:UNEMPLOY>23442.0</topp:UNEMPLOY><topp:SERVICE>65498.0</topp:SERVICE><topp:MANUAL>22407.0</topp:MANUAL><topp:P_MALE>0.466</topp:P_MALE><topp:P_FEMALE>0.534</topp:P_FEMALE><topp:SAMP_POP>72696.0</topp:SAMP_POP></topp:states><topp:states fid="states.3"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.5571 -75.7071 38.6491 -75.7111 38.8301 -75.7241 39.1411 -75.7521 39.2471 -75.7611 39.2951 -75.7641 39.3831 -75.7721 39.7231 -75.7911 39.7241 -75.7751 39.7741 -75.7451 39.8201 -75.6951 39.8381 -75.6441 39.8401 -75.5831 39.8261 -75.4701 39.7981 -75.4201 39.7891 -75.4121 39.7781 -75.4281 39.7631 -75.4601 39.7411 -75.4751 39.7191 -75.4761 39.7141 -75.4891 39.6121 -75.6101 39.5661 -75.5621 39.4631 -75.5901 39.3661 -75.5151 39.2571 -75.4021 39.0731 -75.3971 39.0121 -75.3241 38.9451 -75.3071 38.8081 -75.1901 38.7991 -75.0831 38.4491 -75.0451 38.4491 -75.0681 38.4501 -75.0931 38.4551 -75.3501 38.4631 -75.6991 38.5571 -75.7071</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Delaware</topp:STATE_NAME><topp:STATE_FIPS>10</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DE</topp:STATE_ABBR><topp:LAND_KM>5062.456</topp:LAND_KM><topp:WATER_KM>1385.022</topp:WATER_KM><topp:PERSONS>666168.0</topp:PERSONS><topp:FAMILIES>175867.0</topp:FAMILIES><topp:HOUSHOLD>247497.0</topp:HOUSHOLD><topp:MALE>322968.0</topp:MALE><topp:FEMALE>343200.0</topp:FEMALE><topp:WORKERS>247566.0</topp:WORKERS><topp:DRVALONE>258087.0</topp:DRVALONE><topp:CARPOOL>42968.0</topp:CARPOOL><topp:PUBTRANS>8069.0</topp:PUBTRANS><topp:EMPLOYED>335147.0</topp:EMPLOYED><topp:UNEMPLOY>13945.0</topp:UNEMPLOY><topp:SERVICE>87973.0</topp:SERVICE><topp:MANUAL>44140.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>102776.0</topp:SAMP_POP></topp:states><topp:states fid="states.4"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.4801 -79.2311 38.4371 -79.2721 38.4121 -79.3171 38.4621 -79.4861 38.5531 -79.5361 38.5921 -79.6421 38.5501 -79.6691 38.5201 -79.6651 38.5001 -79.6921 38.4301 -79.6841 38.3941 -79.7201 38.3511 -79.7331 38.3531 -79.7641 38.3141 -79.8001 38.2981 -79.8031 38.2841 -79.7861 38.2681 -79.7931 38.2501 -79.8311 38.1791 -79.9161 38.1621 -79.9101 38.1211 -79.9351 38.1031 -79.9281 38.0671 -79.9571 38.0381 -79.9661 37.9891 -80.0001 37.9551 -80.0551 37.9141 -80.1061 37.8911 -80.1181 37.8771 -80.1601 37.8601 -80.1721 37.8421 -80.1711 37.8021 -80.2231 37.7781 -80.2201 37.7571 -80.2541 37.7251 -80.2501 37.6821 -80.3031 37.6711 -80.2951 37.6521 -80.3051 37.6401 -80.3011 37.6401 -80.2541 37.6241 -80.2191 37.5961 -80.2461 37.5661 -80.3161 37.5331 -80.3261 37.5281 -80.3081 37.5361 -80.2801 37.5111 -80.2881 37.4911 -80.3471 37.4751 -80.3521 37.4651 -80.3881 37.4341 -80.4251 37.4221 -80.4741 37.4331 -80.4871 37.4601 -80.4881 37.4741 -80.5081 37.4691 -80.5421 37.4451 -80.5971 37.3881 -80.7051 37.3921 -80.7291 37.3871 -80.7461 37.3781 -80.7471 37.3711 -80.7631 37.3861 -80.7701 37.3911 -80.7991 37.4121 -80.7991 37.4231 -80.8501 37.3881 -80.8771 37.3501 -80.8481 37.3391 -80.8551 37.3011 -80.9341 37.2911 -80.9681 37.2961 -80.9781 37.3061 -80.9861 37.2851 -81.0251 37.2741 -81.1401 37.2401 -81.2231 37.2931 -81.3121 37.3381 -81.3581 37.3111 -81.3911 37.2821 -81.4031 37.2541 -81.4751 37.2521 -81.4951 37.2341 -81.5051 37.2061 -81.5561 37.2041 -81.6661 37.2351 -81.7011 37.2501 -81.7381 37.2721 -81.7521 37.2871 -81.7921 37.2791 -81.8151 37.2851 -81.8391 37.3061 -81.8581 37.3251 -81.8631 37.3401 -81.8971 37.3711 -81.9261 37.4151 -81.9201 37.4661 -81.9881 37.4821 -81.9761 37.4921 -81.9481 37.5061 -81.9351 37.5311 -81.9591 37.5431 -81.9761 37.5301 -82.0261 37.5511 -82.0491 37.5251 -82.0551 37.5481 -82.0841 37.5571 -82.1421 37.5651 -82.1461 37.5691 -82.1371 37.5901 -82.1311 37.5931 -82.1591 37.6401 -82.1851 37.6231 -82.2051 37.6561 -82.2381 37.6681 -82.2951 37.7441 -82.3291 37.7581 -82.3191 37.7841 -82.3391 37.8111 -82.4051 37.8721 -82.4211 37.8941 -82.4371 37.9221 -82.5001 37.9421 -82.4931 37.9541 -82.4801 37.9751 -82.4751 38.0151 -82.5241 38.1091 -82.5931 38.1461 -82.6461 38.1691 -82.6471 38.1781 -82.6131 38.1931 -82.6061 38.2381 -82.6161 38.2451 -82.5891 38.2551 -82.5741 38.2921 -82.5801 38.3071 -82.5721 38.3681 -82.5981 38.4121 -82.5861 38.4031 -82.5751 38.4001 -82.5471 38.4051 -82.4951 38.4301 -82.4151 38.4281 -82.3941 38.4411 -82.3291 38.4651 -82.3141 38.5791 -82.2901 38.5941 -82.2711 38.5841 -82.2131 38.5941 -82.1841 38.6321 -82.1731 38.6771 -82.1891 38.7101 -82.1841 38.7781 -82.2161 38.8041 -82.1971 38.8381 -82.1461 38.8991 -82.1391 38.9521 -82.1011 38.9771 -82.0851 38.9881 -82.0581 39.0141 -82.0431 39.0151 -81.9991 38.9921 -81.9751 38.9911 -81.9371 38.9841 -81.9271 38.9321 -81.8981 38.8941 -81.9311 38.8841 -81.9151 38.8731 -81.8921 38.8851 -81.8661 38.9371 -81.8411 38.9481 -81.8231 38.9231 -81.7831 38.9301 -81.7621 38.9681 -81.7811 39.0161 -81.7751 39.0441 -81.8131 39.0661 -81.8241 39.0761 -81.8191 39.0771 -81.7861 39.0941 -81.7531 39.1251 -81.7441 39.1751 -81.7591 39.2131 -81.7231 39.2191 -81.6981 39.2601 -81.6891 39.2701 -81.6671 39.2651 -81.5721 39.3321 -81.5571 39.3521 -81.5401 39.4061 -81.4651 39.4101 -81.4481 39.4051 -81.4341 39.3451 -81.3761 39.3531 -81.3381 39.3861 -81.2841 39.3881 -81.2371 39.4081 -81.2251 39.4151 -81.2001 39.4371 -81.1801 39.4671 -81.1171 39.4961 -81.0981 39.5321 -81.0371 39.5441 -81.0321 39.5811 -80.9831 39.6061 -80.9321 39.6071 -80.9121 39.6241 -80.8811 39.6621 -80.8721 39.6801 -80.8631 39.7031 -80.8321 39.7181 -80.8321 39.7361 -80.8561 39.7591 -80.8701 39.8081 -80.8191 39.8391 -80.8261 39.8561 -80.7981 39.8721 -80.7911 39.9041 -80.8121 39.9151 -80.8081 39.9191 -80.7961 39.9131 -80.7681 39.9211 -80.7591 39.9461 -80.7631 39.9831 -80.7391 40.0351 -80.7381 40.1541 -80.7021 40.1681 -80.7011 40.1941 -80.6781 40.2451 -80.6501 40.2761 -80.6141 40.3061 -80.6041 40.3731 -80.6091 40.3881 -80.6291 40.3981 -80.6281 40.4801 -80.6021 40.5041 -80.6251 40.5391 -80.6331 40.5681 -80.6681 40.5821 -80.6671 40.6131 -80.6371 40.6191 -80.6111 40.6151 -80.5741 40.6371 -80.5221 40.4781 -80.5241 40.4021 -80.5231 40.1621 -80.5261 40.0221 -80.5251 39.9581 -80.5241 39.7211 -80.5241 39.7191 -80.4291 39.7211 -79.9181 39.7211 -79.7651 39.7201 -79.4811 39.1971 -79.4901 39.2131 -79.4611 39.2111 -79.4491 39.2691 -79.3851 39.2911 -79.3461 39.3001 -79.2951 39.3251 -79.2801 39.3481 -79.2601 39.3931 -79.1631 39.4131 -79.1581 39.4161 -79.1311 39.4471 -79.1041 39.4641 -79.0961 39.4701 -79.1041 39.4701 -79.0701 39.4851 -79.0641 39.4831 -79.0491 39.4381 -78.9701 39.4601 -78.9551 39.5251 -78.8711 39.5631 -78.8381 39.5661 -78.8061 39.5851 -78.8221 39.6151 -78.7981 39.6301 -78.7981 39.6441 -78.7721 39.6261 -78.7671 39.6261 -78.7321 39.6211 -78.7301 39.6081 -78.7361 39.6011 -78.7741 39.5811 -78.7611 39.5761 -78.7321 39.5591 -78.7161 39.5361 -78.6661 39.5371 -78.6491 39.5291 -78.6371 39.5351 -78.6041 39.5201 -78.5641 39.5251 -78.5091 39.5191 -78.4811 39.5331 -78.4561 39.5481 -78.4461 39.5491 -78.4211 39.5801 -78.4621 39.5921 -78.4501 39.5871 -78.4041 39.6201 -78.4321 39.6141 -78.3841 39.6311 -78.3771 39.6321 -78.3571 39.6401 -78.3481 39.6181 -78.2731 39.6411 -78.2571 39.6581 -78.2291 39.6731 -78.2271 39.6751 -78.2041 39.6941 -78.1831 39.6751 -78.0941 39.6221 -78.0261 39.5981 -77.9951 39.6111 -77.9641 39.5851 -77.9451 39.5911 -77.9351 39.6141 -77.9471 39.6181 -77.9381 39.5961 -77.9031 39.6001 -77.8911 39.6161 -77.8881 39.6021 -77.8551 39.6051 -77.8421 39.5721 -77.8401 39.5651 -77.8531 39.5641 -77.8851 39.5571 -77.8901 39.5451 -77.8691 39.5141 -77.8641 39.5311 -77.8441 39.5251 -77.8351 39.5291 -77.8291 39.5111 -77.8251 39.5011 -77.8481 39.4931 -77.8251 39.4981 -77.7711 39.4801 -77.7991 39.4591 -77.7851 39.4631 -77.8041 39.4501 -77.7961 39.4391 -77.8041 39.4321 -77.8021 39.4251 -77.7571 39.4031 -77.7411 39.3961 -77.7371 39.3781 -77.7561 39.3601 -77.7451 39.3381 -77.7541 39.3261 -77.7501 39.3171 -77.7271 39.2841 -77.7591 39.2461 -77.7681 39.1961 -77.8051 39.1411 -77.8201 39.1321 -77.8301 39.2651 -78.0331 39.3911 -78.2291 39.4231 -78.2771 39.4561 -78.3471 39.3801 -78.3501 39.3611 -78.3651 39.3501 -78.3441 39.3411 -78.3411 39.2571 -78.4131 39.2441 -78.3991 39.2121 -78.4231 39.1971 -78.4241 39.1701 -78.4021 39.1481 -78.4301 39.1181 -78.4481 39.1111 -78.4851 39.0931 -78.5011 39.0571 -78.5361 39.0351 -78.5641 39.0231 -78.5491 39.0131 -78.5531 38.9671 -78.5981 38.9791 -78.6311 38.9501 -78.6471 38.9211 -78.6801 38.9041 -78.7191 38.9301 -78.7241 38.9291 -78.7371 38.9111 -78.7491 38.8801 -78.7931 38.8331 -78.8161 38.7631 -78.8661 38.8461 -78.9871 38.7991 -79.0331 38.7901 -79.0551 38.7611 -79.0561 38.7071 -79.0871 38.6591 -79.0881 38.6631 -79.1211 38.6581 -79.1271 38.4801 -79.2311</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>West Virginia</topp:STATE_NAME><topp:STATE_FIPS>54</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>WV</topp:STATE_ABBR><topp:LAND_KM>62384.2</topp:LAND_KM><topp:WATER_KM>375.199</topp:WATER_KM><topp:PERSONS>1793477.0</topp:PERSONS><topp:FAMILIES>500259.0</topp:FAMILIES><topp:HOUSHOLD>688557.0</topp:HOUSHOLD><topp:MALE>861536.0</topp:MALE><topp:FEMALE>931941.0</topp:FEMALE><topp:WORKERS>661702.0</topp:WORKERS><topp:DRVALONE>493164.0</topp:DRVALONE><topp:CARPOOL>106918.0</topp:CARPOOL><topp:PUBTRANS>7237.0</topp:PUBTRANS><topp:EMPLOYED>671085.0</topp:EMPLOYED><topp:UNEMPLOY>71142.0</topp:UNEMPLOY><topp:SERVICE>205950.0</topp:SERVICE><topp:MANUAL>124172.0</topp:MANUAL><topp:P_MALE>0.48</topp:P_MALE><topp:P_FEMALE>0.52</topp:P_FEMALE><topp:SAMP_POP>317564.0</topp:SAMP_POP></topp:states><topp:states fid="states.5"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.6491 -75.7111 38.5571 -75.7071 38.4631 -75.6991 38.4551 -75.3501 38.4501 -75.0931 38.3691 -75.1551 38.2731 -75.1501 38.2011 -75.2621 38.0681 -75.3731 38.0161 -75.3721 37.9961 -75.6261 37.9701 -75.6481 37.9791 -75.8651 38.0971 -75.7691 38.1741 -75.8971 38.2311 -75.8381 38.2401 -75.8611 38.2631 -75.7941 38.2581 -75.8941 38.3571 -75.8721 38.3751 -75.8861 38.2821 -75.9491 38.2821 -75.9951 38.3211 -76.0201 38.2581 -76.0651 38.4361 -76.2941 38.4781 -76.2911 38.5431 -76.1921 38.5951 -76.2511 38.5711 -76.0311 38.6221 -76.0281 38.5911 -76.0461 38.6101 -76.0751 38.7071 -76.1241 38.7091 -76.1741 38.7621 -76.2231 38.7691 -76.2671 38.6791 -76.3371 38.6991 -76.3501 38.834 -76.2721 38.7651 -76.1951 38.7881 -76.1651 38.8851 -76.1141 38.8891 -76.0751 38.8981 -76.1021 38.9481 -76.0951 38.9201 -76.1131 38.9731 -76.1991 39.1181 -76.1111 39.0921 -76.2211 39.1301 -76.2381 39.2041 -76.2181 39.3211 -76.1121 39.3581 -76.0371 39.3791 -75.8491 39.3941 -75.9781 39.4711 -75.9521 39.5241 -75.9741 39.5691 -76.0311 39.5421 -76.0781 39.4011 -76.1541 39.3741 -76.2261 39.3931 -76.3641 39.2311 -76.3991 39.2421 -76.5311 39.2591 -76.6041 39.2311 -76.5651 39.1981 -76.5761 39.1801 -76.6071 39.1581 -76.5951 39.1961 -76.5631 39.1181 -76.4231 38.9081 -76.4721 38.7581 -76.5491 38.7091 -76.5251 38.5221 -76.5081 38.3911 -76.3851 38.3461 -76.4051 38.3201 -76.4211 38.3351 -76.4711 38.4101 -76.5201 38.4501 -76.6471 38.2131 -76.3431 38.0451 -76.3301 38.2221 -76.5771 38.2341 -76.7601 38.3911 -76.8641 38.2991 -76.9081 38.3311 -76.9731 38.4261 -77.0021 38.3901 -77.2201 38.4131 -77.2551 38.4871 -77.2771 38.6481 -77.1291 38.6771 -77.1251 38.7031 -77.0931 38.7151 -77.0811 38.7121 -77.0571 38.7181 -77.0461 38.7881 -77.0451 38.8891 -76.9111 38.9661 -77.0081 38.9931 -77.0421 38.9321 -77.1221 38.9641 -77.1521 38.9751 -77.2431 39.0271 -77.2551 39.0621 -77.3241 39.0681 -77.3461 39.0661 -77.4331 39.0801 -77.4591 39.1031 -77.4791 39.1161 -77.5131 39.1571 -77.5161 39.1761 -77.4781 39.2181 -77.4611 39.2291 -77.4641 39.2491 -77.4941 39.2681 -77.5421 39.2981 -77.5681 39.2991 -77.6161 39.3181 -77.6791 39.3171 -77.7271 39.3261 -77.7501 39.3381 -77.7541 39.3601 -77.7451 39.3781 -77.7561 39.3961 -77.7371 39.4031 -77.7411 39.4251 -77.7571 39.4321 -77.8021 39.4391 -77.8041 39.4501 -77.7961 39.4631 -77.8041 39.4591 -77.7851 39.4801 -77.7991 39.4981 -77.7711 39.4931 -77.8251 39.5011 -77.8481 39.5111 -77.8251 39.5291 -77.8291 39.5251 -77.8351 39.5311 -77.8441 39.5141 -77.8641 39.5451 -77.8691 39.5571 -77.8901 39.5641 -77.8851 39.5651 -77.8531 39.5721 -77.8401 39.6051 -77.8421 39.6021 -77.8551 39.6161 -77.8881 39.6001 -77.8911 39.5961 -77.9031 39.6181 -77.9381 39.6141 -77.9471 39.5911 -77.9351 39.5851 -77.9451 39.6111 -77.9641 39.5981 -77.9951 39.6221 -78.0261 39.6751 -78.0941 39.6941 -78.1831 39.6751 -78.2041 39.6731 -78.2271 39.6581 -78.2291 39.6411 -78.2571 39.6181 -78.2731 39.6401 -78.3481 39.6321 -78.3571 39.6311 -78.3771 39.6141 -78.3841 39.6201 -78.4321 39.5871 -78.4041 39.5921 -78.4501 39.5801 -78.4621 39.5491 -78.4211 39.5481 -78.4461 39.5331 -78.4561 39.5191 -78.4811 39.5251 -78.5091 39.5201 -78.5641 39.5351 -78.6041 39.5291 -78.6371 39.5371 -78.6491 39.5361 -78.6661 39.5591 -78.7161 39.5761 -78.7321 39.5811 -78.7611 39.6011 -78.7741 39.6081 -78.7361 39.6211 -78.7301 39.6261 -78.7321 39.6261 -78.7671 39.6441 -78.7721 39.6301 -78.7981 39.6151 -78.7981 39.5851 -78.8221 39.5661 -78.8061 39.5631 -78.8381 39.5251 -78.8711 39.4601 -78.9551 39.4381 -78.9701 39.4831 -79.0491 39.4851 -79.0641 39.4701 -79.0701 39.4701 -79.1041 39.4641 -79.0961 39.4471 -79.1041 39.4161 -79.1311 39.4131 -79.1581 39.3931 -79.1631 39.3481 -79.2601 39.3251 -79.2801 39.3001 -79.2951 39.2911 -79.3461 39.2691 -79.3851 39.2111 -79.4491 39.2131 -79.4611 39.1971 -79.4901 39.7201 -79.4811 39.7191 -79.3961 39.7221 -78.9301 39.7231 -78.8181 39.7231 -78.3851 39.7241 -78.3341 39.7251 -78.0961 39.7191 -77.4761 39.7191 -77.4641 39.7201 -77.2211 39.7201 -76.9971 39.7211 -76.7901 39.7201 -76.5701 39.7211 -76.2331 39.7221 -76.1391 39.7231 -75.7911 39.3831 -75.7721 39.2951 -75.7641 39.2471 -75.7611 39.1411 -75.7521 38.8301 -75.7241 38.6491 -75.7111</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.9071 -76.2931 38.9671 -76.2941 38.9561 -76.3391 38.9411 -76.3141 38.9121 -76.3221 38.9241 -76.3421 38.8751 -76.3291 38.8541 -76.3751 38.9581 -76.3561 39.0401 -76.2991 38.9781 -76.2481 38.9231 -76.2461 38.9491 -76.2731 38.9071 -76.2931</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.4491 -75.0681 38.4491 -75.0451 38.3221 -75.0871 38.4491 -75.0681</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.0271 -75.2701 38.0371 -75.2441 38.0941 -75.2091 38.2041 -75.1641 38.3201 -75.0941 38.1241 -75.1731 38.0281 -75.2421 38.0271 -75.2701</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Maryland</topp:STATE_NAME><topp:STATE_FIPS>24</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>MD</topp:STATE_ABBR><topp:LAND_KM>25316.345</topp:LAND_KM><topp:WATER_KM>6188.794</topp:WATER_KM><topp:PERSONS>4781468.0</topp:PERSONS><topp:FAMILIES>1245814.0</topp:FAMILIES><topp:HOUSHOLD>1748991.0</topp:HOUSHOLD><topp:MALE>2318671.0</topp:MALE><topp:FEMALE>2462797.0</topp:FEMALE><topp:WORKERS>1783061.0</topp:WORKERS><topp:DRVALONE>1732837.0</topp:DRVALONE><topp:CARPOOL>376449.0</topp:CARPOOL><topp:PUBTRANS>202169.0</topp:PUBTRANS><topp:EMPLOYED>2481342.0</topp:EMPLOYED><topp:UNEMPLOY>111536.0</topp:UNEMPLOY><topp:SERVICE>586994.0</topp:SERVICE><topp:MANUAL>260308.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>684773.0</topp:SAMP_POP></topp:states><topp:states fid="states.6"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.6411 -102.0431 37.3861 -102.0411 36.9881 -102.0361 36.9981 -102.9971 36.9991 -103.0771 36.9941 -103.9931 36.9931 -105.1451 36.9921 -105.2121 36.9941 -105.7121 36.9921 -105.9911 36.9911 -106.4711 36.9891 -106.8601 36.9991 -106.8891 36.9971 -107.4101 36.9981 -107.4711 36.9991 -108.3711 36.9961 -109.0471 37.6301 -109.0441 37.8871 -109.0421 38.1521 -109.0421 38.2441 -109.0551 38.4941 -109.0531 39.3601 -109.0501 39.5181 -109.0521 39.6571 -109.0511 40.2101 -109.0501 40.6651 -109.0451 40.9981 -109.0471 41.0031 -107.9181 41.0001 -107.3031 40.9981 -106.8641 41.0011 -106.3281 41.0001 -106.2021 40.9961 -105.2781 40.9941 -104.9331 41.0031 -104.0511 40.9991 -103.5711 41.0001 -103.3821 40.9981 -102.6511 41.0001 -102.6201 40.9981 -102.0471 40.7431 -102.0461 40.6971 -102.0451 40.4311 -102.0471 40.3421 -102.0471 39.9981 -102.0511 39.5681 -102.0481 39.5621 -102.0481 39.1261 -102.0471 39.0361 -102.0481 38.6921 -102.0471 38.6151 -102.0471 38.2631 -102.0451 38.2531 -102.0451 37.7341 -102.0431 37.6411 -102.0431</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Colorado</topp:STATE_NAME><topp:STATE_FIPS>08</topp:STATE_FIPS><topp:SUB_REGION>Mtn</topp:SUB_REGION><topp:STATE_ABBR>CO</topp:STATE_ABBR><topp:LAND_KM>268659.501</topp:LAND_KM><topp:WATER_KM>960.364</topp:WATER_KM><topp:PERSONS>3294394.0</topp:PERSONS><topp:FAMILIES>854214.0</topp:FAMILIES><topp:HOUSHOLD>1282489.0</topp:HOUSHOLD><topp:MALE>1631295.0</topp:MALE><topp:FEMALE>1663099.0</topp:FEMALE><topp:WORKERS>1233023.0</topp:WORKERS><topp:DRVALONE>1216639.0</topp:DRVALONE><topp:CARPOOL>210274.0</topp:CARPOOL><topp:PUBTRANS>46983.0</topp:PUBTRANS><topp:EMPLOYED>1633281.0</topp:EMPLOYED><topp:UNEMPLOY>99438.0</topp:UNEMPLOY><topp:SERVICE>421079.0</topp:SERVICE><topp:MANUAL>181760.0</topp:MANUAL><topp:P_MALE>0.495</topp:P_MALE><topp:P_FEMALE>0.505</topp:P_FEMALE><topp:SAMP_POP>512677.0</topp:SAMP_POP></topp:states><topp:states fid="states.7"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.6551 -86.5101 36.6521 -86.7701 36.6501 -87.0681 36.6511 -87.1121 36.6491 -87.3461 36.6451 -87.6401 36.6441 -87.6931 36.6411 -87.8531 36.6691 -87.8701 36.6791 -88.0711 36.5821 -88.0411 36.5381 -88.0351 36.4961 -88.0421 36.4981 -88.4951 36.4991 -88.5121 36.4981 -88.8101 36.4991 -88.8261 36.4991 -88.8301 36.5021 -89.3461 36.5021 -89.4141 36.5101 -89.4181 36.6161 -89.3731 36.6251 -89.3631 36.6281 -89.3421 36.6221 -89.3221 36.5751 -89.2831 36.5691 -89.2411 36.5811 -89.2101 36.6311 -89.2001 36.6531 -89.1771 36.6711 -89.1671 36.7131 -89.1971 36.7271 -89.1961 36.7601 -89.1771 36.7591 -89.1511 36.7681 -89.1251 36.7921 -89.1251 36.8041 -89.1641 36.8291 -89.1731 36.8431 -89.1661 36.8661 -89.1291 36.9531 -89.1041 36.9771 -89.1071 36.9881 -89.1291 36.9981 -89.1501 37.0251 -89.1741 37.0641 -89.1691 37.0931 -89.1461 37.1121 -89.1161 37.1851 -89.0651 37.2201 -88.9931 37.2181 -88.9321 37.2021 -88.8631 37.1521 -88.7461 37.1411 -88.7391 37.1351 -88.6881 37.1091 -88.6141 37.0721 -88.5591 37.0641 -88.5171 37.0681 -88.4901 37.0721 -88.4761 37.0981 -88.4501 37.1561 -88.4221 37.2051 -88.4501 37.2571 -88.5011 37.2961 -88.5111 37.4001 -88.4671 37.4201 -88.4191 37.4091 -88.3591 37.4421 -88.3111 37.4761 -88.0871 37.5101 -88.0711 37.5831 -88.1341 37.6281 -88.1571 37.6601 -88.1591 37.7001 -88.1331 37.7351 -88.0721 37.8051 -88.0351 37.8011 -88.0111 37.7761 -87.9581 37.7991 -87.9391 37.8091 -87.9201 37.8381 -87.9101 37.8751 -87.9361 37.9041 -87.9341 37.9191 -87.9211 37.9241 -87.8991 37.8901 -87.8571 37.8781 -87.8231 37.8981 -87.7531 37.8941 -87.7281 37.8991 -87.7091 37.8971 -87.6791 37.8361 -87.6841 37.8281 -87.6511 37.8431 -87.6071 37.8641 -87.5931 37.8901 -87.5941 37.9231 -87.6271 37.9711 -87.6041 37.9151 -87.5041 37.9361 -87.4521 37.9341 -87.3871 37.8931 -87.3101 37.8701 -87.2721 37.8491 -87.2261 37.8381 -87.1751 37.8261 -87.1581 37.7891 -87.1311 37.7841 -87.1061 37.8071 -87.0711 37.9071 -87.0361 37.9241 -87.0131 37.9301 -86.9891 37.9371 -86.9311 37.9531 -86.9001 37.9861 -86.8631 37.9911 -86.8261 37.9781 -86.8021 37.8981 -86.7531 37.8941 -86.7281 37.9111 -86.6891 37.9131 -86.6681 37.9021 -86.6601 37.8601 -86.6701 37.8471 -86.6651 37.8451 -86.6451 37.8571 -86.6141 37.9211 -86.5981 37.9251 -86.5811 37.9211 -86.5411 37.9271 -86.5221 37.9421 -86.5161 37.9871 -86.5301 38.0181 -86.5271 38.0461 -86.5191 38.0511 -86.5031 38.0591 -86.4581 38.0751 -86.4421 38.0881 -86.4421 38.1111 -86.4741 38.1291 -86.4641 38.1291 -86.4521 38.1081 -86.4071 38.1231 -86.3931 38.1341 -86.3441 38.1431 -86.3351 38.1551 -86.3431 38.1671 -86.3871 38.1941 -86.3881 38.1931 -86.3641 38.1771 -86.3411 38.1501 -86.2971 38.0781 -86.2911 38.0581 -86.2771 38.0401 -86.2521 38.0171 -86.1901 38.0111 -86.1051 37.9661 -86.0521 37.9921 -86.0311 38.0011 -86.0061 38.0111 -85.9581 38.0331 -85.9301 38.0641 -85.9141 38.1791 -85.9121 38.2381 -85.8521 38.2761 -85.8391 38.2861 -85.8061 38.2821 -85.7861 38.2701 -85.7461 38.3001 -85.6811 38.3371 -85.6541 38.3831 -85.6431 38.4461 -85.6121 38.4711 -85.5071 38.5181 -85.4661 38.5361 -85.4321 38.5611 -85.4171 38.5841 -85.4241 38.6941 -85.4531 38.7241 -85.4461 38.7381 -85.4181 38.7361 -85.3351 38.7441 -85.2711 38.6951 -85.2051 38.6951 -85.1601 38.7141 -85.1191 38.7501 -85.0681 38.7641 -85.0251 38.7801 -84.9751 38.7931 -84.8181 38.8341 -84.8241 38.8661 -84.7871 38.8841 -84.7881 38.8971 -84.8031 38.9011 -84.8591 38.9091 -84.8751 38.9271 -84.8751 38.9541 -84.8461 38.9821 -84.8341 39.0051 -84.8441 39.0321 -84.8761 39.0501 -84.8901 39.0641 -84.8861 39.1031 -84.8271 39.1021 -84.8111 39.1061 -84.7891 39.1421 -84.7421 39.0891 -84.6671 39.0741 -84.6221 39.0701 -84.5931 39.0941 -84.5151 39.1071 -84.4921 39.1111 -84.4441 39.0841 -84.4251 39.0471 -84.4191 39.0351 -84.3911 39.0371 -84.3451 39.0141 -84.3131 38.9441 -84.2901 38.9171 -84.2611 38.8741 -84.2351 38.8121 -84.2281 38.7881 -84.1761 38.7651 -84.0881 38.7631 -84.0531 38.7771 -83.9621 38.7571 -83.9121 38.7441 -83.8571 38.7111 -83.8371 38.6931 -83.7901 38.6501 -83.7701 38.6351 -83.7121 38.6201 -83.6781 38.6231 -83.6551 38.6351 -83.6431 38.6641 -83.6331 38.6771 -83.6181 38.6961 -83.5261 38.6901 -83.5001 38.6631 -83.4531 38.6541 -83.3711 38.6311 -83.3301 38.6061 -83.3201 38.5961 -83.3061 38.5961 -83.2901 38.6091 -83.2721 38.6241 -83.2451 38.6091 -83.1821 38.6191 -83.1431 38.6641 -83.1111 38.6851 -83.0601 38.7141 -83.0271 38.7191 -82.9721 38.7461 -82.9211 38.7421 -82.8901 38.7181 -82.8731 38.6831 -82.8801 38.6521 -82.8601 38.6001 -82.8531 38.5711 -82.8271 38.5571 -82.8021 38.5521 -82.7421 38.5391 -82.6951 38.5021 -82.6691 38.4721 -82.6131 38.4121 -82.5861 38.3681 -82.5981 38.3071 -82.5721 38.2921 -82.5801 38.2551 -82.5741 38.2451 -82.5891 38.2381 -82.6161 38.1931 -82.6061 38.1781 -82.6131 38.1691 -82.6471 38.1461 -82.6461 38.1091 -82.5931 38.0151 -82.5241 37.9751 -82.4751 37.9541 -82.4801 37.9421 -82.4931 37.9221 -82.5001 37.8941 -82.4371 37.8721 -82.4211 37.8111 -82.4051 37.7841 -82.3391 37.7581 -82.3191 37.7441 -82.3291 37.6681 -82.2951 37.6561 -82.2381 37.6231 -82.2051 37.6401 -82.1851 37.5931 -82.1591 37.5901 -82.1311 37.5691 -82.1371 37.5651 -82.1461 37.5571 -82.1421 37.5481 -82.0841 37.5251 -82.0551 37.5511 -82.0491 37.5301 -82.0261 37.5431 -81.9761 37.5311 -81.9591 37.3041 -82.2891 37.2601 -82.3531 37.2501 -82.4061 37.1991 -82.5501 37.1931 -82.5681 37.1091 -82.7191 37.0931 -82.7211 37.0751 -82.7091 37.0651 -82.7201 37.0331 -82.7231 37.0051 -82.8121 36.9741 -82.8661 36.9321 -82.8601 36.8931 -82.8781 36.8631 -82.9501 36.8581 -83.0461 36.8501 -83.0681 36.7791 -83.1281 36.7511 -83.1241 36.7391 -83.1381 36.7341 -83.2031 36.7091 -83.3211 36.6881 -83.3851 36.6721 -83.4041 36.6611 -83.4601 36.6611 -83.5301 36.6161 -83.6461 36.5981 -83.6751 36.5841 -83.6951 36.5911 -83.9351 36.5921 -84.0061 36.5951 -84.2541 36.5951 -84.2561 36.6051 -84.7811 36.6051 -84.7911 36.6201 -84.9981 36.6251 -85.2721 36.6261 -85.3001 36.6181 -85.4371 36.6261 -85.7851 36.6331 -85.9801 36.6431 -86.1991 36.6501 -86.4151 36.6551 -86.5101</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.4981 -89.5331 36.5181 -89.5661 36.5411 -89.5681 36.5571 -89.5561 36.5641 -89.5301 36.5591 -89.4931 36.5471 -89.4811 36.5251 -89.4711 36.5041 -89.4811 36.4981 -89.4751 36.4981 -89.5331</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Kentucky</topp:STATE_NAME><topp:STATE_FIPS>21</topp:STATE_FIPS><topp:SUB_REGION>E S Cen</topp:SUB_REGION><topp:STATE_ABBR>KY</topp:STATE_ABBR><topp:LAND_KM>103961.904</topp:LAND_KM><topp:WATER_KM>1772.542</topp:WATER_KM><topp:PERSONS>4551524.0</topp:PERSONS><topp:FAMILIES>1237346.0</topp:FAMILIES><topp:HOUSHOLD>1718663.0</topp:HOUSHOLD><topp:MALE>2195130.0</topp:MALE><topp:FEMALE>2356394.0</topp:FEMALE><topp:WORKERS>1656590.0</topp:WORKERS><topp:DRVALONE>1502949.0</topp:DRVALONE><topp:CARPOOL>273091.0</topp:CARPOOL><topp:PUBTRANS>48158.0</topp:PUBTRANS><topp:EMPLOYED>1970934.0</topp:EMPLOYED><topp:UNEMPLOY>148125.0</topp:UNEMPLOY><topp:SERVICE>556744.0</topp:SERVICE><topp:MANUAL>361621.0</topp:MANUAL><topp:P_MALE>0.482</topp:P_MALE><topp:P_FEMALE>0.518</topp:P_FEMALE><topp:SAMP_POP>646517.0</topp:SAMP_POP></topp:states><topp:states fid="states.8"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.0011 -95.0711 37.0001 -95.4061 37.0001 -95.5251 36.9981 -95.7851 37.0001 -95.9571 36.9981 -96.0051 37.0001 -96.5181 37.0001 -96.7481 36.9991 -97.1371 36.9961 -97.4651 36.9981 -97.8031 36.9981 -98.1041 36.9991 -98.3461 36.9981 -98.5391 36.9981 -98.9991 36.9941 -99.4371 36.9951 -99.5441 36.9951 -99.9981 36.9971 -100.0881 36.9971 -100.6331 36.9961 -100.9501 36.9971 -101.0711 36.9961 -101.5531 36.9881 -102.0241 36.9881 -102.0361 37.3861 -102.0411 37.6411 -102.0431 37.7341 -102.0431 38.2531 -102.0451 38.2631 -102.0451 38.6151 -102.0471 38.6921 -102.0471 39.0361 -102.0481 39.1261 -102.0471 39.5621 -102.0481 39.5681 -102.0481 39.9981 -102.0511 40.0011 -101.4061 40.0011 -101.3211 40.0001 -100.7541 39.9991 -100.7341 40.0001 -100.1901 40.0001 -100.1801 40.0021 -99.6271 39.9991 -99.1771 39.9981 -99.0641 39.9981 -98.7201 39.9971 -98.5041 39.9981 -98.2631 39.9981 -97.9291 39.9991 -97.8161 39.9971 -97.3611 39.9961 -96.9071 39.9941 -96.8011 39.9941 -96.4531 39.9941 -96.2401 39.9951 -96.0001 39.9931 -95.7801 39.9921 -95.3291 39.9991 -95.3081 39.9421 -95.2401 39.9381 -95.2071 39.9101 -95.1931 39.9081 -95.1501 39.8691 -95.1001 39.8661 -95.0621 39.8771 -95.0331 39.8961 -95.0211 39.9001 -94.9641 39.8961 -94.9371 39.8491 -94.9361 39.8331 -94.9231 39.8281 -94.8981 39.8171 -94.8881 39.7931 -94.8991 39.7821 -94.9331 39.7751 -94.9341 39.7571 -94.9211 39.7601 -94.8761 39.7541 -94.8701 39.7391 -94.8771 39.7261 -94.9051 39.7271 -94.9301 39.7361 -94.9521 39.7321 -94.9611 39.6841 -94.9781 39.6611 -95.0281 39.6251 -95.0551 39.5861 -95.0531 39.5601 -95.1081 39.5321 -95.1011 39.4851 -95.0471 39.4621 -95.0401 39.4391 -94.9851 39.4111 -94.9581 39.3811 -94.9251 39.3801 -94.8981 39.3401 -94.9111 39.3231 -94.9071 39.2861 -94.8801 39.2611 -94.8331 39.2111 -94.8201 39.1961 -94.7891 39.1711 -94.7301 39.1741 -94.6751 39.1581 -94.6461 39.1511 -94.6121 39.1411 -94.6001 39.1121 -94.6071 39.0441 -94.6091 38.8371 -94.6121 38.7371 -94.6121 38.4711 -94.6181 38.3921 -94.6181 38.0551 -94.6171 38.0301 -94.6161 37.6791 -94.6191 37.6501 -94.6181 37.3601 -94.6181 37.3271 -94.6181 37.0601 -94.6201 36.9961 -94.6201 37.0001 -95.0321 37.0011 -95.0711</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Kansas</topp:STATE_NAME><topp:STATE_FIPS>20</topp:STATE_FIPS><topp:SUB_REGION>W N Cen</topp:SUB_REGION><topp:STATE_ABBR>KS</topp:STATE_ABBR><topp:LAND_KM>211921.641</topp:LAND_KM><topp:WATER_KM>1188.865</topp:WATER_KM><topp:PERSONS>2477574.0</topp:PERSONS><topp:FAMILIES>658600.0</topp:FAMILIES><topp:HOUSHOLD>944726.0</topp:HOUSHOLD><topp:MALE>1214645.0</topp:MALE><topp:FEMALE>1262929.0</topp:FEMALE><topp:WORKERS>907383.0</topp:WORKERS><topp:DRVALONE>928575.0</topp:DRVALONE><topp:CARPOOL>135598.0</topp:CARPOOL><topp:PUBTRANS>7585.0</topp:PUBTRANS><topp:EMPLOYED>1172214.0</topp:EMPLOYED><topp:UNEMPLOY>57772.0</topp:UNEMPLOY><topp:SERVICE>346339.0</topp:SERVICE><topp:MANUAL>166429.0</topp:MANUAL><topp:P_MALE>0.49</topp:P_MALE><topp:P_FEMALE>0.51</topp:P_FEMALE><topp:SAMP_POP>453411.0</topp:SAMP_POP></topp:states><topp:states fid="states.9"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.5461 -79.1441 36.5491 -79.2171 36.5471 -79.5101 36.5471 -79.7171 36.5451 -80.0241 36.5471 -80.0481 36.5511 -80.4351 36.5571 -80.6111 36.5631 -80.8381 36.5651 -80.9031 36.5721 -81.3451 36.5891 -81.6691 36.6071 -81.6521 36.6111 -81.8291 36.6131 -81.9181 36.5951 -81.9291 36.5951 -82.1541 36.5931 -82.2161 36.5911 -82.2961 36.5911 -82.6101 36.5901 -82.8491 36.5911 -82.9861 36.5881 -83.2111 36.5891 -83.2481 36.6001 -83.2751 36.5981 -83.4641 36.5981 -83.6751 36.6161 -83.6461 36.6611 -83.5301 36.6611 -83.4601 36.6721 -83.4041 36.6881 -83.3851 36.7091 -83.3211 36.7341 -83.2031 36.7391 -83.1381 36.7511 -83.1241 36.7791 -83.1281 36.8501 -83.0681 36.8581 -83.0461 36.8631 -82.9501 36.8931 -82.8781 36.9321 -82.8601 36.9741 -82.8661 37.0051 -82.8121 37.0331 -82.7231 37.0651 -82.7201 37.0751 -82.7091 37.0931 -82.7211 37.1091 -82.7191 37.1931 -82.5681 37.1991 -82.5501 37.2501 -82.4061 37.2601 -82.3531 37.3041 -82.2891 37.5311 -81.9591 37.5061 -81.9351 37.4921 -81.9481 37.4821 -81.9761 37.4661 -81.9881 37.4151 -81.9201 37.3711 -81.9261 37.3401 -81.8971 37.3251 -81.8631 37.3061 -81.8581 37.2851 -81.8391 37.2791 -81.8151 37.2871 -81.7921 37.2721 -81.7521 37.2501 -81.7381 37.2351 -81.7011 37.2041 -81.6661 37.2061 -81.5561 37.2341 -81.5051 37.2521 -81.4951 37.2541 -81.4751 37.2821 -81.4031 37.3111 -81.3911 37.3381 -81.3581 37.2931 -81.3121 37.2401 -81.2231 37.2741 -81.1401 37.2851 -81.0251 37.3061 -80.9861 37.2961 -80.9781 37.2911 -80.9681 37.3011 -80.9341 37.3391 -80.8551 37.3501 -80.8481 37.3881 -80.8771 37.4231 -80.8501 37.4121 -80.7991 37.3911 -80.7991 37.3861 -80.7701 37.3711 -80.7631 37.3781 -80.7471 37.3871 -80.7461 37.3921 -80.7291 37.3881 -80.7051 37.4451 -80.5971 37.4691 -80.5421 37.4741 -80.5081 37.4601 -80.4881 37.4331 -80.4871 37.4221 -80.4741 37.4341 -80.4251 37.4651 -80.3881 37.4751 -80.3521 37.4911 -80.3471 37.5111 -80.2881 37.5361 -80.2801 37.5281 -80.3081 37.5331 -80.3261 37.5661 -80.3161 37.5961 -80.2461 37.6241 -80.2191 37.6401 -80.2541 37.6401 -80.3011 37.6521 -80.3051 37.6711 -80.2951 37.6821 -80.3031 37.7251 -80.2501 37.7571 -80.2541 37.7781 -80.2201 37.8021 -80.2231 37.8421 -80.1711 37.8601 -80.1721 37.8771 -80.1601 37.8911 -80.1181 37.9141 -80.1061 37.9551 -80.0551 37.9891 -80.0001 38.0381 -79.9661 38.0671 -79.9571 38.1031 -79.9281 38.1211 -79.9351 38.1621 -79.9101 38.1791 -79.9161 38.2501 -79.8311 38.2681 -79.7931 38.2841 -79.7861 38.2981 -79.8031 38.3141 -79.8001 38.3531 -79.7641 38.3511 -79.7331 38.3941 -79.7201 38.4301 -79.6841 38.5001 -79.6921 38.5201 -79.6651 38.5501 -79.6691 38.5921 -79.6421 38.5531 -79.5361 38.4621 -79.4861 38.4121 -79.3171 38.4371 -79.2721 38.4801 -79.2311 38.6581 -79.1271 38.6631 -79.1211 38.6591 -79.0881 38.7071 -79.0871 38.7611 -79.0561 38.7901 -79.0551 38.7991 -79.0331 38.8461 -78.9871 38.7631 -78.8661 38.8331 -78.8161 38.8801 -78.7931 38.9111 -78.7491 38.9291 -78.7371 38.9301 -78.7241 38.9041 -78.7191 38.9211 -78.6801 38.9501 -78.6471 38.9791 -78.6311 38.9671 -78.5981 39.0131 -78.5531 39.0231 -78.5491 39.0351 -78.5641 39.0571 -78.5361 39.0931 -78.5011 39.1111 -78.4851 39.1181 -78.4481 39.1481 -78.4301 39.1701 -78.4021 39.1971 -78.4241 39.2121 -78.4231 39.2441 -78.3991 39.2571 -78.4131 39.3411 -78.3411 39.3501 -78.3441 39.3611 -78.3651 39.3801 -78.3501 39.4561 -78.3471 39.4231 -78.2771 39.3911 -78.2291 39.2651 -78.0331 39.1321 -77.8301 39.1411 -77.8201 39.1961 -77.8051 39.2461 -77.7681 39.2841 -77.7591 39.3171 -77.7271 39.3181 -77.6791 39.2991 -77.6161 39.2981 -77.5681 39.2681 -77.5421 39.2491 -77.4941 39.2291 -77.4641 39.2181 -77.4611 39.1761 -77.4781 39.1571 -77.5161 39.1161 -77.5131 39.1031 -77.4791 39.0801 -77.4591 39.0661 -77.4331 39.0681 -77.3461 39.0621 -77.3241 39.0271 -77.2551 38.9751 -77.2431 38.9641 -77.1521 38.9321 -77.1221 38.9151 -77.0781 38.8861 -77.0671 38.8621 -77.0391 38.8381 -77.0401 38.8291 -77.0451 38.8131 -77.0351 38.7881 -77.0451 38.7181 -77.0461 38.7121 -77.0571 38.7151 -77.0811 38.7031 -77.0931 38.6771 -77.1251 38.6481 -77.1291 38.6221 -77.1971 38.6601 -77.1941 38.6501 -77.2271 38.5011 -77.3031 38.4361 -77.3381 38.3621 -77.2891 38.3431 -77.3211 38.3311 -77.2401 38.3751 -77.0541 38.2801 -76.9991 38.2021 -76.9361 38.1201 -76.5951 38.0741 -76.5491 38.0251 -76.5581 38.0031 -76.5731 38.0121 -76.5241 37.9561 -76.3671 37.8901 -76.2591 37.8501 -76.2511 37.7981 -76.3241 37.7191 -76.3091 37.7001 -76.3571 37.6771 -76.3231 37.6221 -76.3441 37.6561 -76.5071 37.7701 -76.5801 37.7961 -76.6311 37.9161 -76.7711 37.9191 -76.8181 37.7981 -76.7321 37.7741 -76.6811 37.6411 -76.5691 37.5511 -76.3141 37.5251 -76.3481 37.5521 -76.5121 37.5151 -76.4341 37.5151 -76.3551 37.3901 -76.2541 37.3301 -76.2751 37.3341 -76.3001 37.3931 -76.3391 37.4571 -76.4461 37.4181 -76.4631 37.4121 -76.4171 37.3731 -76.4031 37.3771 -76.4551 37.2931 -76.3921 37.2551 -76.4611 37.4121 -76.6531 37.4181 -76.7041 37.3711 -76.6691 37.2911 -76.5951 37.2071 -76.4241 37.1521 -76.4121 37.1731 -76.3961 37.1461 -76.3631 37.1771 -76.3371 37.1221 -76.2851 37.1071 -76.3951 37.0741 -76.2781 37.0201 -76.2931 36.9901 -76.3841 36.9651 -76.4261 37.0671 -76.5311 37.0881 -76.5151 37.1171 -76.5641 37.0801 -76.5681 37.1321 -76.6241 37.1781 -76.6101 37.2251 -76.6481 37.2321 -76.6971 37.1931 -76.7461 37.2401 -76.7951 37.2431 -76.8571 37.3221 -76.8751 37.2591 -76.8781 37.2361 -76.9411 37.2011 -76.9001 37.2071 -76.7971 37.1501 -76.7291 37.1971 -76.6851 37.1471 -76.6711 37.0541 -76.6651 37.0241 -76.5771 36.9941 -76.6131 37.0061 -76.5551 36.9611 -76.4891 36.9121 -76.5171 36.9191 -76.4821 36.8951 -76.4861 36.8411 -76.5601 36.7951 -76.5611 36.8691 -76.5071 36.9011 -76.4101 36.9131 -76.3481 36.8601 -76.3411 36.8351 -76.3941 36.8261 -76.4011 36.8451 -76.3171 36.8281 -76.2921 36.9421 -76.3071 36.9621 -76.2841 36.9351 -76.2021 36.9041 -76.1911 36.9311 -76.1181 36.9231 -75.9951 36.5551 -75.8781 36.5561 -75.9011 36.5991 -75.8921 36.7211 -75.9501 36.5561 -75.9981 36.5561 -76.0271 36.6031 -76.0611 36.5561 -76.0451 36.5571 -76.1271 36.5561 -76.3301 36.5551 -76.4971 36.5551 -76.5631 36.5541 -76.9211 36.5541 -76.9241 36.5561 -77.1771 36.5531 -77.3201 36.5531 -77.7631 36.5521 -77.8981 36.5521 -78.0511 36.5451 -78.3211 36.5411 -78.4581 36.5461 -78.7371 36.5431 -78.7961 36.5461 -79.1441</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.0271 -75.2701 38.0281 -75.2421 37.9621 -75.2981 37.8881 -75.3391 37.8751 -75.3861 37.9011 -75.3441 37.9001 -75.3781 37.9181 -75.3461 38.0271 -75.2701</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.5521 -75.8671 37.5611 -75.9411 37.5851 -75.9291 37.5801 -75.8871 37.5921 -75.9051 37.7111 -75.7991 37.7891 -75.7821 37.8241 -75.6961 37.8581 -75.6861 37.9301 -75.7331 37.9411 -75.6581 37.9701 -75.6481 37.9961 -75.6261 38.0161 -75.3721 37.6971 -75.6171 37.6771 -75.5891 37.5891 -75.6991 37.5591 -75.6501 37.5581 -75.7271 37.5101 -75.7561 37.4931 -75.7051 37.4691 -75.8131 37.4261 -75.8201 37.4081 -75.7901 37.4181 -75.8261 37.3671 -75.8971 37.1421 -75.9311 37.1261 -75.9701 37.3081 -76.0181 37.4841 -75.9341 37.4791 -75.9651 37.5211 -75.9541 37.5561 -75.9301 37.5521 -75.8671</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Virginia</topp:STATE_NAME><topp:STATE_FIPS>51</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>VA</topp:STATE_ABBR><topp:LAND_KM>102537.328</topp:LAND_KM><topp:WATER_KM>4263.82</topp:WATER_KM><topp:PERSONS>6180651.0</topp:PERSONS><topp:FAMILIES>1627615.0</topp:FAMILIES><topp:HOUSHOLD>2289067.0</topp:HOUSHOLD><topp:MALE>3030948.0</topp:MALE><topp:FEMALE>3149703.0</topp:FEMALE><topp:WORKERS>2343200.0</topp:WORKERS><topp:DRVALONE>2278600.0</topp:DRVALONE><topp:CARPOOL>499251.0</topp:CARPOOL><topp:PUBTRANS>125792.0</topp:PUBTRANS><topp:EMPLOYED>3025109.0</topp:EMPLOYED><topp:UNEMPLOY>141926.0</topp:UNEMPLOY><topp:SERVICE>777181.0</topp:SERVICE><topp:MANUAL>420070.0</topp:MANUAL><topp:P_MALE>0.49</topp:P_MALE><topp:P_FEMALE>0.51</topp:P_FEMALE><topp:SAMP_POP>898089.0</topp:SAMP_POP></topp:states><topp:states fid="states.10"><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.9531 -89.1041 36.8661 -89.1291 36.8431 -89.1661 36.8291 -89.1731 36.8041 -89.1641 36.7921 -89.1251 36.7681 -89.1251 36.7591 -89.1511 36.7601 -89.1771 36.7271 -89.1961 36.7131 -89.1971 36.6711 -89.1671 36.6531 -89.1771 36.6311 -89.2001 36.5811 -89.2101 36.5691 -89.2411 36.5751 -89.2831 36.6221 -89.3221 36.6281 -89.3421 36.6251 -89.3631 36.6161 -89.3731 36.5101 -89.4181 36.5021 -89.4141 36.4561 -89.4481 36.4451 -89.4701 36.4651 -89.4911 36.4981 -89.4751 36.5041 -89.4811 36.5251 -89.4711 36.5471 -89.4811 36.5591 -89.4931 36.5641 -89.5301 36.5571 -89.5561 36.5411 -89.5681 36.5181 -89.5661 36.4981 -89.5331 36.4711 -89.5161 36.4401 -89.5451 36.4011 -89.5201 36.3551 -89.5191 36.3451 -89.5441 36.3541 -89.6051 36.3341 -89.6221 36.3081 -89.6061 36.2801 -89.5421 36.2641 -89.5351 36.2571 -89.5411 36.2401 -89.6181 36.2541 -89.6701 36.2521 -89.6941 36.2401 -89.6951 36.2201 -89.6761 36.1831 -89.6181 36.1521 -89.5891 36.1291 -89.5891 36.0991 -89.6671 36.0821 -89.6781 36.0251 -89.6881 35.9991 -89.7211 35.9961 -89.9631 35.9911 -90.2831 35.9891 -90.3781 36.0911 -90.3151 36.1151 -90.2841 36.1181 -90.2631 36.1371 -90.2341 36.1611 -90.2321 36.1721 -90.2191 36.1961 -90.1611 36.2121 -90.1311 36.2571 -90.1091 36.2721 -90.0661 36.3001 -90.0491 36.3251 -90.0671 36.3621 -90.0501 36.3821 -90.0521 36.3971 -90.0801 36.4041 -90.1161 36.4221 -90.1231 36.4531 -90.1171 36.4571 -90.1371 36.4911 -90.1501 36.4921 -90.2241 36.4901 -90.5811 36.4891 -90.8041 36.4871 -91.1331 36.4911 -91.4111 36.4901 -91.4521 36.4901 -91.6881 36.4911 -92.1271 36.4911 -92.1461 36.4901 -92.5221 36.4891 -92.7771 36.4891 -92.8521 36.4901 -93.2971 36.4901 -93.3281 36.4891 -93.5961 36.4891 -93.8571 36.4901 -94.0801 36.4891 -94.6171 36.6701 -94.6201 36.7631 -94.6211 36.9961 -94.6201 37.0601 -94.6201 37.3271 -94.6181 37.3601 -94.6181 37.6501 -94.6181 37.6791 -94.6191 38.0301 -94.6161 38.0551 -94.6171 38.3921 -94.6181 38.4711 -94.6181 38.7371 -94.6121 38.8371 -94.6121 39.0441 -94.6091 39.1121 -94.6071 39.1411 -94.6001 39.1511 -94.6121 39.1581 -94.6461 39.1741 -94.6751 39.1711 -94.7301 39.1961 -94.7891 39.2111 -94.8201 39.2611 -94.8331 39.2861 -94.8801 39.3231 -94.9071 39.3401 -94.9111 39.3801 -94.8981 39.3811 -94.9251 39.4111 -94.9581 39.4391 -94.9851 39.4621 -95.0401 39.4851 -95.0471 39.5321 -95.1011 39.5601 -95.1081 39.5861 -95.0531 39.6251 -95.0551 39.6611 -95.0281 39.6841 -94.9781 39.7321 -94.9611 39.7361 -94.9521 39.7271 -94.9301 39.7261 -94.9051 39.7391 -94.8771 39.7541 -94.8701 39.7601 -94.8761 39.7571 -94.9211 39.7751 -94.9341 39.7821 -94.9331 39.7931 -94.8991 39.8171 -94.8881 39.8281 -94.8981 39.8331 -94.9231 39.8491 -94.9361 39.8961 -94.9371 39.9001 -94.9641 39.8961 -95.0211 39.8771 -95.0331 39.8661 -95.0621 39.8691 -95.1001 39.9081 -95.1501 39.9101 -95.1931 39.9381 -95.2071 39.9421 -95.2401 39.9991 -95.3081 40.0241 -95.3441 40.0281 -95.3701 40.0431 -95.3901 40.0481 -95.4131 40.0801 -95.4031 40.0951 -95.3841 40.1151 -95.3921 40.1311 -95.4221 40.1731 -95.4601 40.2131 -95.4661 40.2261 -95.4761 40.2661 -95.5461 40.3091 -95.5951 40.3091 -95.6461 40.3221 -95.6451 40.3311 -95.6171 40.3461 -95.6151 40.3581 -95.6331 40.3961 -95.6361 40.4851 -95.6951 40.5121 -95.6841 40.5301 -95.6571 40.5581 -95.6621 40.5651 -95.6751 40.5611 -95.6871 40.5241 -95.6911 40.5321 -95.7361 40.5491 -95.7631 40.5891 -95.7671 40.5841 -95.3821 40.5811 -95.2171 40.5771 -94.9201 40.5751 -94.6391 40.5741 -94.4841 40.5701 -94.2381 40.5741 -94.0171 40.5781 -93.7861 40.5801 -93.5621 40.5801 -93.3701 40.5841 -93.1001 40.5891 -92.7171 40.5911 -92.6461 40.5991 -92.3611 40.6001 -92.1921 40.6081 -91.9461 40.6091 -91.7411 40.5931 -91.7161 40.5811 -91.6891 40.5511 -91.6911 40.5321 -91.6221 40.5041 -91.6161 40.4841 -91.5851 40.4631 -91.5791 40.4551 -91.5331 40.4411 -91.5381 40.4351 -91.5291 40.4101 -91.5271 40.4051 -91.5001 40.3901 -91.4901 40.3901 -91.4761 40.3711 -91.4481 40.3091 -91.4861 40.2511 -91.4981 40.2001 -91.5061 40.1341 -91.5161 40.0661 -91.5041 40.0051 -91.4871 39.9461 -91.4471 39.9211 -91.4301 39.9011 -91.4341 39.8851 -91.4501 39.8631 -91.4491 39.8031 -91.3811 39.7611 -91.3731 39.7241 -91.3671 39.6851 -91.3171 39.6001 -91.2031 39.5521 -91.1561 39.5281 -91.0931 39.4731 -91.0641 39.4441 -91.0361 39.4001 -90.9471 39.3501 -90.8501 39.2961 -90.7791 39.2471 -90.7381 39.2241 -90.7321 39.1951 -90.7181 39.1441 -90.7161 39.0931 -90.6901 39.0581 -90.7071 39.0371 -90.7061 38.9351 -90.6681 38.8801 -90.6271 38.8711 -90.5701 38.8911 -90.5301 38.9591 -90.4691 38.9621 -90.4131 38.9241 -90.3191 38.9241 -90.2781 38.9141 -90.2431 38.8531 -90.1321 38.8301 -90.1131 38.8001 -90.1211 38.7851 -90.1351 38.7731 -90.1631 38.7231 -90.1961 38.7001 -90.2021 38.6581 -90.1831 38.6101 -90.1831 38.5621 -90.2401 38.5321 -90.2611 38.5181 -90.2651 38.4271 -90.3011 38.3901 -90.3391 38.3651 -90.3581 38.3231 -90.3691 38.2341 -90.3641 38.1881 -90.3361 38.1661 -90.2891 38.1221 -90.2541 38.0881 -90.2071 38.0531 -90.1341 38.0321 -90.1191 37.9931 -90.0411 37.9691 -90.0101 37.9631 -89.9581 37.9111 -89.9781 37.8781 -89.9371 37.8751 -89.9001 37.8911 -89.8661 37.9051 -89.8611 37.9051 -89.8511 37.8401 -89.7281 37.8041 -89.6911 37.7831 -89.6751 37.7451 -89.6661 37.7061 -89.5811 37.6941 -89.5211 37.6791 -89.5131 37.6501 -89.5191 37.6151 -89.5131 37.5711 -89.5241 37.4911 -89.4941 37.4531 -89.4531 37.4111 -89.4271 37.3551 -89.4351 37.3391 -89.4681 37.3291 -89.5001 37.3041 -89.5131 37.2761 -89.5131 37.2561 -89.4891 37.2531 -89.4651 37.2241 -89.4681 37.1651 -89.4401 37.1371 -89.4231 37.0991 -89.3791 37.0491 -89.3821 37.0091 -89.3101 36.9991 -89.2821 37.0081 -89.2621 37.0271 -89.2641 37.0601 -89.3091 37.0851 -89.3031 37.0911 -89.2841 37.0871 -89.2641 37.0411 -89.2371 37.0281 -89.2101 36.9861 -89.1931 36.9881 -89.1291 36.9771 -89.1071 36.9531 -89.1041</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Missouri</topp:STATE_NAME><topp:STATE_FIPS>29</topp:STATE_FIPS><topp:SUB_REGION>W N Cen</topp:SUB_REGION><topp:STATE_ABBR>MO</topp:STATE_ABBR><topp:LAND_KM>178445.951</topp:LAND_KM><topp:WATER_KM>2100.115</topp:WATER_KM><topp:PERSONS>5117073.0</topp:PERSONS><topp:FAMILIES>1368334.0</topp:FAMILIES><topp:HOUSHOLD>1961206.0</topp:HOUSHOLD><topp:MALE>2464315.0</topp:MALE><topp:FEMALE>2652758.0</topp:FEMALE><topp:WORKERS>1861192.0</topp:WORKERS><topp:DRVALONE>1816079.0</topp:DRVALONE><topp:CARPOOL>312042.0</topp:CARPOOL><topp:PUBTRANS>47129.0</topp:PUBTRANS><topp:EMPLOYED>2367395.0</topp:EMPLOYED><topp:UNEMPLOY>155388.0</topp:UNEMPLOY><topp:SERVICE>659782.0</topp:SERVICE><topp:MANUAL>386746.0</topp:MANUAL><topp:P_MALE>0.482</topp:P_MALE><topp:P_FEMALE>0.518</topp:P_FEMALE><topp:SAMP_POP>864999.0</topp:SAMP_POP></topp:states></gml:featureMembers>
+--></div>
+<div id="v3/topp-states-wfs.xml"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<wfs:FeatureCollection numberOfFeatures="3" timeStamp="2008-09-12T00:24:21.013-04:00" xsi:schemaLocation="http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.1.0/wfs.xsd" xmlns:ogc="http://www.opengis.net/ogc" xmlns:opengeo="http://open-geo.com" xmlns:tiger="http://www.census.gov" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:seb="http://seb.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink"><gml:featureMembers><topp:states gml:id="states.1"><gml:boundedBy><gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:lowerCorner>36.986 -91.516</gml:lowerCorner><gml:upperCorner>42.509 -87.507</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.511 -88.071 37.476 -88.087 37.442 -88.311 37.409 -88.359 37.421 -88.419 37.401 -88.467 37.296 -88.511 37.257 -88.501 37.205 -88.451 37.156 -88.422 37.098 -88.451 37.072 -88.476 37.068 -88.491 37.064 -88.517 37.072 -88.559 37.109 -88.614 37.135 -88.688 37.141 -88.739 37.152 -88.746 37.202 -88.863 37.218 -88.932 37.221 -88.993 37.185 -89.065 37.112 -89.116 37.093 -89.146 37.064 -89.169 37.025 -89.174 36.998 -89.151 36.988 -89.129 36.986 -89.193 37.028 -89.211 37.041 -89.237 37.087 -89.264 37.091 -89.284 37.085 -89.303 37.061 -89.309 37.027 -89.264 37.008 -89.262 36.999 -89.282 37.009 -89.311 37.049 -89.382 37.099 -89.379 37.137 -89.423 37.165 -89.441 37.224 -89.468 37.253 -89.465 37.256 -89.489 37.276 -89.513 37.304 -89.513 37.329 -89.501 37.339 -89.468 37.355 -89.435 37.411 -89.427 37.453 -89.453 37.491 -89.494 37.571 -89.524 37.615 -89.513 37.651 -89.519 37.679 -89.513 37.694 -89.521 37.706 -89.581 37.745 -89.666 37.783 -89.675 37.804 -89.691 37.841 -89.728 37.905 -89.851 37.905 -89.861 37.891 -89.866 37.875 -89.901 37.878 -89.937 37.911 -89.978 37.963 -89.958 37.969 -90.011 37.993 -90.041 38.032 -90.119 38.053 -90.134 38.088 -90.207 38.122 -90.254 38.166 -90.289 38.188 -90.336 38.234 -90.364 38.323 -90.369 38.365 -90.358 38.391 -90.339 38.427 -90.301 38.518 -90.265 38.532 -90.261 38.562 -90.241 38.611 -90.183 38.658 -90.183 38.701 -90.202 38.723 -90.196 38.773 -90.163 38.785 -90.135 38.801 -90.121 38.831 -90.113 38.853 -90.132 38.914 -90.243 38.924 -90.278 38.924 -90.319 38.962 -90.413 38.959 -90.469 38.891 -90.531 38.871 -90.571 38.881 -90.627 38.935 -90.668 39.037 -90.706 39.058 -90.707 39.093 -90.691 39.144 -90.716 39.195 -90.718 39.224 -90.732 39.247 -90.738 39.296 -90.779 39.351 -90.851 39.401 -90.947 39.444 -91.036 39.473 -91.064 39.528 -91.093 39.552 -91.156 39.601 -91.203 39.685 -91.317 39.724 -91.367 39.761 -91.373 39.803 -91.381 39.863 -91.449 39.885 -91.451 39.901 -91.434 39.921 -91.431 39.946 -91.447 40.005 -91.487 40.066 -91.504 40.134 -91.516 40.201 -91.506 40.251 -91.498 40.309 -91.486 40.371 -91.448 40.386 -91.418 40.392 -91.385 40.402 -91.372 40.447 -91.385 40.503 -91.374 40.528 -91.382 40.547 -91.412 40.572 -91.411 40.603 -91.375 40.639 -91.262 40.643 -91.214 40.656 -91.162 40.682 -91.129 40.705 -91.119 40.761 -91.092 40.833 -91.088 40.879 -91.049 40.923 -90.983 40.951 -90.961 41.071 -90.954 41.104 -90.957 41.144 -90.991 41.165 -91.018 41.176 -91.056 41.231 -91.101 41.267 -91.102 41.334 -91.073 41.401 -91.055 41.423 -91.027 41.431 -91.001 41.421 -90.949 41.444 -90.844 41.449 -90.779 41.451 -90.708 41.462 -90.658 41.509 -90.601 41.525 -90.541 41.527 -90.454 41.543 -90.434 41.567 -90.423 41.586 -90.348 41.602 -90.339 41.649 -90.341 41.722 -90.326 41.756 -90.304 41.781 -90.255 41.806 -90.195 41.931 -90.154 41.983 -90.142 42.033 -90.151 42.061 -90.168 42.103 -90.166 42.121 -90.176 42.122 -90.191 42.159 -90.231 42.197 -90.323 42.211 -90.367 42.242 -90.407 42.263 -90.417 42.341 -90.427 42.361 -90.441 42.388 -90.491 42.421 -90.563 42.461 -90.605 42.475 -90.648 42.494 -90.651 42.509 -90.638 42.508 -90.419 42.504 -89.923 42.503 -89.834 42.497 -89.401 42.497 -89.359 42.491 -88.939 42.491 -88.764 42.489 -88.706 42.491 -88.297 42.489 -88.194 42.489 -87.797 42.314 -87.836 42.156 -87.761 42.059 -87.671 41.847 -87.612 41.723 -87.529 41.469 -87.532 41.301 -87.532 41.173 -87.531 41.009 -87.532 40.745 -87.532 40.494 -87.537 40.483 -87.535 40.166 -87.535 39.887 -87.535 39.609 -87.535 39.477 -87.538 39.351 -87.541 39.338 -87.597 39.307 -87.625 39.297 -87.611 39.281 -87.615 39.258 -87.606 39.248 -87.584 39.208 -87.588 39.198 -87.594 39.196 -87.607 39.168 -87.644 39.146 -87.671 39.131 -87.659 39.113 -87.662 39.103 -87.631 39.088 -87.631 39.084 -87.612 39.062 -87.585 38.995 -87.581 38.994 -87.591 38.977 -87.547 38.963 -87.533 38.931 -87.531 38.904 -87.539 38.869 -87.559 38.857 -87.551 38.795 -87.507 38.776 -87.519 38.769 -87.508 38.736 -87.508 38.685 -87.543 38.672 -87.588 38.642 -87.625 38.622 -87.628 38.599 -87.619 38.593 -87.641 38.573 -87.652 38.547 -87.672 38.515 -87.651 38.501 -87.653 38.504 -87.679 38.481 -87.692 38.466 -87.756 38.457 -87.758 38.445 -87.738 38.417 -87.748 38.378 -87.784 38.352 -87.834 38.286 -87.851 38.285 -87.863 38.316 -87.874 38.315 -87.883 38.301 -87.888 38.281 -87.914 38.302 -87.913 38.304 -87.925 38.241 -87.981 38.234 -87.986 38.201 -87.977 38.171 -87.932 38.157 -87.931 38.136 -87.951 38.131 -87.973 38.103 -88.018 38.092 -88.012 38.096 -87.964 38.073 -87.975 38.054 -88.034 38.045 -88.043 38.038 -88.041 38.033 -88.021 38.008 -88.029 37.975 -88.021 37.956 -88.042 37.934 -88.041 37.929 -88.064 37.944 -88.078 37.923 -88.084 37.917 -88.031 37.905 -88.026 37.896 -88.044 37.906 -88.101 37.895 -88.101 37.867 -88.075 37.843 -88.034 37.827 -88.042 37.831 -88.089 37.817 -88.086 37.805 -88.035 37.735 -88.072 37.701 -88.133 37.661 -88.159 37.628 -88.157 37.583 -88.134 37.511 -88.071</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.143E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states><topp:states gml:id="states.2"><gml:boundedBy><gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:lowerCorner>38.788 -77.122</gml:lowerCorner><gml:upperCorner>38.993 -76.911</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.966 -77.008 38.889 -76.911 38.788 -77.045 38.813 -77.035 38.829 -77.045 38.838 -77.041 38.862 -77.039 38.886 -77.067 38.915 -77.078 38.932 -77.122 38.993 -77.042 38.966 -77.008</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>District of Columbia</topp:STATE_NAME><topp:STATE_FIPS>11</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DC</topp:STATE_ABBR><topp:LAND_KM>159.055</topp:LAND_KM><topp:WATER_KM>17.991</topp:WATER_KM><topp:PERSONS>606900.0</topp:PERSONS><topp:FAMILIES>122087.0</topp:FAMILIES><topp:HOUSHOLD>249634.0</topp:HOUSHOLD><topp:MALE>282970.0</topp:MALE><topp:FEMALE>323930.0</topp:FEMALE><topp:WORKERS>229975.0</topp:WORKERS><topp:DRVALONE>106694.0</topp:DRVALONE><topp:CARPOOL>36621.0</topp:CARPOOL><topp:PUBTRANS>111422.0</topp:PUBTRANS><topp:EMPLOYED>303994.0</topp:EMPLOYED><topp:UNEMPLOY>23442.0</topp:UNEMPLOY><topp:SERVICE>65498.0</topp:SERVICE><topp:MANUAL>22407.0</topp:MANUAL><topp:P_MALE>0.466</topp:P_MALE><topp:P_FEMALE>0.534</topp:P_FEMALE><topp:SAMP_POP>72696.0</topp:SAMP_POP></topp:states><topp:states gml:id="states.3"><gml:boundedBy><gml:Envelope srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:lowerCorner>38.449 -75.791</gml:lowerCorner><gml:upperCorner>39.841 -75.045</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:the_geom><gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.557 -75.707 38.649 -75.711 38.831 -75.724 39.141 -75.752 39.247 -75.761 39.295 -75.764 39.383 -75.772 39.723 -75.791 39.724 -75.775 39.774 -75.745 39.821 -75.695 39.838 -75.644 39.841 -75.583 39.826 -75.471 39.798 -75.421 39.789 -75.412 39.778 -75.428 39.763 -75.461 39.741 -75.475 39.719 -75.476 39.714 -75.489 39.612 -75.611 39.566 -75.562 39.463 -75.591 39.366 -75.515 39.257 -75.402 39.073 -75.397 39.012 -75.324 38.945 -75.307 38.808 -75.191 38.799 -75.083 38.449 -75.045 38.449 -75.068 38.451 -75.093 38.455 -75.351 38.463 -75.699 38.557 -75.707</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Delaware</topp:STATE_NAME><topp:STATE_FIPS>10</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DE</topp:STATE_ABBR><topp:LAND_KM>5062.456</topp:LAND_KM><topp:WATER_KM>1385.022</topp:WATER_KM><topp:PERSONS>666168.0</topp:PERSONS><topp:FAMILIES>175867.0</topp:FAMILIES><topp:HOUSHOLD>247497.0</topp:HOUSHOLD><topp:MALE>322968.0</topp:MALE><topp:FEMALE>343200.0</topp:FEMALE><topp:WORKERS>247566.0</topp:WORKERS><topp:DRVALONE>258087.0</topp:DRVALONE><topp:CARPOOL>42968.0</topp:CARPOOL><topp:PUBTRANS>8069.0</topp:PUBTRANS><topp:EMPLOYED>335147.0</topp:EMPLOYED><topp:UNEMPLOY>13945.0</topp:UNEMPLOY><topp:SERVICE>87973.0</topp:SERVICE><topp:MANUAL>44140.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>102776.0</topp:SAMP_POP></topp:states></gml:featureMembers></wfs:FeatureCollection>
+--></div>
+<div id="v2/point-coord.xml"><!--
+<gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+</gml:Point>
+--></div>
+<div id="v2/point-coordinates.xml"><!--
+<gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+</gml:Point>
+--></div>
+<div id="v2/linestring-coord.xml"><!--
+<gml:LineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+</gml:LineString>
+--></div>
+<div id="v2/linestring-coordinates.xml"><!--
+<gml:LineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4</gml:coordinates>
+</gml:LineString>
+--></div>
+<div id="v2/multipoint-coord.xml"><!--
+<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ </gml:Point>
+ </gml:pointMember>
+</gml:MultiPoint>
+--></div>
+<div id="v2/multipoint-coordinates.xml"><!--
+<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">2,3</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+</gml:MultiPoint>
+--></div>
+<div id="v2/multilinestring-coord.xml"><!--
+<gml:MultiLineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coord>
+ <gml:X>1</gml:X>
+ <gml:Y>2</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>2</gml:X>
+ <gml:Y>3</gml:Y>
+ </gml:coord>
+ </gml:LineString>
+ </gml:lineStringMember>
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coord>
+ <gml:X>3</gml:X>
+ <gml:Y>4</gml:Y>
+ </gml:coord>
+ <gml:coord>
+ <gml:X>4</gml:X>
+ <gml:Y>5</gml:Y>
+ </gml:coord>
+ </gml:LineString>
+ </gml:lineStringMember>
+</gml:MultiLineString>
+--></div>
+<div id="v2/multilinestring-coordinates.xml"><!--
+<gml:MultiLineString xmlns:gml="http://www.opengis.net/gml" srsName="foo">
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 2,3</gml:coordinates>
+ </gml:LineString>
+ </gml:lineStringMember>
+ <gml:lineStringMember>
+ <gml:LineString>
+ <gml:coordinates decimal="." cs="," ts=" ">3,4 4,5</gml:coordinates>
+ </gml:LineString>
+ </gml:lineStringMember>
+</gml:MultiLineString>
+--></div>
+<div id="v3/repeated-name.xml"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<wfs:FeatureCollection numberOfFeatures="1" timeStamp="2010-01-29T15:10:38.921-07:00"
+ xsi:schemaLocation="http://medford.opengeo.org http://localhost:8080/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=medford%3Azoning http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:wfs="http://www.opengis.net/wfs"
+ xmlns:medford="http://opengeo.org/#medford"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ows="http://www.opengis.net/ows"
+ xmlns:gml="http://www.opengis.net/gml"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <gml:featureMembers>
+ <medford:zoning gml:id="zoning.1">
+ <medford:the_geom>
+ <gml:MultiSurface srsName="urn:x-ogc:def:crs:EPSG:4326">
+ <gml:surfaceMember>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList>42.397027571297585 -122.88465674265922 42.39702893980587 -122.88509730796012 42.397029086785146 -122.88511582432085 42.39702379767053 -122.88528111596624 42.39748517484964 -122.88529300380065 42.39748473847452 -122.88509914138723 42.39748482219041 -122.8849959517568 42.397485082635576 -122.8846741899541 42.3974853307826 -122.88436529392652 42.39702663751206 -122.88435664014142 42.397027571297585 -122.88465674265922</gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+ </gml:Polygon>
+ </gml:surfaceMember>
+ </gml:MultiSurface>
+ </medford:the_geom>
+ <medford:objectid>1</medford:objectid>
+ <medford:cityzone>YES</medford:cityzone>
+ <medford:zoning>I-L</medford:zoning>
+ <medford:revdate>2004-04-12T00:00:00-06:00</medford:revdate>
+ <medford:finord></medford:finord>
+ <medford:filenum></medford:filenum>
+ <medford:acres>0.95741118624</medford:acres>
+ <medford:misc></medford:misc>
+ <medford:shape_leng>835.705330224</medford:shape_leng>
+ <medford:perimeter>835.705330224</medford:perimeter>
+ <medford:area>41704.8312728</medford:area>
+ <medford:shape_le_1>835.705330224</medford:shape_le_1>
+ <medford:shape_area>41704.8312728</medford:shape_area>
+ <medford:hectares>0.38745056079</medford:hectares>
+ </medford:zoning>
+ </gml:featureMembers>
+</wfs:FeatureCollection>
+-->
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/GPX.html b/misc/openlayers/tests/Format/GPX.html
new file mode 100644
index 0000000..6286cfe
--- /dev/null
+++ b/misc/openlayers/tests/Format/GPX.html
@@ -0,0 +1,179 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var gpx_data = '<?xml version="1.0" encoding="ISO-8859-1"?><gpx version="1.1" creator="Memory-Map 5.1.3.715 http://www.memory-map.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"><wpt lat="51.3697845627" lon="-0.1853562259"><name>Mark</name><sym><![CDATA[Flag]]></sym><type><![CDATA[Marks]]></type></wpt><rte><name><![CDATA[Route8]]></name><type><![CDATA[Route]]></type><rtept lat="51.3761803674" lon="-0.1829991904"><name><![CDATA[WP0801]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat="51.3697894659" lon="-0.1758887005"><name><![CDATA[WP0802]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat="51.3639790884" lon="-0.1833202965"><name><![CDATA[WP0803]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat="51.3567607069" lon="-0.1751119509"><name><![CDATA[WP0804]]></name><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept></rte><trk><name><![CDATA[Track]]></name><type><![CDATA[Track]]></type><trkseg><trkpt lat="51.3768216433" lon="-0.1721292044"></trkpt><trkpt lat="51.3708337670" lon="-0.1649230916"></trkpt><trkpt lat="51.3644368725" lon="-0.1736741378"></trkpt><trkpt lat="51.3576354272" lon="-0.1662595250"></trkpt></trkseg></trk></gpx>';
+
+ function test_Format_GPX_constructor(t) {
+ t.plan(5);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.GPX(options);
+ t.ok(format instanceof OpenLayers.Format.GPX,
+ "new OpenLayers.Format.GPX returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ t.eq(format.externalProjection.getCode(), "EPSG:4326",
+ "default external projection is EPSG:4326");
+ }
+ function test_Format_GPX_read(t) {
+ t.plan(7);
+
+ var origDefaultPrecision = OpenLayers.Util.DEFAULT_PRECISION;
+ OpenLayers.Util.DEFAULT_PRECISION = 9;
+
+ var expected,
+ P = OpenLayers.Geometry.Point,
+ LS = OpenLayers.Geometry.LineString;
+ var f = new OpenLayers.Format.GPX();
+ var features = f.read(gpx_data);
+ t.eq(features.length, 3, "Number of features read is correct");
+ expected = new P(-0.1853562259, 51.3697845627);
+ t.geom_eq(features[2].geometry, expected, "waypoint feature correctly created");
+ expected = new LS([
+ new P(-0.1721292044, 51.3768216433),
+ new P(-0.1649230916, 51.370833767),
+ new P(-0.1736741378, 51.3644368725),
+ new P(-0.166259525, 51.3576354272)
+ ]);
+ t.geom_eq(features[0].geometry, expected, "track feature correctly created");
+ expected = new LS([
+ new P(-0.1829991904, 51.3761803674),
+ new P(-0.1758887005, 51.3697894659),
+ new P(-0.1833202965, 51.3639790884),
+ new P(-0.1751119509, 51.3567607069)
+ ]);
+ t.geom_eq(features[1].geometry, expected, "route feature correctly created");
+
+ f.internalProjection = new OpenLayers.Projection("EPSG:3857");
+ features = f.read(gpx_data);
+ expected = new P(-20633.760679678744, 6686966.841929403);
+ t.geom_eq(features[2].geometry, expected, "transformed waypoint feature correctly created");
+ expected = new LS([
+ new P(-19161.33538179203, 6688221.743275255),
+ new P(-18359.1545744088, 6687153.931130851),
+ new P(-19333.316581165607, 6686013.33343931),
+ new P(-18507.925659955214, 6684800.777090962)
+ ]);
+ t.geom_eq(features[0].geometry, expected, "transformed track feature correctly created");
+ expected = new LS([
+ new P(-20371.3766880736, 6688107.378491073),
+ new P(-19579.84057322507, 6686967.716235109),
+ new P(-20407.12205561124, 6685931.714395953),
+ new P(-19493.373203291227, 6684644.845706556)
+ ]);
+ t.geom_eq(features[1].geometry, expected, "transformed route feature correctly created");
+
+ OpenLayers.Util.DEFAULT_PRECISION = origDefaultPrecision;
+ }
+ function test_format_GPX_read_attributes(t) {
+ t.plan(2);
+ var f = new OpenLayers.Format.GPX();
+ var features = f.read(gpx_data);
+ t.eq(features[2].attributes['name'], "Mark", "Text attribute node read correctly.");
+ t.eq(features[2].attributes['sym'], "Flag", "CDATA attribute node read correctly.");
+ }
+ function test_Format_GPX_serialize_points(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.GPX();
+
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);
+ var features = [
+ new OpenLayers.Feature.Vector(point, {name: 'foo', description: 'bar'}),
+ new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})
+ ];
+ var data = parser.write(features);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wpt lon="-111.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt><wpt lon="-112.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes points correctly');
+
+ parser.internalProjection = new OpenLayers.Projection("EPSG:3857");
+ point = new OpenLayers.Geometry.Point(-12367595.42541111, 5621521.485409545);
+ point2 = new OpenLayers.Geometry.Point(-12472235.746742222, 5621521.485409545);
+ features = [
+ new OpenLayers.Feature.Vector(point, {name: 'foo', description: 'bar'}),
+ new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})
+ ];
+ data = parser.write(features);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wpt lon="-111.1" lat="45"><name>foo</name><desc>bar</desc></wpt><wpt lon="-112.04" lat="45"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes transformed points correctly');
+ }
+ function test_Format_GPX_serialize_line(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.GPX();
+
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);
+ var line = new OpenLayers.Geometry.LineString([point, point2]);
+ var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+ var data = parser.write(f);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes line correctly');
+
+ parser.internalProjection = new OpenLayers.Projection("EPSG:3857");
+ point = new OpenLayers.Geometry.Point(-12367595.42541111, 5621521.485409545);
+ point2 = new OpenLayers.Geometry.Point(-12472235.746742222, 5621521.485409545);
+ line = new OpenLayers.Geometry.LineString([point, point2]);
+ f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+ data = parser.write(f);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.1" lat="45"/><trkpt lon="-112.04" lat="45"/></trkseg></trk></gpx>', 'GPX serializes transformed line correctly');
+ }
+ function test_Format_GPX_serialize_lines(t) {
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.GPX();
+
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);
+ var line = new OpenLayers.Geometry.LineString([point, point2]);
+ var point3 = new OpenLayers.Geometry.Point(1, 2);
+ var point4 = new OpenLayers.Geometry.Point(3, 4);
+ var line2 = new OpenLayers.Geometry.LineString([point3, point4]);
+ var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
+ var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'});
+ var data = parser.write([f, f2]);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk><trk><name>dude</name><desc>truite</desc><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes lines correctly');
+ }
+ function test_Format_GPX_serialize_multiline(t) {
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.GPX();
+
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);
+ var line = new OpenLayers.Geometry.LineString([point, point2]);
+ var point3 = new OpenLayers.Geometry.Point(1, 2);
+ var point4 = new OpenLayers.Geometry.Point(3, 4);
+ var line2 = new OpenLayers.Geometry.LineString([point3, point4]);
+ var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]);
+ var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'});
+ var data = parser.write([f]);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes multiline correctly');
+ }
+ function test_Format_GPX_serialize_polygon(t) {
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.GPX();
+
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);
+ var linearRing = new OpenLayers.Geometry.LinearRing([point, point2, point.clone()]);
+ var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
+ var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'});
+ var data = parser.write([f]);
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/><trkpt lon="-111.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes polygon correctly');
+ }
+ function test_Format_GPX_serialize_metadata(t) {
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.GPX();
+
+ var data = parser.write([], {name: 'foo', desc: 'bar'});
+ t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><metadata><name>foo</name><desc>bar</desc></metadata></gpx>', 'GPX serializes metadata correctly');
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/GeoJSON.html b/misc/openlayers/tests/Format/GeoJSON.html
new file mode 100644
index 0000000..98e950f
--- /dev/null
+++ b/misc/openlayers/tests/Format/GeoJSON.html
@@ -0,0 +1,468 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var poly_content = '{"type": "FeatureCollection", "features": [{"geometry": {"type": "Polygon", "coordinates": [[[-131.484375, -5.9765625], [-112.5, -58.0078125], [-32.34375, -50.2734375], [-114.609375, 52.3828125], [-167.34375, -35.5078125], [-146.953125, -57.3046875], [-139.921875, -34.1015625], [-131.484375, -5.9765625]]]}, "type": "Feature", "id": 562, "properties": {"strokeColor": "red", "title": "Feature 2", "author": "Your Name Here"}}]}';
+ var null_geom_feature = '{"type":"Feature","properties":{"strokeColor":"blue","title":"Feature 5","author":"Your Name Here"},"geometry":null,"id":573}';
+ var point_feature = '{"geometry": {"type": "Point", "coordinates": [94.21875, 72.94921875]}, "type": "Feature", "id": 573, "properties": {"strokeColor": "blue", "title": "Feature 5", "author": "Your Name Here"}}';
+ var line_feature = '{"type": "FeatureCollection", "features": [{"geometry": {"type": "LineString", "coordinates": [[-27.0703125, 59.4140625], [-77.6953125, 20.7421875], [30.5859375, -36.2109375], [67.1484375, 34.8046875]]}, "type": "Feature", "id": 559, "properties": {"strokeColor": "red", "title": "Feature 1", "author": "Your Name Here"}}]}';
+ var multiple_features = '{"type": "FeatureCollection", "features": [{"geometry": {"type": "Point", "coordinates": [-91.0546875, 43.9453125]}, "type": "Feature", "id": 577, "properties": {"strokeColor": "red", "title": "Feature 2", "image": "foo.gif", "author": "Your Name Here"}}, {"geometry": {"type": "LineString", "coordinates": [[91.40625, -1.40625], [116.015625, -42.890625], [153.28125, -28.125], [108.984375, 11.25], [75.234375, 8.4375], [76.640625, 9.140625], [67.5, -36.5625], [67.5, -35.859375]]}, "type": "Feature", "id": 576, "properties": {"strokeColor": "red", "title": "Feature 1", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [139.5703125, 57.48046875]}, "type": "Feature", "id": 575, "properties": {"strokeColor": "blue", "title": "Feature 7", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [107.2265625, 82.44140625]}, "type": "Feature", "id": 574, "properties": {"strokeColor": "blue", "title": "Feature 6", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [94.21875, 72.94921875]}, "type": "Feature", "id": 573, "properties": {"strokeColor": "blue", "title": "Feature 5", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [116.3671875, 61.69921875]}, "type": "Feature", "id": 572, "properties": {"strokeColor": "blue", "title": "Feature 4", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [145.8984375, 73.65234375]}, "type": "Feature", "id": 571, "properties": {"strokeColor": "blue", "title": "Feature 3", "author": "Your Name Here"}}, {"geometry": {"type": "Polygon", "coordinates": [[[32.34375, 52.20703125], [87.1875, 70.13671875], [122.6953125, 37.44140625], [75.234375, 42.36328125], [40.078125, 42.36328125], [28.828125, 48.33984375], [18.6328125, 56.77734375], [23.203125, 65.56640625], [32.34375, 52.20703125]]]}, "type": "Feature", "id": 570, "properties": {"strokeColor": "blue", "title": "Feature 2", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [62.578125, -53.4375]}, "type": "Feature", "id": 569, "properties": {"strokeColor": "red", "title": "Feature 3", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [121.640625, 16.875]}, "type": "Feature", "id": 568, "properties": {"strokeColor": "red", "title": "Feature 6", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [135.703125, 8.4375]}, "type": "Feature", "id": 567, "properties": {"strokeColor": "red", "title": "Feature 4", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [137.109375, 48.515625]}, "type": "Feature", "id": 566, "properties": {"strokeColor": "red", "title": "Feature 274", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [0, 5]}, "type": "Feature", "id": 565, "properties": {}}, {"geometry": {"type": "Point", "coordinates": [0, 5]}, "type": "Feature", "id": 564, "properties": {}}, {"geometry": {"type": "Point", "coordinates": [0, 5]}, "type": "Feature", "id": 563, "properties": {}}, {"geometry": {"type": "Polygon", "coordinates": [[[-131.484375, -5.9765625], [-112.5, -58.0078125], [-32.34375, -50.2734375], [-114.609375, 52.3828125], [-167.34375, -35.5078125], [-146.953125, -57.3046875], [-139.921875, -34.1015625], [-131.484375, -5.9765625]]]}, "type": "Feature", "id": 562, "properties": {"strokeColor": "red", "title": "Feature 2", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [48.8671875, -15.8203125]}, "type": "Feature", "id": 560, "properties": {"strokeColor": "red", "title": "Feature 2", "author": "Your Name Here"}}, {"geometry": {"type": "LineString", "coordinates": [[-27.0703125, 59.4140625], [-77.6953125, 20.7421875], [30.5859375, -36.2109375], [67.1484375, 34.8046875]]}, "type": "Feature", "id": 559, "properties": {"strokeColor": "red", "title": "Feature 1", "author": "Your Name Here"}}, {"geometry": {"type": "Point", "coordinates": [12.65625, 16.5234375]}, "type": "Feature", "id": 558, "properties": {"styleUrl": "#allstyle", "title": "Feature 1", "strokeColor": "red", "author": "Your Name Here"}}]}';
+ var parser = new OpenLayers.Format.GeoJSON();
+ var data;
+
+ function test_Format_GeoJSON_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.GeoJSON(options);
+ t.ok(format instanceof OpenLayers.Format.GeoJSON,
+ "new OpenLayers.Format.GeoJSON returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ function test_Format_GeoJSON_null_geom(t) {
+ t.plan(2);
+ var f = new OpenLayers.Format.GeoJSON();
+ var fs = f.read(null_geom_feature);
+ t.ok(fs[0].geometry == null, "Reading feature with null geom works okay");
+ t.eq(f.write(fs[0]), null_geom_feature, "round trip null okay");
+
+ }
+ function test_Format_GeoJSON_valid_type(t) {
+ t.plan(14);
+
+ OpenLayers.Console.error = function(error) { window.global_error = error;};
+ var types = ["Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", "Box", "GeometryCollection"];
+ for (var i = 0; i < types.length; i++) {
+ t.ok(parser.isValidType({'type':types[i]}, "Geometry"), "Geometry with type " + types[i] + " is valid");
+ }
+ t.ok(!parser.isValidType({'type':"foo"}, "Geometry"), "Geometry with type foo is not valid");
+ t.eq(global_error, "Unsupported geometry type: foo", "error message set correctly for 'foo' geom.");
+ t.ok(parser.isValidType({}, "FeatureCollection"), "Feature collection type is always valid");
+ t.ok(parser.isValidType({'type':"GeometryCollection"}, "GeometryCollection"), "Geometry Collection type is valid");
+ t.ok(!parser.isValidType({'type':"GeometryCollection2"}, "GeometryCollection"), "Geometry Collection 2 type is invalid");
+ t.eq(global_error, "Cannot convert types from GeometryCollection2 to GeometryCollection", "error message set correctly for bad geometrycollection type");
+ }
+
+ function test_Format_GeoJSON_point(t) {
+ t.plan(3);
+
+ data = parser.read(point_feature);
+ t.eq(data[0].fid, 573, "Fid is correct on point feature");
+ t.eq(data[0].geometry.x, 94.21875, 'Reading point feature gives correct x');
+ data = parser.read(point_feature, "Feature");
+ t.eq(data.fid, 573, 'Reading point feature with type gives feature instead of array of features ');
+ }
+
+ function test_Format_GeoJSON_line(t) {
+ t.plan(5);
+
+ data = parser.read(line_feature);
+ t.eq(data[0].fid, 559, "Fid is correct on line feature");
+ t.eq(data[0].geometry.components.length, 4, 'Reading line feature gives correct length');
+ t.eq(data[0].geometry.CLASS_NAME, 'OpenLayers.Geometry.LineString', 'Reading line feature gives correct class');
+ t.eq(data[0].geometry.components[0].x, -27.0703125, 'Reading line feature gives correct x');
+ t.eq(data[0].geometry.components[0].y, 59.4140625, 'Reading line feature gives correct y');
+ }
+
+ function test_Format_GeoJSON_poly(t) {
+ t.plan(2);
+
+ data = parser.read(poly_content);
+ t.eq(data[0].fid, 562, "poly id is correct");
+ t.eq(data[0].geometry.components[0].components.length, 8,
+ 'Reading polygon first ring on feature from featurecollection gives correct length');
+ }
+
+ function test_Format_GeoJSON_multipoint(t) {
+ t.plan(5);
+
+ var multipoint = {
+ "type": "MultiPoint",
+ "coordinates": [
+ [100.0, 0.0], [101.0, 1.0]
+ ]
+ };
+ data = parser.read(multipoint, "Geometry");
+ t.eq(data.components.length, 2,
+ "Right number of components");
+ t.eq(data.components[0].CLASS_NAME, "OpenLayers.Geometry.Point", "First component is point");
+ t.eq(data.components[1].CLASS_NAME, "OpenLayers.Geometry.Point", "Second component is point");
+ t.eq(data.components[1].x, 101, "x of second component is right");
+ t.eq(data.components[1].y, 1, "y of second component is right");
+ }
+
+ function test_Format_GeoJSON_multipoint_projected(t) {
+ t.plan(1);
+ var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint([
+ new OpenLayers.Geometry.Point(15555162, 4247484)]));
+ var format = new OpenLayers.Format.GeoJSON({
+ internalProjection: new OpenLayers.Projection("EPSG:900913"),
+ externalProjection: new OpenLayers.Projection("EPSG:4326")
+ });
+ var data = format.write(f);
+ var found = (data.search('139.734') != -1);
+ t.ok(found, "Found 139.734 (correct reprojection) in data output.");
+ }
+
+ function test_Format_GeoJSON_multiline(t) {
+ t.plan(3);
+
+ var multiline = {
+ "type": "MultiLineString",
+ "coordinates": [
+ [ [100.0, 0.0], [101.0, 1.0] ],
+ [ [102.0, 2.0], [103.0, 3.0] ]
+ ]
+ };
+ data = parser.read(multiline, "Geometry");
+ t.eq(data.CLASS_NAME, "OpenLayers.Geometry.MultiLineString", "Correct class retrieved");
+ t.eq(data.components[0].components[0].CLASS_NAME, "OpenLayers.Geometry.Point", "correct type of components");
+ t.eq(data.components[0].CLASS_NAME, "OpenLayers.Geometry.LineString", "correct type of components");
+ }
+
+ function test_Format_GeoJSON_multipol(t) {
+ t.plan(2);
+
+ var multipol = {
+ "type": "MultiPolygon",
+ "coordinates": [
+ [
+ [ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]
+ ],
+ [
+ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
+ [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
+ ]
+ ]
+ };
+ OpenLayers.Console.error = function(error) { window.global_error = error; };
+ data = parser.read(multipol, "Geometry");
+ t.eq(data.CLASS_NAME, "OpenLayers.Geometry.MultiPolygon", "Correct class retrieved");
+ t.eq(data.components[1].components[0].components[0].CLASS_NAME, "OpenLayers.Geometry.Point", "correct type of components");
+ }
+
+ function test_Format_GeoJSON_box(t) {
+ t.plan(6);
+
+ var box = {
+ "type": "Box",
+ "coordinates": [[100.0, 0.0], [101.0, 1.0]]
+ };
+ var poly = parser.read(box, "Geometry");
+ t.eq(poly.CLASS_NAME, "OpenLayers.Geometry.Polygon", "Box creates polygon");
+ t.eq(poly.components[0].components[1].x, 101, "x of lower right is correct");
+ t.eq(poly.components[0].components[1].y, 0, "y of lower right is correct");
+ t.eq(poly.components[0].components[3].x, 100, "x of upper left is correct");
+ t.eq(poly.components[0].components[3].y, 1, "y of upper left is correct");
+ box = parser.write(poly );
+ t.ok(box.search("Polygon") != -1 , "Serializes back to polygon");
+ }
+
+ // This test is from the geom_collection example on geojson spec.
+ function test_Format_GeoJSON_collection(t) {
+ t.plan(12);
+
+ var geomcol = {
+ "type": "GeometryCollection",
+ "geometries": [
+ {
+ "type": "Point",
+ "coordinates": [100.0, 0.0]
+ },
+ {
+ "type": "LineString",
+ "coordinates": [
+ [101.0, 0.0], [102.0, 1.0]
+ ]
+ }
+ ]
+ };
+ data = parser.read(geomcol, "Geometry");
+ t.eq(data.CLASS_NAME, "OpenLayers.Geometry.Collection",
+ "GeometryCollection deserialized into geometry.collection");
+ t.eq(data.components[0].CLASS_NAME, "OpenLayers.Geometry.Point",
+ "First geom is correct type");
+ t.eq(data.components[0].x, 100,
+ "First geom in geom collection has correct x");
+ t.eq(data.components[0].y, 0,
+ "First geom in geom collection has correct x");
+
+ t.eq(data.components[1].CLASS_NAME, "OpenLayers.Geometry.LineString",
+ "Second geom in geom collection is point linestring");
+ t.eq(data.components[1].components.length, 2,
+ "linestring is correct length");
+ t.eq(data.components[1].components[1].x, 102,
+ "linestring is correct x end");
+ t.eq(data.components[1].components[1].y, 1,
+ "linestring is correct y end");
+
+ data = parser.read(geomcol, "FeatureCollection");
+ t.eq(data[0].CLASS_NAME, "OpenLayers.Feature.Vector",
+ "GeometryCollection can be read in as a feature collection");
+ t.eq(data[0].geometry.CLASS_NAME, "OpenLayers.Geometry.Collection",
+ "feature contains the correct geometry type");
+ var feature = {
+ "type": "Feature",
+ "geometry": {
+ "type": "GeometryCollection",
+ "geometries": [
+ {
+ "type": "Point",
+ "coordinates": [100.0, 0.0]
+ },
+ {
+ "type": "LineString",
+ "coordinates": [
+ [101.0, 0.0], [102.0, 1.0]
+ ]
+ }
+ ]
+ },
+ "properties": {
+ "prop0": "value0",
+ "prop1": "value1"
+ }
+ };
+ data = parser.read(feature, "Feature");
+ t.eq(data.geometry.CLASS_NAME, "OpenLayers.Geometry.Collection", "Geometry of feature is a collection");
+ var l = new OpenLayers.Layer.Vector();
+ l.addFeatures(data);
+ t.ok(true, "adding a feature with geomcollection to layer doesn't cause error.");
+ }
+
+ function test_Format_GeoJSON_multipleFeatures(t) {
+ t.plan(2);
+
+ var feats = parser.read(multiple_features);
+ t.eq(feats.length, 19, "parsing a feature collection returns the correct number of features.");
+ var types = {'Point':0, 'LineString':0, 'Polygon':0};
+ for(var i = 0; i < feats.length; i++) {
+ var type = feats[i].geometry.CLASS_NAME.replace("OpenLayers.Geometry.", "");
+ types[type]++;
+ }
+ t.eq(types, {'Point':15, 'Polygon': 2, 'LineString':2}, "Correct number of each type");
+ }
+
+ function test_Format_GeoJSON_writeWithCRS(t) {
+ t.plan(2);
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));
+ feature.fid = 0;
+ var output = '{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]},"id":0,"crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}';
+ var layer = new OpenLayers.Layer.Vector();
+ layer.projection = "EPSG:4326";
+ feature.layer = layer;
+ var parser = new OpenLayers.Format.GeoJSON();
+ var test_out = parser.write(feature);
+ t.eq(test_out, output, "Output is equal for vector with layer in EPSG:4326 ");
+ feature.layer.projection = "EPSG:2805";
+ output = '{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]},"id":0,"crs":{"type":"name","properties":{"name":"EPSG:2805"}}}';
+ test_out = parser.write(feature);
+ t.eq(test_out, output, "Output is equal for vector with point");
+ }
+
+ function test_Format_GeoJSON_write(t) {
+ t.plan(10);
+
+ var line_object = {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [-27.0703125, 59.4140625],
+ [-77.6953125, 20.7421875],
+ [30.5859375, -36.2109375],
+ [67.1484375, 34.8046875]
+ ]
+ },
+ "type": "Feature",
+ "id": 559,
+ "properties": {
+ "strokeColor": "red",
+ "title": "Feature 1",
+ "author": "Your Name Here"
+ }
+ }
+ ]
+ };
+ data = parser.read(line_object);
+ out = parser.write(data);
+ serialized = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"strokeColor":"red","title":"Feature 1","author":"Your Name Here"},"geometry":{"type":"LineString","coordinates":[[-27.0703125,59.4140625],[-77.6953125,20.7421875],[30.5859375,-36.2109375],[67.1484375,34.8046875]]},"id":559}]}';
+ t.eq(out, serialized, "input and output on line collections are the same");
+
+ var serialize_tests = [
+ [
+ new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2)),
+ '{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]},"id":0}'
+ ],
+ [
+ new OpenLayers.Geometry.Point(1,2),
+ '{"type":"Point","coordinates":[1,2]}'
+ ],
+ [
+ new OpenLayers.Geometry.MultiPoint([
+ new OpenLayers.Geometry.Point(1,2)
+ ]),
+ '{"type":"MultiPoint","coordinates":[[1,2]]}'
+ ],
+ [
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1,2),
+ new OpenLayers.Geometry.Point(3,4)
+ ]),
+ '{"type":"LineString","coordinates":[[1,2],[3,4]]}'
+ ],
+ [
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1,2),
+ new OpenLayers.Geometry.Point(3,4),
+ new OpenLayers.Geometry.Point(5,6)
+ ])
+ ]),
+ '{"type":"Polygon","coordinates":[[[1,2],[3,4],[5,6],[1,2]]]}'
+ ],
+ [
+ new OpenLayers.Geometry.Collection([
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(1,2),
+ new OpenLayers.Geometry.Point(3,4),
+ new OpenLayers.Geometry.Point(5,6)
+ ])
+ ]),
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1,2),
+ new OpenLayers.Geometry.Point(3,4)
+ ]),
+ new OpenLayers.Geometry.Point(1,2)
+ ]),
+ '{"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]}]}'
+ ]
+ ];
+ serialize_tests[0][0].fid = 0;
+ multiline = new OpenLayers.Geometry.MultiLineString([serialize_tests[3][0], serialize_tests[3][0]]);
+ serialize_tests.push([multiline, '{"type":"MultiLineString","coordinates":[[[1,2],[3,4]],[[1,2],[3,4]]]}']);
+ multipolygon = new OpenLayers.Geometry.MultiPolygon([serialize_tests[4][0], serialize_tests[4][0]]);
+ serialize_tests.push([multipolygon, '{"type":"MultiPolygon","coordinates":[[[[1,2],[3,4],[5,6],[1,2]]],[[[1,2],[3,4],[5,6],[1,2]]]]}']);
+ serialize_tests.push([ [ serialize_tests[0][0] ], '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[1,2]},"id":0}]}' ]);
+ for (var i = 0; i < serialize_tests.length; i++) {
+ var input = serialize_tests[i][0];
+ var output = serialize_tests[i][1];
+ test_out = parser.write(input);
+ t.eq(test_out, output, "Serializing " + input.toString() + " saved correctly.");
+ }
+ }
+
+ function test_write_no_fid(t) {
+ t.plan(4);
+
+ var geojson;
+ var feature = new OpenLayers.Feature.Vector();
+
+ feature.fid = null;
+ geojson = parser.write(feature);
+ t.eq(geojson, '{"type":"Feature","properties":{},"geometry":null}',
+ "no id set in the GeoJSON string when fid is null");
+
+ feature.fid = undefined;
+ geojson = parser.write(feature);
+ t.eq(geojson, '{"type":"Feature","properties":{},"geometry":null}',
+ "no id set in the GeoJSON string when fid is undefined");
+
+ feature.fid = 0;
+ geojson = parser.write(feature);
+ t.eq(geojson, '{"type":"Feature","properties":{},"geometry":null,"id":0}',
+ "id set in the GeoJSON string when fid is 0");
+
+ delete feature.fid;
+ geojson = parser.write(feature);
+ t.eq(geojson, '{"type":"Feature","properties":{},"geometry":null}',
+ "id not set in the GeoJSON string when fid is delected");
+ }
+
+ function test_Format_GeoJSON_read_object(t) {
+ t.plan(1);
+
+ var line_object = {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [-27.0703125, 59.4140625],
+ [-77.6953125, 20.7421875],
+ [30.5859375, -36.2109375],
+ [67.1484375, 34.8046875]
+ ]
+ },
+ "type": "Feature",
+ "id": 559,
+ "properties": {
+ "strokeColor": "red",
+ "title": "Feature 1",
+ "author": "Your Name Here"
+ }
+ }
+ ]
+ };
+ data = parser.read(line_object);
+ t.eq(data[0].fid, 559, "Can read data from an object correctly.");
+ }
+
+ function test_Format_GeoJSON_read_attributes(t) {
+ t.plan(3);
+
+ var parser = new OpenLayers.Format.GeoJSON();
+ data = parser.read(line_feature);
+ t.eq(data[0].attributes['strokeColor'], 'red', 'read strokeColor attribute properly');
+ t.eq(data[0].attributes['title'], 'Feature 1', 'read title attribute properly');
+ t.eq(data[0].attributes['author'], 'Your Name Here', 'read author attribute properly');
+ }
+
+ function test_read_bbox(t) {
+ t.plan(8);
+
+ var f;
+ parser = new OpenLayers.Format.GeoJSON();
+
+ // 4 tests
+ f = '{"geometry": {"type": "Point", "coordinates": [94.21875, 72.94921875], "bbox": [94.21875, 72.94921875, 94.21875, 72.94921875]}, "type": "Feature", "id": 573, "properties": {}, "bbox": [95.0, 73.0]}';
+ data = parser.read(f);
+ t.eq(data[0].bounds.left, 94.21875, "read left bound is correct");
+ t.eq(data[0].bounds.bottom, 72.94921875, "read bottom left bound is correct");
+ t.eq(data[0].bounds.right, 94.21875, "read right bound is correct");
+ t.eq(data[0].bounds.top, 72.94921875, "read top left bound is correct");
+
+ // 4 tests
+ f = '{"geometry": {"type": "Point", "coordinates": [94.21875, 72.94921875]}, "type": "Feature", "id": 573, "properties": {}, "bbox": [95.0, 73.0, 96.0, 74.0]}';
+ data = parser.read(f);
+ t.eq(data[0].bounds.left, 95.0, "read left bound is correct");
+ t.eq(data[0].bounds.bottom, 73.0, "read bottom left bound is correct");
+ t.eq(data[0].bounds.right, 96.0, "read right bound is correct");
+ t.eq(data[0].bounds.top, 74.0, "read top left bound is correct");
+ }
+
+ function test_Format_GeoJSON_point_extradims(t) {
+ t.plan(3);
+ var point_feature_3d = '{"geometry": {"type": "Point", "coordinates": [94.21875, 72.94921875, 0.0]}, "type": "Feature", "id": 573, "properties": {"strokeColor": "blue", "title": "Feature 5", "author": "Your Name Here"}}';
+ p = new OpenLayers.Format.GeoJSON({"ignoreExtraDims": true});
+ data = p.read(point_feature_3d);
+ t.eq(data[0].fid, 573, "Fid is correct on point feature");
+ t.eq(data[0].geometry.x, 94.21875, 'Reading point feature gives correct x');
+ data = p.read(point_feature_3d, "Feature");
+ t.eq(data.fid, 573, 'Reading point feature with type gives feature instead of array of features ');
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/GeoRSS.html b/misc/openlayers/tests/Format/GeoRSS.html
new file mode 100644
index 0000000..6e82f05
--- /dev/null
+++ b/misc/openlayers/tests/Format/GeoRSS.html
@@ -0,0 +1,122 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_Format_GeoRSS_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.GeoRSS(options);
+ t.ok(format instanceof OpenLayers.Format.GeoRSS,
+ "new OpenLayers.Format.GeoRSS returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ function test_Format_GeoRSS_serializeline(t) {
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.GeoRSS();
+ var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
+ var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68);
+ var l = new OpenLayers.Geometry.LineString([point, point2]);
+ var f = new OpenLayers.Feature.Vector(l);
+ var data = parser.write([f]);
+ t.xml_eq(data, '<rss xmlns="http://backend.userland.com/rss2"><item><title></title><description></description><georss:line xmlns:georss="http://www.georss.org/georss">45.68 -111.04 45.68 -112.04</georss:line></item></rss>', 'GeoRSS serializes a line correctly');
+ }
+ function test_Format_GeoRSS_box(t) {
+ t.plan(4);
+ var xml = '<rss xmlns="http://backend.userland.com/rss2"><item><title></title><description></description><georss:box xmlns:georss="http://www.georss.org/georss">45.68 -112.04 47.68 -111.04</georss:box></item></rss>';
+ var format = new OpenLayers.Format.GeoRSS();
+ var features = format.read(xml);
+ t.eq(features.length, 1, "one feature returned");
+ t.eq(features[0].geometry.components[0].components.length, 5, "polygon returned");
+ t.eq(features[0].geometry.components[0].components[0].x, -112.04, "polygon returned with correct first x");
+ t.eq(features[0].geometry.components[0].components[0].y, 45.68, "polygon returned with correct first y");
+ }
+ function test_Format_GeoRSS_w3cgeo(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.GeoRSS();
+ var data = parser.read('<rss xmlns="http://backend.userland.com/rss2" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"><item><geo:long>-1</geo:long><geo:lat>1</geo:lat></item></rss>');
+ t.eq(data[0].geometry.x, -1, "w3c geo x read correctly");
+ t.eq(data[0].geometry.y, 1, "w3c geo y read correctly");
+ }
+ function test_Format_GeoRSS_reproject_null(t) {
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.GeoRSS({'internalProjection':new OpenLayers.Projection("EPSG:4326"), 'externalProjection': new OpenLayers.Projection("EPSG:4326")});
+ var data = parser.read('<rss xmlns="http://backend.userland.com/rss2" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"><item></item></rss>');
+ t.eq(data.length, 1, "Parsing items with null geometry and reprojection doesn't fail");
+ }
+ function test_Format_GeoRSS_roundtrip(t) {
+ t.plan(input.length);
+ var parser = new OpenLayers.Format.GeoRSS();
+ for(var i=0; i < input.length; i++) {
+ var feed = shell_start+input[i]+shell_end;
+ var data = parser.read(feed);
+ var out = parser.write(data);
+ var expected_result = output[i];
+ t.xml_eq(out, expected_result, "Output gave expected value");
+ }
+ }
+ function test_Format_GeoRSS_gml_roundtrip(t) {
+ t.plan(input_gml.length);
+ var parser = new OpenLayers.Format.GeoRSS();
+ for(var i=0; i < input_gml.length; i++) {
+ var feed = shell_start_gml+input_gml[i]+shell_end_gml;
+ var data = parser.read(feed);
+ var out = parser.write(data);
+ var expected_result = output_gml[i];
+ t.xml_eq(out, expected_result, "Output gave expected value");
+ }
+ }
+
+ function test_leading_space(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.GeoRSS();
+ var items = parser.read('<rss version="2.0" xmlns:georss="http://www.georss.org/georss"><item><description> <![CDATA[foo]]></description></item></rss>');
+ t.eq(items.length, 1, "item created");
+
+ // when parsing a node composed of both spaces and a cdata section
+ // (e.g. <description> <![DATA[foo]]></description> IE8 ignores
+ // the leading white spaces, and reports that the node does not
+ // include a text node. For that reason, we need to trim the
+ // string value resulting from the parsing.
+
+ var description = OpenLayers.String.trim(items[0].attributes.description);
+ t.eq(description, "foo", "description value is ok");
+ }
+
+ var shell_start = '<feed xmlns="http://www.w3.org/2005/Atom" \n xmlns:georss="http://www.georss.org/georss">\n <title>scribble</title>\n <id>http://featureserver.org/featureserver.cgi/scribble?format=atom</id>\n <author><name>FeatureServer</name></author>\n';
+ var shell_end = '</feed>';
+ var input = ['<entry><id>http://featureserver.org/featureserver.cgi/scribble/562.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/562.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:polygon>-5.9765625 -131.484375 -58.0078125 -112.5 -50.2734375 -32.34375 52.3828125 -114.609375 -35.5078125 -167.34375 -57.3046875 -146.953125 -34.1015625 -139.921875 -5.9765625 -131.484375</georss:polygon></entry>',
+ '<entry><id>http://featureserver.org/featureserver.cgi/scribble/796.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/796.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: 00ccff&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:point>75.5859375 15.46875</georss:point></entry>',
+ '<entry><id>http://featureserver.org/featureserver.cgi/scribble/794.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/794.atom"/><title>Feature 5</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 5&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:line>28.828125 32.6953125 49.921875 34.8046875 39.375 58.0078125 39.375 58.0078125 40.078125 58.0078125 41.484375 58.0078125 43.59375 58.0078125 45.703125 58.7109375 47.8125 58.7109375 49.21875 58.7109375 51.328125 59.4140625 52.03125 59.4140625 54.140625 60.8203125 56.25 61.5234375 56.25 62.2265625 57.65625 62.2265625 57.65625 62.9296875 58.359375 63.6328125 58.359375 65.0390625 58.359375 65.7421875 59.0625 66.4453125 59.0625 67.1484375 59.0625 68.5546875 59.765625 69.9609375 59.765625 72.0703125 59.765625 73.4765625 59.765625 76.2890625 59.765625 78.3984375 59.765625 79.8046875 59.765625 81.9140625 59.765625 83.3203125 59.0625 84.7265625 59.0625 86.8359375 58.359375 87.5390625 58.359375 88.2421875 56.953125 89.6484375 56.25 91.0546875 54.84375 93.8671875 52.03125 96.6796875 51.328125 98.7890625 50.625 100.1953125 49.21875 102.3046875 48.515625 103.7109375 47.8125 104.4140625 47.109375 105.8203125 46.40625 106.5234375 46.40625 107.9296875 45.703125 109.3359375 45 110.7421875 43.59375 112.8515625 43.59375 114.2578125 43.59375 114.9609375 42.890625 117.0703125 42.890625 117.7734375 42.1875 118.4765625 42.1875 119.1796875 42.1875 119.8828125</georss:line></entry>'
+ ];
+ var output= ['<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/562.atom</link><georss:polygon xmlns:georss="http://www.georss.org/georss">-5.9765625 -131.484375 -58.0078125 -112.5 -50.2734375 -32.34375 52.3828125 -114.609375 -35.5078125 -167.34375 -57.3046875 -146.953125 -34.1015625 -139.921875 -5.9765625 -131.484375</georss:polygon></item></rss>',
+ '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: 00ccff&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/796.atom</link><georss:point xmlns:georss="http://www.georss.org/georss">75.5859375 15.46875</georss:point></item></rss>',
+ '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 5</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 5&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/794.atom</link><georss:line xmlns:georss="http://www.georss.org/georss">28.828125 32.6953125 49.921875 34.8046875 39.375 58.0078125 39.375 58.0078125 40.078125 58.0078125 41.484375 58.0078125 43.59375 58.0078125 45.703125 58.7109375 47.8125 58.7109375 49.21875 58.7109375 51.328125 59.4140625 52.03125 59.4140625 54.140625 60.8203125 56.25 61.5234375 56.25 62.2265625 57.65625 62.2265625 57.65625 62.9296875 58.359375 63.6328125 58.359375 65.0390625 58.359375 65.7421875 59.0625 66.4453125 59.0625 67.1484375 59.0625 68.5546875 59.765625 69.9609375 59.765625 72.0703125 59.765625 73.4765625 59.765625 76.2890625 59.765625 78.3984375 59.765625 79.8046875 59.765625 81.9140625 59.765625 83.3203125 59.0625 84.7265625 59.0625 86.8359375 58.359375 87.5390625 58.359375 88.2421875 56.953125 89.6484375 56.25 91.0546875 54.84375 93.8671875 52.03125 96.6796875 51.328125 98.7890625 50.625 100.1953125 49.21875 102.3046875 48.515625 103.7109375 47.8125 104.4140625 47.109375 105.8203125 46.40625 106.5234375 46.40625 107.9296875 45.703125 109.3359375 45 110.7421875 43.59375 112.8515625 43.59375 114.2578125 43.59375 114.9609375 42.890625 117.0703125 42.890625 117.7734375 42.1875 118.4765625 42.1875 119.1796875 42.1875 119.8828125</georss:line></item></rss>'
+ ];
+
+ var shell_start_gml = '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss"> <title>scribble</title><id>http://featureserver.org/featureserver.cgi/scribble?format=atom</id><author><name>FeatureServer</name></author>';
+ var shell_end_gml = '</feed>';
+ var input_gml = ['<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/111.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:Point><gml:pos>0 10</gml:pos></gml:Point></georss:where></entry>',
+ '<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/111.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>110,-50 110,-10 155,-10 155,-50 110,-50</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></georss:where></entry>',
+ '<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/111.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:LineString><gml:coordinates>0,10 10,20</gml:coordinates></gml:LineString></georss:where></entry>',
+ '<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href="http://featureserver.org/featureserver.cgi/scribble/111.atom"/><title>Feature 2</title><content type="html">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:Envelope><gml:lowerCorner>0 1</gml:lowerCorner><gml:upperCorner>20 21</gml:upperCorner></gml:Envelope></georss:where></entry>'
+ ];
+ var output_gml = ['<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:point xmlns:georss="http://www.georss.org/georss">0 10</georss:point></item></rss>',
+ '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:polygon xmlns:georss="http://www.georss.org/georss">110 -50 110 -10 155 -10 155 -50 110 -50</georss:polygon></item></rss>',
+ '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:line xmlns:georss="http://www.georss.org/georss">0 10 10 20</georss:line></item></rss>',
+ '<rss xmlns="http://backend.userland.com/rss2"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:polygon xmlns:georss="http://www.georss.org/georss">0 1 0 21 20 21 20 1 0 1</georss:polygon></item></rss>'
+ ];
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/JSON.html b/misc/openlayers/tests/Format/JSON.html
new file mode 100644
index 0000000..84461e1
--- /dev/null
+++ b/misc/openlayers/tests/Format/JSON.html
@@ -0,0 +1,53 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_Format_JSON_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.JSON(options);
+ t.ok(format instanceof OpenLayers.Format.JSON,
+ "new OpenLayers.Format.JSON returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ function test_Format_JSON_parser(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.JSON();
+ var data = format.read('{"a":["b"], "c":1}');
+ var obj = {"a":["b"], "c":1};
+ t.eq(obj['a'], data['a'], "element with array parsed correctly.");
+ t.eq(obj['c'], data['c'], "element with number parsed correctly.");
+ }
+
+ function test_Format_JSON_writer(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.JSON();
+ var data = format.write({"a":["b"], "c":1});
+ var obj = '{"a":["b"],"c":1}';
+ t.eq(data, obj, "writing data to json works.");
+ }
+
+
+ function test_keepData(t) {
+ t.plan(2);
+
+ var options = {'keepData': true};
+ var format = new OpenLayers.Format.JSON(options);
+ format.read('{"a":["b"], "c":1}');
+
+ t.ok(format.data != null, 'data property is not null after read with keepData=true');
+ t.eq(format.data.c,1,'keepData keeps the right data');
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/KML.html b/misc/openlayers/tests/Format/KML.html
new file mode 100644
index 0000000..ba87637
--- /dev/null
+++ b/misc/openlayers/tests/Format/KML.html
@@ -0,0 +1,1437 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var test_content = '<kml xmlns="http://earth.google.com/kml/2.0"><Folder><name>OpenLayers export</name><description>Vector geometries from OpenLayers</description><Placemark id="KML.Polygon"><name>OpenLayers.Feature.Vector_344</name><description>A KLM Polygon</description><Polygon><outerBoundaryIs><LinearRing><coordinates>5.001370157823406,49.26855713824488 8.214706453896161,49.630662409673505 8.397385910100951,48.45172350357396 5.001370157823406,49.26855713824488</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark><Placemark id="KML.LineString"><name>OpenLayers.Feature.Vector_402</name><description>A KML LineString</description><LineString><coordinates>5.838523393080493,49.74814616928052 5.787079558782349,48.410795432216574 8.91427702008381,49.28932499608202</coordinates></LineString></Placemark><Placemark id="KML.Point"><name>OpenLayers.Feature.Vector_451</name><description>A KML Point</description><Point><coordinates>6.985073041685488,49.8682250149058</coordinates></Point></Placemark><Placemark id="KML.MultiGeometry"><name>SF Marina Harbor Master</name><description>KML MultiGeometry</description><MultiGeometry><LineString><coordinates>-122.4425587930444,37.80666418607323 -122.4428379594768,37.80663578323093</coordinates></LineString><LineString><coordinates>-122.4425509770566,37.80662588061205 -122.4428340530617,37.8065999493009</coordinates></LineString></MultiGeometry></Placemark></Folder></kml>';
+ var test_style = '<kml xmlns="http://earth.google.com/kml/2.0"> <Placemark> <Style> <LineStyle> <color>870000ff</color> <width>10</width> </LineStyle> </Style> <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark></kml>';
+ var test_style_fill = '<kml xmlns="http://earth.google.com/kml/2.0"> <Placemark> <Style> <PolyStyle> <fill>1</fill> <color>870000ff</color> <width>10</width> </PolyStyle> </Style> <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark><Placemark> <Style> <PolyStyle> <fill>0</fill> <color>870000ff</color> <width>10</width> </PolyStyle> </Style> <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark></kml>';
+ var test_style_outline = '<kml xmlns="http://earth.google.com/kml/2.0"> <Placemark> <Style> <PolyStyle> <outline>0</outline> <color>870000ff</color> <width>10</width> </PolyStyle> </Style> <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark></kml>';
+ var test_style_font = '<kml xmlns="http://earth.google.com/kml/2.0"> <Placemark><Style><LabelStyle><color>870000ff</color><scale>1.5</scale></LabelStyle></Style><LineString><coordinates> -112,36 -113,37 </coordinates></LineString></Placemark></kml>';
+ var test_nl = '<kml xmlns="http://earth.google.com/kml/2.2"> <Document> <NetworkLink> <Link> <href>http://maker.geocommons.com/maps/1717/overlays/0</href> </Link> </NetworkLink> </Document></kml>';
+ function test_Format_KML_constructor(t) {
+ t.plan(5);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.KML(options);
+ t.ok(format instanceof OpenLayers.Format.KML,
+ "new OpenLayers.Format.KML returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ t.eq(format.externalProjection.getCode(), "EPSG:4326",
+ "default external projection is EPSG:4326");
+ }
+ function test_Format_KML_multipoint(t) {
+ t.plan(1);
+ var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint([
+ new OpenLayers.Geometry.Point(15555162, 4247484)]));
+ var format = new OpenLayers.Format.KML({
+ extractStyles: true,
+ extractAttributes: true,
+ internalProjection: new OpenLayers.Projection("EPSG:900913"),
+ externalProjection: new OpenLayers.Projection("EPSG:4326")
+ });
+ var data = format.write(f);
+ var found = (data.search('139.734') != -1);
+ t.ok(found, "Found 139.734 (correct reprojection) in data output.");
+ }
+ function test_Format_KML_read(t) {
+ t.plan(5);
+ var features = (new OpenLayers.Format.KML()).read(this.test_content);
+ t.eq(features.length, 4, "Number of features read is correct");
+ t.ok(features[0].geometry.toString() == "POLYGON((5.001370157823406 49.26855713824488,8.214706453896161 49.630662409673505,8.397385910100951 48.45172350357396,5.001370157823406 49.26855713824488))", "polygon feature geometry correctly created");
+ t.ok(features[1].geometry.toString() == "LINESTRING(5.838523393080493 49.74814616928052,5.787079558782349 48.410795432216574,8.91427702008381 49.28932499608202)", "linestring feature geometry correctly created");
+ t.ok(features[2].geometry.toString() == "POINT(6.985073041685488 49.8682250149058)", "point feature geometry correctly created");
+ t.ok(features[3].geometry.CLASS_NAME == "OpenLayers.Geometry.Collection",
+ "read geometry collection");
+ }
+
+
+ function test_Format_KML_readCdataAttributes_20(t) {
+ t.plan(2);
+ var cdata = '<kml xmlns="http://earth.google.com/kml/2.0"><Document><Placemark><name><![CDATA[Pezinok]]> </name><description><![CDATA[Full of text.]]></description><styleUrl>#rel1.0</styleUrl><Point> <coordinates>17.266666, 48.283333</coordinates></Point></Placemark></Document></kml>';
+ var features = (new OpenLayers.Format.KML()).read(cdata);
+ t.eq(features[0].attributes.description, "Full of text.", "Description attribute in cdata read correctly");
+ t.eq(features[0].attributes.name, "Pezinok", "title attribute in cdata read correctly");
+
+ }
+
+ function test_Format_KML_networklink(t) {
+ t.plan(1);
+ var f = new OpenLayers.Format.KML({'maxDepth':1});
+ f.fetchLink = function(url) {
+ t.eq(url, "http://maker.geocommons.com/maps/1717/overlays/0", "network link fetched a link correctly.");
+ return '';
+ }
+ f.read(test_nl);
+ }
+ function test_Format_KML_readCdataAttributes_21(t) {
+ t.plan(2);
+ var cdata = '<kml xmlns="http://earth.google.com/kml/2.1"><Document><Placemark><name><![CDATA[Pezinok]]></name><description><![CDATA[Full of text.]]></description><styleUrl>#rel1.0</styleUrl><Point> <coordinates>17.266666, 48.283333</coordinates></Point></Placemark></Document></kml>';
+ var features = (new OpenLayers.Format.KML()).read(cdata);
+ t.eq(features[0].attributes.description, "Full of text.", "Description attribute in cdata read correctly");
+ t.eq(features[0].attributes.name, "Pezinok", "title attribute in cdata read correctly");
+
+ }
+
+ function test_Format_KML_write(t) {
+ // make sure id, name, and description are preserved
+ t.plan(1);
+ var kmlExpected = this.test_content;
+ var options = {
+ foldersName: "OpenLayers export",
+ foldersDesc: "Vector geometries from OpenLayers"
+ };
+
+ var format = new OpenLayers.Format.KML(options);
+ var features = format.read(kmlExpected);
+ var kmlOut = format.write(features);
+ var kmlOut = kmlOut.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(kmlOut, kmlExpected, "correctly writes an KML doc string");
+ }
+
+ function test_Format_KML_write_noNameDesc(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.KML({
+ foldersName: null,
+ foldersDesc: null
+ });
+ var geom = new OpenLayers.Geometry.Point(0, 0)
+ var feature = new OpenLayers.Feature.Vector(geom);
+ feature.id = 42;
+ var kmlOut = format.write(feature);
+ var expected = '<kml xmlns="http://earth.google.com/kml/2.0"><Folder><Placemark><name>42</name><description>No description available</description><Point><coordinates>0,0</coordinates></Point></Placemark></Folder></kml>'
+ t.eq(kmlOut, expected, "null foldersName or foldersDesc don't create elements");
+ }
+
+ function test_Format_KML_write_multis(t) {
+ /**
+ * KML doesn't have a representation for multi geometries of a
+ * specific type. KML MultiGeometry maps to OL Geometry.Collection.
+ * Because of this, multi-geometries in OL can't make a round trip
+ * through KML (an OL MultiPoint maps to a KML MultiGeometry
+ * containing points, which maps back to an OL Collection containing
+ * points). So we need to acceptance tests for the writing of
+ * multi-geometries specifically instead of relying on the round-trip
+ * write test above.
+ */
+ t.plan(3);
+ var format = new OpenLayers.Format.KML({foldersDesc: "test output"});
+ var multi, feature, output, expected;
+
+ // test multipoint
+ var multi = new OpenLayers.Geometry.MultiPoint([
+ new OpenLayers.Geometry.Point(0, 1)
+ ]);
+ feature = new OpenLayers.Feature.Vector(multi, {name: "test name"});
+ output = format.write(feature);
+ expected = '<kml xmlns="http://earth.google.com/kml/2.0"><Folder><name>OpenLayers export</name><description>test output</description><Placemark><name>test name</name><description>No description available</description><MultiGeometry><Point><coordinates>0,1</coordinates></Point></MultiGeometry></Placemark></Folder></kml>';
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, expected, "multipoint correctly written");
+
+ // test multilinestring
+ var multi = new OpenLayers.Geometry.MultiLineString([
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(1, 0),
+ new OpenLayers.Geometry.Point(0, 1)
+ ])
+ ]);
+ feature = new OpenLayers.Feature.Vector(multi, {name: "test name"});
+ output = format.write(feature);
+ expected = '<kml xmlns="http://earth.google.com/kml/2.0"><Folder><name>OpenLayers export</name><description>test output</description><Placemark><name>test name</name><description>No description available</description><MultiGeometry><LineString><coordinates>1,0 0,1</coordinates></LineString></MultiGeometry></Placemark></Folder></kml>';
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, expected, "multilinestring correctly written");
+
+ // test multipolygon
+ var multi = new OpenLayers.Geometry.MultiPolygon([
+ new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(0, 0),
+ new OpenLayers.Geometry.Point(1, 0),
+ new OpenLayers.Geometry.Point(0, 1)
+ ])
+ ])
+ ]);
+ feature = new OpenLayers.Feature.Vector(multi, {name: "test name"});
+ output = format.write(feature);
+ expected = '<kml xmlns="http://earth.google.com/kml/2.0"><Folder><name>OpenLayers export</name><description>test output</description><Placemark><name>test name</name><description>No description available</description><MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>0,0 1,0 0,1 0,0</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry></Placemark></Folder></kml>';
+ var output = output.replace(/<\?[^>]*\?>/, ''); // Remove XML Prolog
+ t.eq(output, expected, "multilinestring correctly written");
+
+ }
+ function test_Format_KML_extractStyle(t) {
+ t.plan(1);
+ var f = new OpenLayers.Format.KML();
+ var features = f.read(test_style);
+ t.ok(features[0].style == undefined, "KML Feature has no style with extractStyle false");
+ }
+ function test_Format_KML_extractStyleFill(t) {
+ t.plan(2);
+ var f = new OpenLayers.Format.KML({extractStyles: true});
+ var features = f.read(test_style_fill);
+ t.eq(features[0].style.fillColor, "#ff0000", "default fill is set");
+ t.eq(features[1].style.fillColor, "none", "KML Feature has none fill");
+ }
+ function test_Format_KML_extractStyleOutline(t) {
+ t.plan(2);
+ var f = new OpenLayers.Format.KML({extractStyles: true});
+ var features = f.read(test_style);
+ t.eq(features[0].style.strokeWidth, "10", "default stroke is set");
+ var features = f.read(test_style_outline);
+ t.eq(features[0].style.strokeWidth, "0", "KML Feature has no outline");
+ }
+ function test_Format_KML_extractStyleFont(t) {
+ t.plan(2);
+ var f = new OpenLayers.Format.KML({extractStyles: true});
+ var features = f.read(test_style_font);
+ t.eq(features[0].style.fontColor, "#ff0000", "font color is set");
+ t.eq(features[0].style.fontOpacity, parseInt('87', 16) / 255, "font opacity is set");
+ }
+ function test_Format_KML_getStyle(t) {
+ t.plan(1);
+ var style = {t: true};
+ var f = new OpenLayers.Format.KML();
+ f.styles = {test: style};
+ var gotStyle = f.getStyle('test');
+ gotStyle.t = false;
+ t.ok(style.t, "getStyle returns copy of style rather than reference");
+ }
+ function test_Format_KML_extendedData(t) {
+ t.plan(6);
+ var f = new OpenLayers.Format.KML();
+ var features = f.read(OpenLayers.Util.getElement("kml_extendeddata").value);
+ t.eq(features[0].attributes.holeYardage.value, "234", "read value from extendeddata correctly.");
+ t.eq(features[0].attributes.holeYardage.displayName, "<b><i>The yardage is </i></b>", "read displayName from extendeddata correctly.");
+ t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage.value, features[0].attributes.holeYardage.value, "attribute value written correctly");
+ t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage.displayName, features[0].attributes.holeYardage.displayName, "attribute displayName written correctly");
+ f.kvpAttributes = true;
+ features = f.read(OpenLayers.Util.getElement("kml_extendeddata").value);
+ t.eq(features[0].attributes.holeYardage, "234", "read kvp value from extendeddata correctly.");
+ t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage, features[0].attributes.holeYardage, "kvp attribute value written correctly");
+ }
+
+ function test_Format_KML_extendedData_SchemaData(t) {
+ t.plan(10);
+ var f = new OpenLayers.Format.KML();
+ var features = f.read(OpenLayers.Util.getElement("kml_extendeddata2").value);
+ t.eq(features[0].attributes.TrailHeadName.value, "Pi in the sky", "read value from extendeddata (schema data) correctly.");
+ t.eq(features[0].attributes.TrailHeadName.displayName, "TrailHeadName", "read displayName from extendeddata correctly");
+ t.eq(features[0].attributes.ElevationGain.value, "10", "read value from extendeddata (schema data) correctly.");
+ t.eq(features[0].attributes.ElevationGain.displayName, "ElevationGain", "read displayName from extendeddata correctly");
+ t.eq(f.read(f.write(features[0]))[0].attributes.TrailHeadName.value, features[0].attributes.TrailHeadName.value, "attribute value from extendeddata (schema data) written correctly");
+ t.eq(f.read(f.write(features[0]))[0].attributes.ElevationGain.value, features[0].attributes.ElevationGain.value, "attribute value from extendeddata (schema data) written correctly");
+ f.kvpAttributes = true;
+ features = f.read(OpenLayers.Util.getElement("kml_extendeddata2").value);
+ t.eq(features[0].attributes.TrailHeadName, "Pi in the sky", "read kvp value from extendeddata (schema data) correctly.");
+ t.eq(features[0].attributes.ElevationGain, "10", "read kvp value from extendeddata (schema data) correctly.");
+ t.eq(f.read(f.write(features[0]))[0].attributes.TrailHeadName, features[0].attributes.TrailHeadName, "kvp attribute value from extendeddata (schema data) written correctly");
+ t.eq(f.read(f.write(features[0]))[0].attributes.ElevationGain, features[0].attributes.ElevationGain, "kvp attribute value from extendeddata (schema data) written correctly");
+ }
+
+ function test_Format_KML_placemarkName(t) {
+ t.plan(3);
+
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
+ var f = new OpenLayers.Format.KML();
+
+ t.eq(f.read(f.write(feature))[0].attributes.name, feature.id, "placemark name from feature.id");
+ feature.style = {
+ label: "placemark name from style.label"
+ };
+ t.eq(f.read(f.write(feature))[0].attributes.name, feature.style.label, "placemark name from style.label");
+
+ feature.attributes.name = "placemark name from attributes.name";
+ t.eq(f.read(f.write(feature))[0].attributes.name, feature.attributes.name, "placemark name from attributes.name");
+ }
+ function test_Format_KML_linestring_projected(t) {
+ t.plan(1);
+ var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(15555162, 4247484), new OpenLayers.Geometry.Point(15555163, 4247485)]));
+ var format = new OpenLayers.Format.KML({
+ internalProjection: new OpenLayers.Projection("EPSG:900913"),
+ externalProjection: new OpenLayers.Projection("EPSG:4326")
+ });
+ var data = format.write(f);
+ var found = (data.search('139.734') != -1);
+ t.ok(found, "Found 139.734 (correct reprojection) in data output.");
+ }
+
+ function test_extractTracks(t) {
+
+ t.plan(13);
+
+ var xml = new OpenLayers.Format.XML();
+ var doc = xml.read(document.getElementById("macnoise.kml").firstChild.nodeValue);
+
+ var format = new OpenLayers.Format.KML({
+ extractTracks: true,
+ trackAttributes: ["speed", "num"] // additional custom attributes
+ });
+
+ var features = format.read(doc.documentElement);
+ t.eq(features.length, 170, "got 170 features");
+
+ var attr = features[4].attributes;
+
+ // standard track point attributes
+ t.ok(attr.when instanceof Date, "features have when attribute");
+ t.eq(attr.when.getTime(), 1272736815000, "correct time for fifth feature");
+ t.eq(attr.altitude, 1006, "altitude parsed");
+ t.eq(attr.heading, 230, "heading parsed");
+ t.eq(attr.tilt, 0, "tilt parsed");
+ t.eq(attr.roll, 0, "roll parsed");
+
+ // custom track attributes (all features acquire from the placemark)
+ t.eq(attr.name, "B752", "correct name");
+ t.eq(attr.adflag, "A", "correct adflag");
+ t.eq(attr.flightid, "DAL2973", "correct flightid");
+
+ // additional per point attributes (determined by trackAttributes property)
+ t.eq(attr.speed, "166", "correct speed");
+ t.eq(attr.num, "50", "correct num");
+
+ var exp = new OpenLayers.Geometry.Point(-93.0753620391713, 44.9879724110872);
+ exp.z = 1006;
+ t.geom_eq(features[4].geometry, exp, "correct geometry");
+
+ }
+
+
+ </script>
+</head>
+<body>
+ <textarea id="kml_extendeddata" style="display:none">
+<?xml version="1.0" encoding="UTF-8"?>
+<kml xmlns="http://www.opengis.net/kml/2.2">
+ <Document>
+ <name>Entity-Replacement</name>
+ <Placemark>
+ <name>Club house</name>
+ <ExtendedData>
+ <Data name="holeNumber">
+ <displayName><![CDATA[
+ <b>This is hole </b>
+ ]]></displayName>
+ <value>1</value>
+ </Data>
+ <Data name="holePar">
+ <displayName><![CDATA[
+ <i>The par for this hole is </i>
+ ]]></displayName>
+ <value>4</value>
+ </Data>
+ <Data name="holeYardage">
+ <displayName><![CDATA[<b><i>The yardage is </i></b>]]></displayName>
+ <value>234</value>
+ </Data>
+ </ExtendedData>
+ <Point>
+ <coordinates>-111.956,33.5043</coordinates>
+ </Point>
+ </Placemark>
+ <Placemark>
+ <name>By the lake</name>
+ <ExtendedData>
+ <Data name="holeNumber">
+ <displayName><![CDATA[
+ <b>This is hole </b>
+ ]]></displayName>
+ <value>5</value>
+ </Data>
+ <Data name="holePar">
+ <displayName><![CDATA[
+ <i>The par for this hole is </i>
+ ]]></displayName>
+ <value>5</value>
+ </Data>
+ <Data name="holeYardage">
+ <displayName><![CDATA[
+ <b><i>The yardage is </i></b>
+ ]]></displayName>
+ <value>523</value>
+ </Data>
+ </ExtendedData>
+ <Point>
+ <coordinates>-111.95,33.5024</coordinates>
+ </Point>
+ </Placemark>
+ </Document>
+</kml>
+</textarea>
+ <textarea id="kml_extendeddata2" style="display:none">
+<kml xmlns="http://earth.google.com/kml/2.2">
+<Document>
+<Placemark>
+ <name>Easy trail</name>
+ <ExtendedData>
+ <SchemaData schemaUrl="#TrailHeadTypeId">
+ <SimpleData name="TrailHeadName">Pi in the sky</SimpleData>
+ <SimpleData name="TrailLength">3.14159</SimpleData>
+ <SimpleData name="ElevationGain">10</SimpleData>
+ </SchemaData>
+ </ExtendedData>
+ <Point>
+ <coordinates>-122.000,37.002</coordinates>
+ </Point>
+</Placemark>
+<Placemark>
+ <name>Difficult trail</name>
+ <ExtendedData>
+ <SchemaData schemaUrl="#TrailHeadTypeId">
+ <SimpleData name="TrailHeadName">Mount Everest</SimpleData>
+ <SimpleData name="TrailLength">347.45</SimpleData>
+ <SimpleData name="ElevationGain">10000</SimpleData>
+ </SchemaData>
+ </ExtendedData>
+ <Point>
+ <coordinates>-122.000,37.002</coordinates>
+ </Point>
+</Placemark>
+</Document>
+</kml>
+</textarea>
+
+<div id="macnoise.kml"><!--
+<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
+<Document>
+<Camera>
+ <gx:TimeStamp>
+ <when>2010-05-01T13:00:00-05:00</when>
+ </gx:TimeStamp>
+ <longitude>-93.2207</longitude>
+ <latitude>44.882</latitude>
+ <altitude>50000</altitude>
+ <heading>0</heading>
+ <tilt>0</tilt>
+</Camera>
+<Style id="arrival">
+ <IconStyle>
+ <Icon>
+ <href>http://maps.macnoise.com/scripts/plane.png</href>
+ </Icon>
+ </IconStyle>
+ <LineStyle>
+ <color>ff0000ff</color>
+ <width>3</width>
+ </LineStyle>
+ <PolyStyle>
+ <color>7fffffff</color>
+ </PolyStyle>
+</Style>
+<Style id="departure">
+ <IconStyle>
+ <Icon>
+ <href>http://maps.macnoise.com/scripts/plane.png</href>
+ </Icon>
+ </IconStyle>
+ <LineStyle>
+ <color>ff00ff00</color>
+ <width>3</width>
+ </LineStyle>
+ <PolyStyle>
+ <color>7fffffff</color>
+ </PolyStyle>
+</Style>
+<Style id="overflight">
+ <IconStyle>
+ <Icon>
+ <href>http://maps.macnoise.com/scripts/plane.png</href>
+ </Icon>
+ </IconStyle>
+ <LineStyle>
+ <color>ff222222</color>
+ <width>3</width>
+ </LineStyle>
+ <PolyStyle>
+ <color>7fffffff</color>
+ </PolyStyle>
+</Style>
+<Style id='rmt'>
+ <LabelStyle>
+ <color>ff0000cc</color>
+ <colorMode>normal</colorMode>
+ <scale>1</scale>
+ </LabelStyle>
+</Style>
+
+<name>Flight Tracks</name>
+<Folder>
+ <name>Arrivals</name>
+<Placemark>
+ <name>B752</name>
+ <adflag>A</adflag>
+ <flightid>DAL2973</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:01-05</when>
+ <when>2010-05-01T13:00:06-05</when>
+ <when>2010-05-01T13:00:10-05</when>
+ <when>2010-05-01T13:00:15-05</when>
+ <when>2010-05-01T13:00:20-05</when>
+ <when>2010-05-01T13:00:24-05</when>
+ <when>2010-05-01T13:00:29-05</when>
+ <when>2010-05-01T13:00:33-05</when>
+ <when>2010-05-01T13:00:38-05</when>
+ <when>2010-05-01T13:00:43-05</when>
+ <when>2010-05-01T13:00:47-05</when>
+ <when>2010-05-01T13:00:52-05</when>
+ <when>2010-05-01T13:00:57-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.0658625188843 44.9949645987875 1036</gx:coord>
+ <gx:coord>-93.0664690096445 44.9945424635331 1036</gx:coord>
+ <gx:coord>-93.0694347065378 44.9923936108644 1036</gx:coord>
+ <gx:coord>-93.0722946883822 44.9901649091109 1006</gx:coord>
+ <gx:coord>-93.0753620391713 44.9879724110872 1006</gx:coord>
+ <gx:coord>-93.078638650624 44.985904678007 975</gx:coord>
+ <gx:coord>-93.0817463907976 44.9836868456013 975</gx:coord>
+ <gx:coord>-93.0847749343212 44.9813998515538 945</gx:coord>
+ <gx:coord>-93.0879207383429 44.9791066547511 914</gx:coord>
+ <gx:coord>-93.091282218058 44.976822731273 914</gx:coord>
+ <gx:coord>-93.0945882606646 44.9745372955479 884</gx:coord>
+ <gx:coord>-93.0979053364864 44.9722421846492 884</gx:coord>
+ <gx:coord>-93.1012678619471 44.9698451058525 853</gx:coord>
+ <gx:coord>-93.1044570741037 44.967424293466 853</gx:coord>
+ <gx:coord>-93.1068079756418 44.9657037851018 853</gx:coord>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <speed>162</speed>
+ <speed>160</speed>
+ <speed>159</speed>
+ <speed>165</speed>
+ <speed>166</speed>
+ <speed>174</speed>
+ <speed>170</speed>
+ <speed>172</speed>
+ <speed>180</speed>
+ <speed>176</speed>
+ <speed>177</speed>
+ <speed>177</speed>
+ <speed>180</speed>
+ <speed>184</speed>
+ <speed>177</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>E170</name>
+ <adflag>A</adflag>
+ <flightid>TCF7521</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:04-05</when>
+ <when>2010-05-01T13:00:09-05</when>
+ <when>2010-05-01T13:00:13-05</when>
+ <when>2010-05-01T13:00:18-05</when>
+ <when>2010-05-01T13:00:23-05</when>
+ <when>2010-05-01T13:00:27-05</when>
+ <when>2010-05-01T13:00:32-05</when>
+ <when>2010-05-01T13:00:37-05</when>
+ <when>2010-05-01T13:00:41-05</when>
+ <when>2010-05-01T13:00:46-05</when>
+ <when>2010-05-01T13:00:51-05</when>
+ <when>2010-05-01T13:00:55-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.3806146339391 44.8823651507134 2743</gx:coord>
+ <gx:coord>-93.3773041814209 44.887531728655 2743</gx:coord>
+ <gx:coord>-93.3742856469083 44.8942041806778 2743</gx:coord>
+ <gx:coord>-93.3722375106026 44.9009231720158 2743</gx:coord>
+ <gx:coord>-93.3711934089417 44.9077495987718 2712</gx:coord>
+ <gx:coord>-93.3707288919852 44.9145219645156 2712</gx:coord>
+ <gx:coord>-93.3703882714439 44.921240089024 2682</gx:coord>
+ <gx:coord>-93.3700882719793 44.9278850664392 2682</gx:coord>
+ <gx:coord>-93.369810041597 44.934389356737 2651</gx:coord>
+ <gx:coord>-93.3696836566166 44.9408553642446 2651</gx:coord>
+ <gx:coord>-93.3695425129226 44.9473561165969 2621</gx:coord>
+ <gx:coord>-93.3693185423471 44.9537360442564 2621</gx:coord>
+ <gx:coord>-93.3693194298816 44.9599975904123 2590</gx:coord>
+ <gx:coord>-93.3694031671108 44.9661411653607 2590</gx:coord>
+ <gx:angles>20 0 0</gx:angles>
+ <gx:angles>20 0 0</gx:angles>
+ <gx:angles>20 0 0</gx:angles>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>360 0 0</gx:angles>
+ <speed>376</speed>
+ <speed>367</speed>
+ <speed>361</speed>
+ <speed>371</speed>
+ <speed>367</speed>
+ <speed>363</speed>
+ <speed>359</speed>
+ <speed>356</speed>
+ <speed>352</speed>
+ <speed>347</speed>
+ <speed>343</speed>
+ <speed>347</speed>
+ <speed>334</speed>
+ <speed>337</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>BE33</name>
+ <adflag>A</adflag>
+ <flightid>N38175</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:02-05</when>
+ <when>2010-05-01T13:00:07-05</when>
+ <when>2010-05-01T13:00:12-05</when>
+ <when>2010-05-01T13:00:16-05</when>
+ <when>2010-05-01T13:00:21-05</when>
+ <when>2010-05-01T13:00:25-05</when>
+ <when>2010-05-01T13:00:30-05</when>
+ <when>2010-05-01T13:00:35-05</when>
+ <when>2010-05-01T13:00:39-05</when>
+ <when>2010-05-01T13:00:44-05</when>
+ <when>2010-05-01T13:00:49-05</when>
+ <when>2010-05-01T13:00:53-05</when>
+ <when>2010-05-01T13:00:58-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.0144637208028 44.6541474764804 1006</gx:coord>
+ <gx:coord>-93.0162681345228 44.6547274296664 1006</gx:coord>
+ <gx:coord>-93.0196734868835 44.6559915702004 975</gx:coord>
+ <gx:coord>-93.0231899415297 44.657188463998 945</gx:coord>
+ <gx:coord>-93.0267619421777 44.6582849847887 945</gx:coord>
+ <gx:coord>-93.0302021384369 44.6594728216183 914</gx:coord>
+ <gx:coord>-93.0338776768471 44.6606515995762 914</gx:coord>
+ <gx:coord>-93.0375866343814 44.6618806707998 884</gx:coord>
+ <gx:coord>-93.0411146687035 44.6632657982455 884</gx:coord>
+ <gx:coord>-93.0447829038862 44.6646495821585 884</gx:coord>
+ <gx:coord>-93.0486933143218 44.6659856209571 914</gx:coord>
+ <gx:coord>-93.0525604964428 44.6672664774449 884</gx:coord>
+ <gx:coord>-93.0559892061682 44.6686325276705 884</gx:coord>
+ <gx:coord>-93.0595122787868 44.6700360197293 884</gx:coord>
+ <gx:coord>-93.0610274392619 44.6706087373734 884</gx:coord>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>290 0 0</gx:angles>
+ <gx:angles>290 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <gx:angles>300 0 0</gx:angles>
+ <speed>150</speed>
+ <speed>156</speed>
+ <speed>152</speed>
+ <speed>156</speed>
+ <speed>151</speed>
+ <speed>152</speed>
+ <speed>160</speed>
+ <speed>157</speed>
+ <speed>159</speed>
+ <speed>158</speed>
+ <speed>158</speed>
+ <speed>160</speed>
+ <speed>155</speed>
+ <speed>155</speed>
+ <speed>156</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>A319</name>
+ <adflag>A</adflag>
+ <flightid>DAL1588</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:04-05</when>
+ <when>2010-05-01T13:00:08-05</when>
+ <when>2010-05-01T13:00:13-05</when>
+ <when>2010-05-01T13:00:18-05</when>
+ <when>2010-05-01T13:00:22-05</when>
+ <when>2010-05-01T13:00:27-05</when>
+ <when>2010-05-01T13:00:31-05</when>
+ <when>2010-05-01T13:00:36-05</when>
+ <when>2010-05-01T13:00:41-05</when>
+ <when>2010-05-01T13:00:45-05</when>
+ <when>2010-05-01T13:00:50-05</when>
+ <when>2010-05-01T13:00:55-05</when>
+ <when>2010-05-01T13:00:59-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.6927825194056 44.7952011849485 3011</gx:coord>
+ <gx:coord>-93.6850156681578 44.7968042586582 2987</gx:coord>
+ <gx:coord>-93.6752785488692 44.7990458605003 2956</gx:coord>
+ <gx:coord>-93.6657083011645 44.8014897663497 2926</gx:coord>
+ <gx:coord>-93.6560029615388 44.803768841381 2865</gx:coord>
+ <gx:coord>-93.6462045264035 44.8058749817725 2834</gx:coord>
+ <gx:coord>-93.6365671200126 44.8080848199989 2804</gx:coord>
+ <gx:coord>-93.6269933807039 44.8102767000109 2773</gx:coord>
+ <gx:coord>-93.6175405757462 44.8123960709083 2743</gx:coord>
+ <gx:coord>-93.6082528975965 44.8146455509748 2743</gx:coord>
+ <gx:coord>-93.599077315807 44.816765612372 2743</gx:coord>
+ <gx:coord>-93.5899428762254 44.8186933623744 2743</gx:coord>
+ <gx:coord>-93.5809104439923 44.8205403457841 2743</gx:coord>
+ <gx:coord>-93.5720785209701 44.8224608846058 2743</gx:coord>
+ <gx:coord>-93.5703603013364 44.8228739543212 2743</gx:coord>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <gx:angles>70 0 0</gx:angles>
+ <speed>390</speed>
+ <speed>383</speed>
+ <speed>397</speed>
+ <speed>390</speed>
+ <speed>405</speed>
+ <speed>388</speed>
+ <speed>386</speed>
+ <speed>397</speed>
+ <speed>377</speed>
+ <speed>373</speed>
+ <speed>367</speed>
+ <speed>362</speed>
+ <speed>365</speed>
+ <speed>350</speed>
+ <speed>354</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>E145</name>
+ <adflag>A</adflag>
+ <flightid>CHQ1453</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:01-05</when>
+ <when>2010-05-01T13:00:06-05</when>
+ <when>2010-05-01T13:00:11-05</when>
+ <when>2010-05-01T13:00:15-05</when>
+ <when>2010-05-01T13:00:20-05</when>
+ <when>2010-05-01T13:00:24-05</when>
+ <when>2010-05-01T13:00:29-05</when>
+ <when>2010-05-01T13:00:34-05</when>
+ <when>2010-05-01T13:00:38-05</when>
+ <when>2010-05-01T13:00:43-05</when>
+ <when>2010-05-01T13:00:48-05</when>
+ <when>2010-05-01T13:00:52-05</when>
+ <when>2010-05-01T13:00:57-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-92.5727580977974 45.0236058844647 2530</gx:coord>
+ <gx:coord>-92.5742776202954 45.0237913896498 2530</gx:coord>
+ <gx:coord>-92.5803397933112 45.0241784662561 2499</gx:coord>
+ <gx:coord>-92.5865075192046 45.0247891381303 2469</gx:coord>
+ <gx:coord>-92.5926877928765 45.0257073410966 2469</gx:coord>
+ <gx:coord>-92.5986546763805 45.0261844476041 2438</gx:coord>
+ <gx:coord>-92.6046737535477 45.0267206733977 2438</gx:coord>
+ <gx:coord>-92.6106885874739 45.0275061986719 2438</gx:coord>
+ <gx:coord>-92.616359210337 45.027935793162 2438</gx:coord>
+ <gx:coord>-92.6220735719954 45.028379077688 2438</gx:coord>
+ <gx:coord>-92.6280403097635 45.0290552550566 2438</gx:coord>
+ <gx:coord>-92.6341725652711 45.029824064212 2438</gx:coord>
+ <gx:coord>-92.640279209769 45.0304963952702 2438</gx:coord>
+ <gx:coord>-92.6463747377703 45.0311129317319 2438</gx:coord>
+ <gx:coord>-92.650043383232 45.0314890298388 2438</gx:coord>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <speed>235</speed>
+ <speed>246</speed>
+ <speed>239</speed>
+ <speed>244</speed>
+ <speed>234</speed>
+ <speed>232</speed>
+ <speed>238</speed>
+ <speed>227</speed>
+ <speed>228</speed>
+ <speed>229</speed>
+ <speed>229</speed>
+ <speed>232</speed>
+ <speed>228</speed>
+ <speed>232</speed>
+ <speed>236</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>E170</name>
+ <adflag>A</adflag>
+ <flightid>CPZ5695</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:11-05</when>
+ <when>2010-05-01T13:00:15-05</when>
+ <when>2010-05-01T13:00:20-05</when>
+ <when>2010-05-01T13:00:25-05</when>
+ <when>2010-05-01T13:00:29-05</when>
+ <when>2010-05-01T13:00:34-05</when>
+ <when>2010-05-01T13:00:38-05</when>
+ <when>2010-05-01T13:00:43-05</when>
+ <when>2010-05-01T13:00:48-05</when>
+ <when>2010-05-01T13:00:52-05</when>
+ <when>2010-05-01T13:00:57-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-92.3689380245182 45.0389467469425 2804</gx:coord>
+ <gx:coord>-92.3759530819834 45.0380951007958 2773</gx:coord>
+ <gx:coord>-92.3831159633175 45.0369957486846 2712</gx:coord>
+ <gx:coord>-92.3901362714549 45.0355238496347 2651</gx:coord>
+ <gx:coord>-92.3970814910858 45.0339385808083 2621</gx:coord>
+ <gx:coord>-92.4043121546626 45.032585906621 2560</gx:coord>
+ <gx:coord>-92.4118367565321 45.0319048652958 2499</gx:coord>
+ <gx:coord>-92.419078934653 45.030875157485 2469</gx:coord>
+ <gx:coord>-92.4262095560369 45.0291153314744 2438</gx:coord>
+ <gx:coord>-92.4335237384463 45.0273941113051 2438</gx:coord>
+ <gx:coord>-92.4408178608932 45.0260076351757 2438</gx:coord>
+ <gx:coord>-92.4451575746228 45.0254275529773 2438</gx:coord>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>250 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <gx:angles>250 0 0</gx:angles>
+ <gx:angles>250 0 0</gx:angles>
+ <gx:angles>250 0 0</gx:angles>
+ <gx:angles>260 0 0</gx:angles>
+ <speed>277</speed>
+ <speed>288</speed>
+ <speed>283</speed>
+ <speed>291</speed>
+ <speed>283</speed>
+ <speed>284</speed>
+ <speed>298</speed>
+ <speed>288</speed>
+ <speed>288</speed>
+ <speed>278</speed>
+ <speed>283</speed>
+ <speed>288</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>DC95</name>
+ <adflag>A</adflag>
+ <flightid>DAL2858</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:03-05</when>
+ <when>2010-05-01T13:00:07-05</when>
+ <when>2010-05-01T13:00:12-05</when>
+ <when>2010-05-01T13:00:17-05</when>
+ <when>2010-05-01T13:00:21-05</when>
+ <when>2010-05-01T13:00:26-05</when>
+ <when>2010-05-01T13:00:30-05</when>
+ <when>2010-05-01T13:00:35-05</when>
+ <when>2010-05-01T13:00:40-05</when>
+ <when>2010-05-01T13:00:44-05</when>
+ <when>2010-05-01T13:00:49-05</when>
+ <when>2010-05-01T13:00:54-05</when>
+ <when>2010-05-01T13:00:58-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.1962465696187 44.4584257162471 3078</gx:coord>
+ <gx:coord>-93.1954858158128 44.462643897726 3078</gx:coord>
+ <gx:coord>-93.1945524569257 44.4696206853623 3048</gx:coord>
+ <gx:coord>-93.1935347734104 44.4765680167011 3048</gx:coord>
+ <gx:coord>-93.1921548885013 44.4834366892852 3048</gx:coord>
+ <gx:coord>-93.1912787899895 44.4902740201102 3048</gx:coord>
+ <gx:coord>-93.190869393024 44.496999598511 3048</gx:coord>
+ <gx:coord>-93.190355669541 44.503701889363 3048</gx:coord>
+ <gx:coord>-93.1899042890233 44.510392533924 3048</gx:coord>
+ <gx:coord>-93.1894352972433 44.5171043633827 3048</gx:coord>
+ <gx:coord>-93.1887272976791 44.523838031578 3017</gx:coord>
+ <gx:coord>-93.1882343860587 44.5305421014878 2987</gx:coord>
+ <gx:coord>-93.1878483537445 44.5373007218153 2987</gx:coord>
+ <gx:coord>-93.187206305476 44.5440099500882 2956</gx:coord>
+ <gx:coord>-93.1870547021374 44.5466877366242 2956</gx:coord>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>10 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <gx:angles>0 0 0</gx:angles>
+ <speed>378</speed>
+ <speed>370</speed>
+ <speed>381</speed>
+ <speed>373</speed>
+ <speed>384</speed>
+ <speed>367</speed>
+ <speed>365</speed>
+ <speed>377</speed>
+ <speed>362</speed>
+ <speed>362</speed>
+ <speed>362</speed>
+ <speed>362</speed>
+ <speed>368</speed>
+ <speed>355</speed>
+ <speed>362</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>B737</name>
+ <adflag>A</adflag>
+ <flightid>SWA1488</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:01-05</when>
+ <when>2010-05-01T13:00:06-05</when>
+ <when>2010-05-01T13:00:11-05</when>
+ <when>2010-05-01T13:00:15-05</when>
+ <when>2010-05-01T13:00:20-05</when>
+ <when>2010-05-01T13:00:24-05</when>
+ <when>2010-05-01T13:00:29-05</when>
+ <when>2010-05-01T13:00:34-05</when>
+ <when>2010-05-01T13:00:38-05</when>
+ <when>2010-05-01T13:00:43-05</when>
+ <when>2010-05-01T13:00:48-05</when>
+ <when>2010-05-01T13:00:52-05</when>
+ <when>2010-05-01T13:00:57-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-92.7436038977339 45.0176449723009 2438</gx:coord>
+ <gx:coord>-92.745419752639 45.0178405701636 2438</gx:coord>
+ <gx:coord>-92.7525586927583 45.0181852080204 2438</gx:coord>
+ <gx:coord>-92.7599978682742 45.0189437491361 2438</gx:coord>
+ <gx:coord>-92.7673964649616 45.0200176804669 2438</gx:coord>
+ <gx:coord>-92.7743047878147 45.0206512321095 2438</gx:coord>
+ <gx:coord>-92.7812211106102 45.0212438545962 2438</gx:coord>
+ <gx:coord>-92.7880905786106 45.0219352711124 2438</gx:coord>
+ <gx:coord>-92.7948110303679 45.0225135550872 2438</gx:coord>
+ <gx:coord>-92.8016256231407 45.0231539091809 2377</gx:coord>
+ <gx:coord>-92.808436321378 45.0237782407713 2316</gx:coord>
+ <gx:coord>-92.8153060032773 45.0245123996427 2255</gx:coord>
+ <gx:coord>-92.8220950756464 45.0250388052127 2194</gx:coord>
+ <gx:coord>-92.8289929014999 45.0256725515916 2164</gx:coord>
+ <gx:coord>-92.8342709686589 45.0263726025032 2118.25</gx:coord>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <gx:angles>280 0 0</gx:angles>
+ <speed>280</speed>
+ <speed>293</speed>
+ <speed>284</speed>
+ <speed>288</speed>
+ <speed>274</speed>
+ <speed>272</speed>
+ <speed>279</speed>
+ <speed>263</speed>
+ <speed>263</speed>
+ <speed>262</speed>
+ <speed>262</speed>
+ <speed>275</speed>
+ <speed>270</speed>
+ <speed>277</speed>
+ <speed>287</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>A318</name>
+ <adflag>A</adflag>
+ <flightid>FFT106</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:05-05</when>
+ <when>2010-05-01T13:00:09-05</when>
+ <when>2010-05-01T13:00:14-05</when>
+ <when>2010-05-01T13:00:19-05</when>
+ <when>2010-05-01T13:00:23-05</when>
+ <when>2010-05-01T13:00:28-05</when>
+ <when>2010-05-01T13:00:33-05</when>
+ <when>2010-05-01T13:00:37-05</when>
+ <when>2010-05-01T13:00:42-05</when>
+ <when>2010-05-01T13:00:47-05</when>
+ <when>2010-05-01T13:00:51-05</when>
+ <when>2010-05-01T13:00:56-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.2974568508014 45.0687622602847 1432</gx:coord>
+ <gx:coord>-93.2934457905393 45.0660257042941 1371</gx:coord>
+ <gx:coord>-93.2902010482642 45.0627382200457 1341</gx:coord>
+ <gx:coord>-93.2880735868205 45.0592062737728 1280</gx:coord>
+ <gx:coord>-93.2866251180089 45.0556538417996 1280</gx:coord>
+ <gx:coord>-93.2855706436895 45.0521555770546 1249</gx:coord>
+ <gx:coord>-93.2848929213344 45.0486326683558 1249</gx:coord>
+ <gx:coord>-93.284149302237 45.0450445279501 1219</gx:coord>
+ <gx:coord>-93.2832681542582 45.0414770478452 1219</gx:coord>
+ <gx:coord>-93.2822163760078 45.0378266141909 1219</gx:coord>
+ <gx:coord>-93.2810695206555 45.0339762188888 1249</gx:coord>
+ <gx:coord>-93.2800852709943 45.0300242656845 1249</gx:coord>
+ <gx:coord>-93.2789451826991 45.026165428423 1249</gx:coord>
+ <gx:coord>-93.2776553627852 45.0222881273358 1219</gx:coord>
+ <gx:angles>140 0 0</gx:angles>
+ <gx:angles>150 0 0</gx:angles>
+ <gx:angles>150 0 0</gx:angles>
+ <gx:angles>160 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <gx:angles>170 0 0</gx:angles>
+ <speed>212</speed>
+ <speed>205</speed>
+ <speed>208</speed>
+ <speed>203</speed>
+ <speed>201</speed>
+ <speed>196</speed>
+ <speed>196</speed>
+ <speed>197</speed>
+ <speed>202</speed>
+ <speed>205</speed>
+ <speed>216</speed>
+ <speed>215</speed>
+ <speed>222</speed>
+ <speed>231</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name></name>
+ <adflag>A</adflag>
+ <flightid></flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:05-05</when>
+ <when>2010-05-01T13:00:10-05</when>
+ <when>2010-05-01T13:00:14-05</when>
+ <when>2010-05-01T13:00:24-05</when>
+ <when>2010-05-01T13:00:33-05</when>
+ <when>2010-05-01T13:00:37-05</when>
+ <when>2010-05-01T13:00:42-05</when>
+ <when>2010-05-01T13:00:47-05</when>
+ <when>2010-05-01T13:00:51-05</when>
+ <when>2010-05-01T13:00:56-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-93.5287325331323 45.3502794027397 731</gx:coord>
+ <gx:coord>-93.5305174337715 45.3463816209029 731</gx:coord>
+ <gx:coord>-93.532323089283 45.3433065196778 731</gx:coord>
+ <gx:coord>-93.5344374505075 45.3397938806867 731</gx:coord>
+ <gx:coord>-93.5365879669744 45.3355152994798 731</gx:coord>
+ <gx:coord>-93.538455345577 45.3317693717468 731</gx:coord>
+ <gx:coord>-93.5402440337749 45.3288175816964 731</gx:coord>
+ <gx:coord>-93.5420054353005 45.3261482119682 701</gx:coord>
+ <gx:coord>-93.5437972875724 45.3236486426325 701</gx:coord>
+ <gx:coord>-93.5449025453586 45.3213557809437 670</gx:coord>
+ <gx:coord>-93.5460939368394 45.3190373998605 670</gx:coord>
+ <gx:coord>-93.5479457332637 45.3165177805485 670</gx:coord>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <gx:angles>200 0 0</gx:angles>
+ <speed>202</speed>
+ <speed>180</speed>
+ <speed>166</speed>
+ <speed>171</speed>
+ <speed>162</speed>
+ <speed>157</speed>
+ <speed>143</speed>
+ <speed>145</speed>
+ <speed>156</speed>
+ <speed>147</speed>
+ <speed>147</speed>
+ <speed>150</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>CRJ2</name>
+ <adflag>A</adflag>
+ <flightid>SKW4805</flightid>
+ <styleUrl>#arrival</styleUrl>
+</Placemark>
+<Placemark>
+ <name>CRJ2</name>
+ <adflag>A</adflag>
+ <flightid>FLG4092</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:01-05</when>
+ <when>2010-05-01T13:00:06-05</when>
+ <when>2010-05-01T13:00:10-05</when>
+ <when>2010-05-01T13:00:15-05</when>
+ <when>2010-05-01T13:00:20-05</when>
+ <when>2010-05-01T13:00:24-05</when>
+ <when>2010-05-01T13:00:29-05</when>
+ <when>2010-05-01T13:00:34-05</when>
+ <when>2010-05-01T13:00:38-05</when>
+ <when>2010-05-01T13:00:44-05</when>
+ <when>2010-05-01T13:00:49-05</when>
+ <when>2010-05-01T13:00:54-05</when>
+ <gx:coord>-93.1836067392297 44.9110362339843 432.2</gx:coord>
+ <gx:coord>-93.1841170614853 44.910663862492 426</gx:coord>
+ <gx:coord>-93.1867007876887 44.908842129317 426</gx:coord>
+ <gx:coord>-93.1893728799637 44.9069842219291 396</gx:coord>
+ <gx:coord>-93.1919479660705 44.9051548529609 365</gx:coord>
+ <gx:coord>-93.1944798212107 44.9032897679148 365</gx:coord>
+ <gx:coord>-93.197164452306 44.9014210542153 335</gx:coord>
+ <gx:coord>-93.1996234874761 44.8995719817206 335</gx:coord>
+ <gx:coord>-93.2021701211426 44.8975674983317 304</gx:coord>
+ <gx:coord>-93.2050345971567 44.8955942303701 304</gx:coord>
+ <gx:coord>-93.2075455037487 44.8938556558558 304</gx:coord>
+ <gx:coord>-93.2100820128846 44.8918590963212 304</gx:coord>
+ <gx:coord>-93.2127524858241 44.89000250047 256</gx:coord>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>230 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <gx:angles>220 0 0</gx:angles>
+ <speed>141</speed>
+ <speed>138</speed>
+ <speed>136</speed>
+ <speed>141</speed>
+ <speed>141</speed>
+ <speed>142</speed>
+ <speed>143</speed>
+ <speed>139</speed>
+ <speed>140</speed>
+ <speed>134</speed>
+ <speed>136</speed>
+ <speed>136</speed>
+ <speed>123</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+</gx:Track></Placemark>
+<Placemark>
+ <name>E170</name>
+ <adflag>A</adflag>
+ <flightid>CPZ5667</flightid>
+ <styleUrl>#arrival</styleUrl>
+<gx:Track>
+ <altitudeMode>absolute</altitudeMode>
+ <extrude>1</extrude>
+ <when>2010-05-01T13:00:00-05</when>
+ <when>2010-05-01T13:00:01-05</when>
+ <when>2010-05-01T13:00:06-05</when>
+ <when>2010-05-01T13:00:10-05</when>
+ <when>2010-05-01T13:00:15-05</when>
+ <when>2010-05-01T13:00:20-05</when>
+ <when>2010-05-01T13:00:24-05</when>
+ <when>2010-05-01T13:00:29-05</when>
+ <when>2010-05-01T13:00:34-05</when>
+ <when>2010-05-01T13:00:38-05</when>
+ <when>2010-05-01T13:00:43-05</when>
+ <when>2010-05-01T13:00:47-05</when>
+ <when>2010-05-01T13:00:52-05</when>
+ <when>2010-05-01T13:00:57-05</when>
+ <when>2010-05-01T13:01:00-05</when>
+ <gx:coord>-92.9496238812799 45.0117549407746 1438.2</gx:coord>
+ <gx:coord>-92.9507065768732 45.0116702587604 1432</gx:coord>
+ <gx:coord>-92.9563739191926 45.0116271226204 1432</gx:coord>
+ <gx:coord>-92.9620225732021 45.0115639668496 1432</gx:coord>
+ <gx:coord>-92.9673675587699 45.0113432900049 1402</gx:coord>
+ <gx:coord>-92.9725115032188 45.0111442254373 1402</gx:coord>
+ <gx:coord>-92.9778810091229 45.0112050922639 1371</gx:coord>
+ <gx:coord>-92.9832227114571 45.0112143826731 1371</gx:coord>
+ <gx:coord>-92.9884546803523 45.0110418166788 1341</gx:coord>
+ <gx:coord>-92.9938268606229 45.0109652220709 1341</gx:coord>
+ <gx:coord>-92.9991151069756 45.010802144845 1310</gx:coord>
+ <gx:coord>-93.0041467584036 45.0105516668541 1310</gx:coord>
+ <gx:coord>-93.0090742909164 45.0105233046799 1280</gx:coord>
+ <gx:coord>-93.0139435770527 45.0106265340001 1280</gx:coord>
+ <gx:coord>-93.0174882575928 45.0106328449121 1256.75</gx:coord>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <gx:angles>270 0 0</gx:angles>
+ <speed>214</speed>
+ <speed>207</speed>
+ <speed>202</speed>
+ <speed>208</speed>
+ <speed>207</speed>
+ <speed>205</speed>
+ <speed>203</speed>
+ <speed>202</speed>
+ <speed>209</speed>
+ <speed>199</speed>
+ <speed>196</speed>
+ <speed>200</speed>
+ <speed>193</speed>
+ <speed>194</speed>
+ <speed>185</speed>
+ <num>10</num>
+ <num>20</num>
+ <num>30</num>
+ <num>40</num>
+ <num>50</num>
+ <num>60</num>
+ <num>70</num>
+ <num>80</num>
+ <num>90</num>
+ <num>100</num>
+ <num>110</num>
+ <num>120</num>
+ <num>130</num>
+ <num>140</num>
+ <num>150</num>
+</gx:Track></Placemark>
+</Folder>
+<Folder>
+ <name>Departures</name>
+</Folder>
+<Folder>
+ <name>Overflights</name>
+</Folder>
+</Document>
+</kml>
+--></div>
+
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/OGCExceptionReport.html b/misc/openlayers/tests/Format/OGCExceptionReport.html
new file mode 100644
index 0000000..7846f94
--- /dev/null
+++ b/misc/openlayers/tests/Format/OGCExceptionReport.html
@@ -0,0 +1,100 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+
+ t.plan(21);
+
+ // OCG WMS 1.3.0 exceptions
+ var text = '<?xml version="1.0" encoding="UTF-8"?> ' +
+'<ServiceExceptionReport version="1.3.0" xmlns="http://www.opengis.net/ogc"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+' xsi:schemaLocation="http://www.opengis.net/ogc' +
+' http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">' +
+' <ServiceException> Plain text message about an error. </ServiceException>' +
+' <ServiceException code="InvalidUpdateSequence"> Another error message, this one with a service exception code supplied. </ServiceException>' +
+' <ServiceException>' +
+' <![CDATA[ Error in module <foo.c>, line 42' +
+'A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:' +
+']]>' +
+' </ServiceException>' +
+' <ServiceException>' +
+' <![CDATA[ <Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation> ]]>' +
+' </ServiceException>' +
+'</ServiceExceptionReport>';
+
+ var parser = new OpenLayers.Format.OGCExceptionReport();
+ var result = parser.read(text);
+
+ var exceptions = result.exceptionReport.exceptions;
+
+ var testWMS = function(exceptions) {
+ t.eq(exceptions.length, 4, "We expect 4 exception messages");
+ t.eq(exceptions[0].text, " Plain text message about an error. ", "First error message correctly parsed");
+ t.eq(exceptions[1].code, "InvalidUpdateSequence", "Code of second error message correctly parsed");
+ t.eq(exceptions[1].text, " Another error message, this one with a service exception code supplied. ", "Text of second error message correctly parsed");
+ t.eq(OpenLayers.String.trim(exceptions[2].text), "Error in module <foo.c>, line 42A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:", "Third message correctly parsed");
+ t.eq(OpenLayers.String.trim(exceptions[3].text), "<Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation>", "Fourth message correctly parsed");
+ };
+
+ testWMS(exceptions);
+
+ // OGC WMS 1.1.1 exceptions
+ text = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd"> ' +
+'<ServiceExceptionReport version="1.1.1">' +
+' <ServiceException> Plain text message about an error. </ServiceException>' +
+' <ServiceException code="InvalidUpdateSequence"> Another error message, this one with a service exception code supplied. </ServiceException>' +
+' <ServiceException>' +
+' <![CDATA[ Error in module <foo.c>, line 42' +
+'A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:' +
+']]>' +
+' </ServiceException>' +
+' <ServiceException>' +
+' <![CDATA[ <Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation> ]]>' +
+' </ServiceException>' +
+'</ServiceExceptionReport>';
+ result = parser.read(text);
+ exceptions = result.exceptionReport.exceptions;
+ testWMS(exceptions);
+
+ // OGC WFS 1.0.0 exceptions
+ text = '<?xml version="1.0" ?> ' +
+'<ServiceExceptionReport version="1.2.0" xmlns="http://www.opengis.net/ogc"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+' xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd">' +
+' <ServiceException code="999" locator="INSERT STMT 01"> parse error: missing closing tag for element WKB_GEOM </ServiceException>' +
+'</ServiceExceptionReport>';
+ result = parser.read(text);
+ t.eq(result.exceptionReport.exceptions[0].code, "999", "code parsed correctly");
+ t.eq(result.exceptionReport.exceptions[0].locator, "INSERT STMT 01", "locator parsed correctly");
+ t.eq(result.exceptionReport.exceptions[0].text, " parse error: missing closing tag for element WKB_GEOM ", "error text parsed correctly");
+
+ // OGC WFS 1.1.0 exceptions that use OWSCommon 1.0
+ text = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<ows:ExceptionReport language="en" version="1.0.0"' +
+' xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows">' +
+' <ows:Exception locator="foo" exceptionCode="InvalidParameterValue">' +
+' <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +
+' <ows:ExceptionText>Second exception line</ows:ExceptionText>' +
+' </ows:Exception>' +
+'</ows:ExceptionReport>';
+
+ var result = parser.read(text);
+ var report = result.exceptionReport;
+ t.eq(report.version, "1.0.0", "Version parsed correctly");
+ t.eq(report.language, "en", "Language parsed correctly");
+ var exception = report.exceptions[0];
+ t.eq(exception.code, "InvalidParameterValue", "exceptionCode properly parsed");
+ t.eq(exception.locator, "foo", "locator properly parsed");
+ t.eq(exception.texts[0], "Update error: Error occured updating features", "ExceptionText correctly parsed");
+ t.eq(exception.texts[1], "Second exception line", "Second ExceptionText correctly parsed");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/OSM.html b/misc/openlayers/tests/Format/OSM.html
new file mode 100644
index 0000000..6ceb316
--- /dev/null
+++ b/misc/openlayers/tests/Format/OSM.html
@@ -0,0 +1,115 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script src="../data/osm.js"></script>
+ <script type="text/javascript">
+
+ function test_Format_OSM_constructor(t) {
+ t.plan(5);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.OSM(options);
+ t.ok(format instanceof OpenLayers.Format.OSM,
+ "new OpenLayers.Format.OSM returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ t.eq(format.externalProjection.getCode(), "EPSG:4326",
+ "default external projection is EPSG:4326");
+ }
+ function test_Format_OSM_node(t) {
+ t.plan(4);
+ var f = new OpenLayers.Format.OSM();
+ var features = f.read(osm_test_data['node']);
+ var feat = features[0];
+ t.eq(feat.attributes, {}, "attributes is empty");
+ t.eq(feat.osm_id, 200545, "internal osm_id property set correctly");
+ t.eq(feat.geometry.x, -1.8166417, "lon is correct");
+ t.eq(feat.geometry.y, 52.5503033, "lat is correct");
+ }
+ function test_Format_OSM_node_with_tags(t) {
+ t.plan(5);
+ var f = new OpenLayers.Format.OSM();
+ var features = f.read(osm_test_data['node_with_tags']);
+ var feat = features[0];
+ t.eq(feat.attributes, {'a':'b'}, "attributes match");
+ t.eq(feat.osm_id, 200545, "internal osm_id property set correctly");
+ t.eq(feat.fid, "node.200545", "OSM-based FID set correctly.");
+ t.eq(feat.geometry.x, -1.8166417, "lon is correct");
+ t.eq(feat.geometry.y, 52.5503033, "lat is correct");
+ }
+ function test_Format_OSM_way(t) {
+ t.plan(8);
+ var f = new OpenLayers.Format.OSM();
+ var features = f.read(osm_test_data['way']);
+ t.eq(features.length, 1, "One feature");
+ var feat = features[0];
+ t.eq(feat.osm_id, 4685537, "OSM ID set correctly.");
+ t.eq(feat.fid, "way.4685537", "OSM-based FID set correctly.");
+ t.eq(feat.geometry.CLASS_NAME, "OpenLayers.Geometry.Polygon", "returned as polygon");
+ t.eq(feat.geometry.components[0].components.length, 11, "Correct number of components");
+ t.eq(feat.geometry.components[0].components[0].osm_id, 29783472, "OSM ID set on components");
+ t.eq(feat.geometry.toString(), "POLYGON((-1.8164007 52.5501836,-1.8170311 52.5506035,-1.8164092 52.5509559,-1.8169385 52.5513103,-1.8159626 52.5517893,-1.8145067 52.5518461,-1.8143197 52.5511883,-1.8141177 52.5506446,-1.8151451 52.5501275,-1.8157703 52.5505521,-1.8164007 52.5501836))", "WKT of feature is correct");
+ t.eq(feat.attributes.landuse, "school", "landuse attribute correct");
+ }
+
+ function test_Format_OSM_node_way(t) {
+ t.plan(5)
+ var f = new OpenLayers.Format.OSM();
+ var features = f.read(osm_test_data['node_way']);
+ t.eq(features.length, 1, "One feature");
+ var feat = features[0];
+ t.eq(feat.osm_id, 21329267, "OSM ID set correctly");
+ t.eq(feat.attributes.highway, "unclassified", "highway attribute is correct.");
+ t.eq(feat.geometry.CLASS_NAME, "OpenLayers.Geometry.LineString", "returned as linestring");
+ t.eq(feat.geometry.components.length, 12, "correct number of segments");
+ }
+
+ function test_Format_OSM_node_way_checkTags(t) {
+ t.plan(9)
+ var f = new OpenLayers.Format.OSM({'checkTags': true});
+ var features = f.read(osm_test_data['node_way']);
+ t.eq(features.length, 3, "multiple features");
+
+ var feat = features[1];
+ t.eq(feat.geometry.CLASS_NAME, "OpenLayers.Geometry.Point", "point class");
+ t.ok(feat.attributes != {}, "feature has attributes");
+
+ var feat = features[2];
+ t.eq(feat.geometry.CLASS_NAME, "OpenLayers.Geometry.Point", "point class");
+ t.ok(feat.attributes != {}, "feature has attributes");
+
+ feat = features[0];
+ t.eq(feat.osm_id, 21329267, "OSM ID set correctly");
+ t.eq(feat.attributes.highway, "unclassified", "highway attribute is correct.");
+ t.eq(feat.geometry.CLASS_NAME, "OpenLayers.Geometry.LineString", "returned as linestring");
+ t.eq(feat.geometry.components.length, 12, "correct number of segments");
+ }
+
+ function test_Format_OSM_serialize(t) {
+ t.plan(4);
+ var f = new OpenLayers.Format.OSM({'checkTags': true});
+ for (var key in osm_serialized_data) {
+ var input = f.read(osm_test_data[key]);
+ var output = f.write(input);
+ output = output.replace(/<\?[^>]*\?>/, '');
+ t.eq(output, osm_serialized_data[key], key + " serialized correctly");
+ }
+ }
+ function test_Format_OSM_write_reproject(t) {
+ t.plan(1);
+ var f = new OpenLayers.Format.OSM({'internalProjection': new OpenLayers.Projection("EPSG:900913")});
+ var feat = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(100000, 100000)
+ );
+ var data = f.write([feat]);
+ var f = new OpenLayers.Format.OSM();
+ var features = f.read(data);
+
+ t.eq(OpenLayers.Util.toFloat(features[0].geometry.x, 3), .898, "exported to lonlat and re-read as lonlat correctly")
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/OWSCommon/v1_0_0.html b/misc/openlayers/tests/Format/OWSCommon/v1_0_0.html
new file mode 100644
index 0000000..9d255b2
--- /dev/null
+++ b/misc/openlayers/tests/Format/OWSCommon/v1_0_0.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+ t.plan(6);
+ var text = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<ows:ExceptionReport language="en" version="1.0.0"' +
+' xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows">' +
+' <ows:Exception locator="foo" exceptionCode="InvalidParameterValue">' +
+' <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +
+' <ows:ExceptionText>Second exception line</ows:ExceptionText>' +
+' </ows:Exception>' +
+'</ows:ExceptionReport>';
+
+ var format = new OpenLayers.Format.OWSCommon();
+ var result = format.read(text);
+ var report = result.exceptionReport;
+ t.eq(report.version, "1.0.0", "Version parsed correctly");
+ t.eq(report.language, "en", "Language parsed correctly");
+ var exception = report.exceptions[0];
+ t.eq(exception.code, "InvalidParameterValue", "exceptionCode properly parsed");
+ t.eq(exception.locator, "foo", "locator properly parsed");
+ t.eq(exception.texts[0], "Update error: Error occured updating features", "ExceptionText correctly parsed");
+ t.eq(exception.texts[1], "Second exception line", "Second ExceptionText correctly parsed");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/OWSCommon/v1_1_0.html b/misc/openlayers/tests/Format/OWSCommon/v1_1_0.html
new file mode 100644
index 0000000..1cdf7ee
--- /dev/null
+++ b/misc/openlayers/tests/Format/OWSCommon/v1_1_0.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+ t.plan(6);
+ var text = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<ows:ExceptionReport xml:lang="en" version="1.1.0"' +
+' xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows/1.1">' +
+' <ows:Exception locator="foo" exceptionCode="InvalidParameterValue">' +
+' <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +
+' <ows:ExceptionText>Second exception line</ows:ExceptionText>' +
+' </ows:Exception>' +
+'</ows:ExceptionReport>';
+
+ var format = new OpenLayers.Format.OWSCommon();
+ var result = format.read(text);
+ var report = result.exceptionReport;
+ t.eq(report.version, "1.1.0", "Version parsed correctly");
+ t.eq(report.language, "en", "Language parsed correctly");
+ var exception = report.exceptions[0];
+ t.eq(exception.code, "InvalidParameterValue", "exceptionCode properly parsed");
+ t.eq(exception.locator, "foo", "locator properly parsed");
+ t.eq(exception.texts[0], "Update error: Error occured updating features", "ExceptionText correctly parsed");
+ t.eq(exception.texts[1], "Second exception line", "Second ExceptionText correctly parsed");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/OWSContext/v0_3_1.html b/misc/openlayers/tests/Format/OWSContext/v0_3_1.html
new file mode 100644
index 0000000..54b63b3
--- /dev/null
+++ b/misc/openlayers/tests/Format/OWSContext/v0_3_1.html
@@ -0,0 +1,278 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_wmswfs(t) {
+ t.plan(17);
+ // taken from http://www.ogcnetwork.net/schemas/owc/0.3.1/context_nested.xml
+ // adapted: add an extra slash (roads/railways) in the Title of the WMS layer to test nesting
+ var text = '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<OWSContext version="0.3.1" id="ows-context-ex-1-v3" xmlns="http://www.opengis.net/ows-context"' +
+ ' xmlns:gml="http://www.opengis.net/gml" xmlns:kml="http://www.opengis.net/kml/2.2"' +
+ ' xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows"' +
+ ' xmlns:sld="http://www.opengis.net/sld" xmlns:xlink="http://www.w3.org/1999/xlink"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+ ' xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd">' +
+ ' <General>' +
+ ' <ows:BoundingBox crs="EPSG:4326">' +
+ ' <ows:LowerCorner>-117 32</ows:LowerCorner>' +
+ ' <ows:UpperCorner>-116 33</ows:UpperCorner>' +
+ ' </ows:BoundingBox>' +
+ ' <ows:Title>OWS Context version 0.3.1 showing nested layers</ows:Title>' +
+ ' </General>' +
+ ' <ResourceList>' +
+ ' <!-- WMS Example -->' +
+ ' <Layer name="topp:major_roads" queryable="1" hidden="1">' +
+ ' <ows:Title>Tiger 2005fe major roads/railways</ows:Title>' +
+ ' <ows:OutputFormat>image/png</ows:OutputFormat>' +
+ ' <Server service="urn:ogc:serviceType:WMS" version="1.1.1">' +
+ ' <OnlineResource' +
+ ' xlink:href="http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS"/>' +
+ ' </Server>' +
+ ' <!-- WFS Example -->' +
+ ' <Layer name="topp:gnis_pop" hidden="0">' +
+ ' <ows:Title>GNIS Population</ows:Title>' +
+ ' <Server service="urn:ogc:serviceType:WFS" version="1.0.0">' +
+ ' <OnlineResource xlink:href="geoserver/wfs?"/>' +
+ ' </Server>' +
+ ' </Layer>' +
+ ' </Layer>' +
+ ' </ResourceList>' +
+ '</OWSContext>';
+ var parser = new OpenLayers.Format.OWSContext();
+ var map = new OpenLayers.Map('map', {allOverlays: true, fractionalZoom: true});
+ var context = parser.read(text, {map: map});
+ t.eq(context.layers.length, 2, "2 layers parsed from OWSContext document");
+ t.eq(context.layers[1].metadata.nestingPath[0], "Tiger 2005fe major roads/railways", "Nesting path correctly set");
+ t.ok(context.layers[0] instanceof OpenLayers.Layer.WMS, "First layer is a WMS layer");
+ t.ok(context.layers[1] instanceof OpenLayers.Layer.Vector, "Second layer is a vector layer");
+ t.eq(context.layers[0].params.LAYERS, "topp:major_roads", "WMS layer name correctly read");
+ t.eq(context.layers[0].params.FORMAT, "image/png", "WMS format correctly read");
+ t.eq(context.layers[0].url, "http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS", "Layer url correctly read");
+ t.eq(context.layers[0].getVisibility(), false, "WMS Layer is hidden");
+ t.ok(context.layers[0].queryable, "WMS layer is queryable");
+ t.eq(context.layers[0].name, "Tiger 2005fe major roads/railways", "Title correctly set");
+ t.ok(context.layers[1].protocol instanceof OpenLayers.Protocol.WFS.v1_0_0, "Vector layer configured with a WFS Protocol");
+ t.eq(context.layers[1].protocol.url, "geoserver/wfs?", "WFS url set correctly");
+ t.ok(context.layers[1].strategies[0] instanceof OpenLayers.Strategy.BBOX, "BBOX strategy configured correctly");
+ t.eq(context.layers[1].name, "GNIS Population", "Title of second layer correctly set");
+ t.eq(context.layers[1].getVisibility(), true, "Second layer is visible");
+ map.zoomToExtent(new OpenLayers.Bounds(-117, 32, -116, 33));
+ var owc = parser.write(map, {id: 'ows-context-ex-1-v3', title: 'OWS Context version 0.3.1 showing nested layers'});
+ t.xml_eq(text, owc, "Can we roundtrip this nested OWSContext with a WMS and WFS layer?");
+ t.eq(context.layers[1].metadata.nestingPath[0], "Tiger 2005fe major roads/railways", "Nesting path is preserved even after calling write");
+ }
+
+ function test_write_wmswfs(t) {
+ t.plan(1);
+ var lon = 5;
+ var lat = 40;
+ var zoom = 5;
+ var map = new OpenLayers.Map( 'map' );
+ var layer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'},
+ {singleTile: true}
+ );
+ var wfs = new OpenLayers.Layer.Vector("myroads", {
+ strategies: [new OpenLayers.Strategy.BBOX()],
+ protocol: new OpenLayers.Protocol.WFS({
+ url: "foo/wfs?",
+ featureType: "roads",
+ featureNS: "http://foo/myns"
+ })
+ });
+ map.addLayers([layer, wfs]);
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+
+ var owc = new OpenLayers.Format.OWSContext();
+ var output = owc.write(map, {id: 'foo'});
+ var expected = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="foo" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer name="feature:roads" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">myroads</ows:Title><Server version="1.0.0" service="urn:ogc:serviceType:WFS"><OnlineResource xlink:href="foo/wfs?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer></ResourceList></OWSContext>';
+ t.xml_eq(output, expected, "OWSContext with a WMS and a WFS layer generated correctly");
+ }
+
+ function test_write_wmsinlinegml(t) {
+ t.plan(1);
+ var lon = 5;
+ var lat = 40;
+ var zoom = 5;
+ var map = new OpenLayers.Map( 'map' );
+ var layer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'},
+ {singleTile: true}
+ );
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+
+ var vector = new OpenLayers.Layer.Vector();
+ map.addLayer(vector);
+ var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,1));
+ var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,0));
+ vector.addFeatures(feature1);
+ vector.addFeatures(feature2);
+ var owc = new OpenLayers.Format.OWSContext();
+ var output = owc.write(map, {id: 'foo'});
+ var expected = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="foo" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer name="vector" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows"/><InlineGeometry><gml:boundedBy xmlns:gml="http://www.opengis.net/gml"><gml:Box><gml:coordinates decimal="." cs="," ts=" ">0,0 1,1</gml:coordinates></gml:Box></gml:boundedBy><gml:featureMember xmlns:gml="http://www.opengis.net/gml"><feature:vector xmlns:feature="http://mapserver.gis.umn.edu/mapserver"><feature:geometry><gml:Point><gml:coordinates decimal="." cs="," ts=" ">0,1</gml:coordinates></gml:Point></feature:geometry></feature:vector></gml:featureMember><gml:featureMember xmlns:gml="http://www.opengis.net/gml"><feature:vector xmlns:feature="http://mapserver.gis.umn.edu/mapserver"><feature:geometry><gml:Point><gml:coordinates decimal="." cs="," ts=" ">1,0</gml:coordinates></gml:Point></feature:geometry></feature:vector></gml:featureMember></InlineGeometry></Layer></ResourceList></OWSContext>';
+ t.xml_eq(output, expected, "OWSContext with a WMS and an inline GML vector layer generated correctly");
+ }
+
+ function test_write_inlinegml_no_features(t){
+ var lon = 5,
+ lat = 40,
+ zoom = 5,
+ map = new OpenLayers.Map( 'map' ),
+ layer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'},
+ {singleTile: true}
+ ),
+ vector = new OpenLayers.Layer.Vector();
+
+ map.addLayers( [ layer, vector ] );
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+
+ var owc = new OpenLayers.Format.OWSContext(),
+ output,
+ caughtException = false,
+ expectedXml = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="foo" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer name="vector" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows"/><InlineGeometry/></Layer></ResourceList></OWSContext>';
+
+ try {
+ output = owc.write(map, {id: 'foo'});
+ } catch (e){
+ caughtException = true;
+ }
+
+ if (caughtException) {
+ t.plan(1);
+ t.fail('OWSContext with a WMS and an inline vector layer failed and threw an exception');
+ } else {
+ t.plan(2);
+ t.ok(true, 'OWSContext with a WMS and an inline vector layer generated without exception');
+ t.xml_eq(output, expectedXml, "OWSContext with a WMS and an inline vector layer generated correctly");
+ }
+ }
+
+ function test_read_inline(t) {
+ t.plan(10);
+ var text = '<?xml version="1.0" encoding="UTF-8"?><OWSContext xmlns="http://www.opengis.net/ows-context" xmlns:gml="http://www.opengis.net/gml" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:sld="http://www.opengis.net/sld" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.3.1" id="ows-context-ex-1-v3" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.0/owsContext.xsd"><General><ows:BoundingBox crs="urn:ogc:def:crs:EPSG:6.6:4326"><ows:LowerCorner>-117.44667178362664 32.57086210449395</ows:LowerCorner><ows:UpperCorner>-116.74066794885977 32.921986352104064</ows:UpperCorner></ows:BoundingBox><ows:Title>OWS Context version 0.3.0 Inline KML and GML examples</ows:Title></General><ResourceList><!-- WMS Example --><Layer name="topp:major_roads" queryable="1" hidden="1"> <ows:Title>Tiger 2005fe major roads</ows:Title> <ows:OutputFormat>image/png</ows:OutputFormat><Server service="urn:ogc:serviceType:WMS" version="1.1.1"><OnlineResource xlink:href="http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS"/></Server></Layer><!-- Inline KML Example --><Layer name="archsites"><ows:Title>Architectural Sites</ows:Title><kml:Document><kml:name>opengeo:archsites 1 to 100</kml:name><kml:Style id="archsitesStyle"><kml:IconStyle><kml:color>ffffffff</kml:color><kml:colorMode>normal</kml:colorMode><kml:Icon><kml:href>http://maps.google.com/mapfiles/kml/pal4/icon25.png</kml:href></kml:Icon></kml:IconStyle></kml:Style><kml:Placemark id="archsites.1"><kml:name>Signature Rock</kml:name><kml:description>Signature Rock Description</kml:description><kml:styleUrl>#archsitesStyle</kml:styleUrl><kml:Point><kml:coordinates>-103.82681673,44.38162255</kml:coordinates></kml:Point></kml:Placemark></kml:Document></Layer><!-- Inline GML Example --><Layer name="coastg"><ows:Title>Coastg as GML Points</ows:Title><InlineGeometry><gml:boundedBy><gml:Box><gml:coord><gml:X>-43.379</gml:X><gml:Y>72.746</gml:Y></gml:coord><gml:coord><gml:X>-43.390</gml:X><gml:Y>72.755</gml:Y></gml:coord></gml:Box></gml:boundedBy><gml:featureMember><au1:coastg xmlns:au1="http://www.ionicsoft.com/wfs" fid="coastg.0"><au1:MERGE>1</au1:MERGE><au1:AREA>0.0020000000000000005</au1:AREA><au1:PERIMETER>0.167</au1:PERIMETER><au1:GEOMETRY><gml:Polygon srsName="urn:ogc:def:crs:EPSG:6.6:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>129.29167335893825,71.9583353847737 129.29167335893825,72.0000014248896 129.33332733905414,72.0000014248896 129.33332733905414,71.9583353847737 129.29167335893825,71.9583353847737</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></au1:GEOMETRY></au1:coastg></gml:featureMember><gml:featureMember><au1:coastg xmlns:au1="http://www.ionicsoft.com/wfs" fid="coastg.1"><au1:MERGE>1</au1:MERGE><au1:AREA>0.0020000000000000005</au1:AREA><au1:PERIMETER>0.167</au1:PERIMETER><au1:GEOMETRY><gml:Polygon srsName="urn:ogc:def:crs:EPSG:6.6:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>135.45832829609282,35.66666796381659 135.41667179597695,35.66666796381659 135.41667179597695,35.70833202393249 135.45832829609282,35.70833202393249 135.45832829609282,35.66666796381659</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></au1:GEOMETRY></au1:coastg></gml:featureMember></InlineGeometry></Layer></ResourceList></OWSContext>';
+ var parser = new OpenLayers.Format.OWSContext();
+ var context = parser.read(text, {map: 'map'});
+ t.ok(context.layers[1] instanceof OpenLayers.Layer.Vector, "Inline KML results in a vector layer");
+ t.eq(context.layers[1].features.length, 1, "Inline KML layer has one feature");
+ t.ok(context.layers[1].features[0].geometry instanceof OpenLayers.Geometry.Point, "KML feature is a point");
+ t.eq(context.layers[1].features[0].attributes.description, "Signature Rock Description", "KML Description correctly parsed");
+ t.eq(context.layers[1].features[0].fid, "archsites.1", "KML feature id correctly parsed");
+ t.eq(context.layers[1].features[0].style.externalGraphic, "http://maps.google.com/mapfiles/kml/pal4/icon25.png", "Style url for KML feature correctly parsed");
+ t.ok(context.layers[2] instanceof OpenLayers.Layer.Vector, "Inline GML results in a vector layer");
+ t.eq(context.layers[2].features.length, 2, "Inline GML layer has two features");
+ t.ok(context.layers[2].features[0].geometry instanceof OpenLayers.Geometry.Polygon, "GML feature is a polygon");
+ t.eq(context.layers[2].features[0].attributes.MERGE, "1", "GML attribute read correctly");
+ }
+
+ function test_read_gml(t) {
+ t.plan(5);
+ var text = '<?xml version="1.0" encoding="UTF-8"?><OWSContext version="0.3.0" id="ows-context-ex-1-v3" xmlns="http://www.opengis.net/ows-context" xmlns:gml="http://www.opengis.net/gml" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:sld="http://www.opengis.net/sld" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.0/owsContext.xsd"><General><ows:BoundingBox crs="urn:ogc:def:crs:EPSG:6.6:4326"><ows:LowerCorner>-117.44667178362664 32.57086210449395</ows:LowerCorner><ows:UpperCorner>-116.74066794885977 32.921986352104064</ows:UpperCorner></ows:BoundingBox><ows:Title>OWS Context version 0.3.0 examples</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0" opacity="1"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><!-- Referenced GML Example --><Layer name="Landuse"><ows:Title>Boston Landuse Polygons</ows:Title><Server service="urn:ogc:serviceType:GML" version="2.1.2" title="Cadcorp GeognoSIS.NET Web Feature Service"><OnlineResource xlink:href="gml/MassGIS/LandUse.gml"/></Server><sld:MinScaleDenominator>5000</sld:MinScaleDenominator><sld:MaxScaleDenominator>50000</sld:MaxScaleDenominator><MaxFeatures>99</MaxFeatures></Layer></ResourceList></OWSContext>';
+ var parser = new OpenLayers.Format.OWSContext();
+ var context = parser.read(text, {map: 'map'});
+ t.ok(context.layers[1].protocol instanceof OpenLayers.Protocol.HTTP, "serviceType GML is translated into an HTTP Protocol");
+ t.eq(context.layers[1].protocol.url, "gml/MassGIS/LandUse.gml", "Url of GML file correctly set");
+ t.ok(context.layers[1].protocol.format instanceof OpenLayers.Format.GML, "GML Format associated with protocol");
+ t.eq(Math.round(context.layers[1].minScale), 50000, "Minscale correctly read");
+ t.eq(Math.round(context.layers[1].maxScale), 5000, "Maxscale correctly read");
+ }
+
+ function test_read_kml(t) {
+ t.plan(3);
+ var text = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="foo" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-5.986328125 27.9150390625</ows:LowerCorner><ows:UpperCorner>15.986328125 52.0849609375</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0" opacity="1"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">KML</ows:Title><Server version="2.2" service="urn:ogc:serviceType:KML"><OnlineResource xlink:href="foo/sundials.kml" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer></ResourceList></OWSContext>';
+ var parser = new OpenLayers.Format.OWSContext();
+ var context = parser.read(text, {map: 'map'});
+ t.ok(context.layers[1].protocol instanceof OpenLayers.Protocol.HTTP, "serviceType KML is translated into an HTTP Protocol");
+ t.eq(context.layers[1].protocol.url, "foo/sundials.kml", "Url of KML file correctly set");
+ t.ok(context.layers[1].protocol.format instanceof OpenLayers.Format.KML, "KML Format associated with protocol");
+ }
+
+ function test_write_gml(t) {
+ t.plan(1);
+ var lon = 5;
+ var lat = 40;
+ var zoom = 5;
+ var map = new OpenLayers.Map( 'map' );
+ var layer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'},
+ {singleTile: true}
+ );
+ var sundials = new OpenLayers.Layer.Vector("GML", {
+ projection: map.displayProjection,
+ strategies: [new OpenLayers.Strategy.Fixed()],
+ protocol: new OpenLayers.Protocol.HTTP({
+ url: "foo/sundials.gml",
+ format: new OpenLayers.Format.GML()
+ })
+ });
+ map.addLayers([layer, sundials]);
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+
+ var owc = new OpenLayers.Format.OWSContext();
+ var output = owc.write(map, {id: 'foo'});
+ var expected = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="foo" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">GML</ows:Title><Server version="2.1.2" service="urn:ogc:serviceType:GML"><OnlineResource xlink:href="foo/sundials.gml" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer></ResourceList></OWSContext>';
+ t.xml_eq(output, expected, "OWSContext with a WMS and a GML vector layer generated correctly");
+ }
+
+ function test_write_kml(t) {
+ t.plan(1);
+ var lon = 5;
+ var lat = 40;
+ var zoom = 5;
+ var map = new OpenLayers.Map( 'map' );
+ var layer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'},
+ {singleTile: true}
+ );
+ var sundials = new OpenLayers.Layer.Vector("KML", {
+ projection: map.displayProjection,
+ strategies: [new OpenLayers.Strategy.Fixed()],
+ protocol: new OpenLayers.Protocol.HTTP({
+ url: "foo/sundials.kml",
+ format: new OpenLayers.Format.KML({
+ extractStyles: true
+ })
+ })
+ });
+ map.addLayers([layer, sundials]);
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+
+ var owc = new OpenLayers.Format.OWSContext();
+ var output = owc.write(map, {id: 'foo'});
+ var expected = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="foo" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name="basic" queryable="0" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://labs.metacarta.com/wms/vmap0" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">KML</ows:Title><Server version="2.2" service="urn:ogc:serviceType:KML"><OnlineResource xlink:href="foo/sundials.kml" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer></ResourceList></OWSContext>';
+ t.xml_eq(output, expected, "OWSContext with a WMS and a KML vector layer generated correctly");
+ }
+
+ function test_nested(t) {
+ t.plan(4);
+ var text = '<OWSContext xmlns="http://www.opengis.net/ows-context" version="0.3.1" id="machu" xsi:schemaLocation="http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><ows:BoundingBox xmlns:ows="http://www.opengis.net/ows" crs="EPSG:4326"><ows:LowerCorner>-40 30</ows:LowerCorner><ows:UpperCorner>55 125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows="http://www.opengis.net/ows">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">General Bathymetric Chart</ows:Title><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">GEBCO</ows:Title><Layer name="GEBCO" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">GEBCO</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/jpeg</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_bathymetry?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/gebco.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer></Layer></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">Administrative boundaries</ows:Title><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">National boundaries</ows:Title><Layer name="GAUL" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">GAUL</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_topography?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/administrative_boundaries_land.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">Maritime boundaries</ows:Title><Layer name="World_Maritime_Boundaries_v4_20090811" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">World_Maritime_Boundaries_v4_20090811</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_topography?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/administrative_boundaries_sea.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer></Layer></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">Cultural Heritage Underwater</ows:Title><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">Sites</ows:Title><Layer name="ARCH_NL" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_NL</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_nl?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer><Layer name="ARCH_PL" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_PL</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_pl?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer><Layer name="ARCH_PT" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_PT</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_pt?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer><Layer name="ARCH_BE" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_BE</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_be?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer><Layer name="ARCH_SE" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_SE</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_se?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer><Layer name="ARCH_DE" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_DE</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_de?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer><Layer name="ARCH_UK" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">ARCH_UK</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_uk?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href="http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png" xmlns:xlink="http://www.w3.org/1999/xlink"/></LegendURL></Style></StyleList></Layer></Layer></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">Theme1</ows:Title><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">layer1</ows:Title><Layer name="TEST_AREA_BE" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">TEST_AREA_BE</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_be?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer><Layer name="TEST_AREA_PT" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">TEST_AREA_PT</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_pt?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer></Layer></Layer><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">Theme2</ows:Title><Layer><ows:Title xmlns:ows="http://www.opengis.net/ows">layer1</ows:Title><Layer name="TEST_AREA_SE" queryable="1" hidden="0"><ows:Title xmlns:ows="http://www.opengis.net/ows">TEST_AREA_SE</ows:Title><ows:OutputFormat xmlns:ows="http://www.opengis.net/ows">image/png</ows:OutputFormat><Server version="1.1.1" service="urn:ogc:serviceType:WMS"><OnlineResource xlink:href="http://foo/bar_se?" xmlns:xlink="http://www.w3.org/1999/xlink"/></Server></Layer></Layer></Layer></ResourceList></OWSContext>';
+ var parser = new OpenLayers.Format.OWSContext();
+ var map = new OpenLayers.Map('map', {allOverlays: true, fractionalZoom: true});
+ var context = parser.read(text, {map: map});
+ t.eq(map.layers.length, 13, "13 layers parsed from document");
+ t.eq(map.layers[0].metadata.nestingPath.join("/"), "General Bathymetric Chart/GEBCO", "Category layers read correctly");
+ t.eq(map.layers[0].metadata.styles[0].legend.url, "http://foo/services/geoservices/legends/machu/gebco.png", "Legend url correctly parsed");
+ map.zoomToExtent(new OpenLayers.Bounds(-40, 30, 55, 125));
+ var owc = parser.write(map, {id: 'machu'});
+ t.xml_eq(text, owc, "Can we roundtrip nested OWSContext successfully?");
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:500px;height:500px"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/QueryStringFilter.html b/misc/openlayers/tests/Format/QueryStringFilter.html
new file mode 100644
index 0000000..b38d1e4
--- /dev/null
+++ b/misc/openlayers/tests/Format/QueryStringFilter.html
@@ -0,0 +1,306 @@
+<html>
+<head>
+ <script src="../../lib/OpenLayers.js"></script>
+ <script type="text/javascript">
+
+ function test_constructor(t) {
+ t.plan(4);
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.QueryStringFilter(options);
+ t.ok(format instanceof OpenLayers.Format.QueryStringFilter,
+ "new OpenLayers.Format.QueryStringFilter object");
+ t.eq(format.foo, "bar", "constructor sets options correctly")
+ t.eq(typeof format.write, 'function', 'format has a write function');
+ t.eq(format.options, options, "format.options correctly set");
+ }
+
+ function test_write(t) {
+ t.plan(30);
+
+ // setup
+
+ var format, filter, params;
+
+ format = new OpenLayers.Format.QueryStringFilter();
+
+ // 1 test
+ filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(0, 1, 2, 3)
+ });
+ params = format.write(filter);
+ t.eq(params.bbox, [0, 1, 2, 3], "correct bbox param if passed a BBOX filter");
+
+ // 3 tests
+ var lon = 100, lat = 200, tolerance = 10;
+ filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ value: new OpenLayers.Geometry.Point(lon, lat),
+ distance: tolerance
+ });
+ params = format.write(filter);
+ t.eq(params.lon, lon, "correct lon param if passed a DWITHIN filter");
+ t.eq(params.lat, lat, "correct lat param if passed a DWITHIN filter");
+ t.eq(params.tolerance, tolerance, "correct tolerance param if passed a DWITHIN filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.WITHIN,
+ value: new OpenLayers.Geometry.Point(lon, lat)
+ });
+ params = format.write(filter);
+ t.eq(params.lon, lon, "correct lon param if passed a WITHIN filter");
+ t.eq(params.lat, lat, "correct lat param if passed a WITHIN filter");
+
+ // Some bbox filters used in the next tests.
+
+ var bboxFilter1 = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(0, 0, 10, 10)
+ });
+
+ var bboxFilter2 = new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(0, 0, 20, 20)
+ });
+
+ // 1 test
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: []
+ });
+ params = format.write(filter);
+ t.eq(params, {}, "returns empty object if given empty AND Logical filter");
+
+ // 1 test
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.OR,
+ filters: [
+ bboxFilter1
+ ]
+ });
+ params = format.write(filter);
+ t.eq(params, {}, "does not support OR Logical filter");
+
+ // 1 test
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ bboxFilter1
+ ]
+ });
+ params = format.write(filter);
+ t.eq(params.bbox, [0, 0, 10, 10],
+ "correct bbox param if passed a Logical filter containing a BBOX");
+
+ // 1 test
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ bboxFilter1, bboxFilter2
+ ]
+ });
+ params = format.write(filter);
+ t.eq(params.bbox, [0, 0, 20, 20],
+ "correct bbox param if passed multiple BBOX filter in a Logical filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an EQUAL_TO filter");
+ t.eq(params["foo__eq"], "bar",
+ "correct param key and value if passed an EQUAL_TO filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an NOT_EQUAL_TO filter");
+ t.eq(params["foo__ne"], "bar",
+ "correct param key and value if passed an NOT_EQUAL_TO filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LESS_THAN,
+ property: "foo",
+ value: "bar"
+ });
+ var params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an LESS_THAN filter");
+ t.eq(params["foo__lt"], "bar",
+ "correct param key and value if passed an LESS_THAN filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ });
+ var params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an LESS_THAN_OR_EQUAL_TO filter");
+ t.eq(params["foo__lte"], "bar",
+ "correct param key and value if passed an LESS_THAN_OR_EQUAL_TO filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.GREATER_THAN,
+ property: "foo",
+ value: "bar"
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an GREATER_THAN filter");
+ t.eq(params["foo__gt"], "bar",
+ "correct param key and value if passed an GREATER_THAN filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an GREATER_THAN_OR_EQUAL_TO filter");
+ t.eq(params["foo__gte"], "bar",
+ "correct param key and value if passed an GREATER_THAN_OR_EQUAL_TO filter");
+
+ // 2 tests
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "foo",
+ value: "bar"
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed a LIKE filter");
+ t.eq(params["foo__ilike"], "bar",
+ "correct param key and value if passed an LIKE filter");
+
+ // 4 tests
+ filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ }),
+ new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LESS_THAN,
+ property: "foo2",
+ value: "baz"
+ })
+ ]
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed an EQUAL_TO filter within a AND filter");
+ t.eq(params["foo__eq"], "bar",
+ "correct param key and value if passed an EQUAL_TO filter within a AND filter");
+ t.eq(params.queryable[1], "foo2",
+ "correct queryable param if passed a LESS_THAN filter within a AND filter");
+ t.eq(params["foo2__lt"], "baz",
+ "correct param key and value if passed a LESS_THAN filter within a AND filter");
+
+ // 2 tests
+ format = new OpenLayers.Format.QueryStringFilter({wildcarded: true});
+ filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "foo",
+ value: "bar"
+ });
+ params = format.write(filter);
+ t.eq(params.queryable[0], "foo",
+ "correct queryable param if passed a LIKE filter (wildcarded true)");
+ t.eq(params["foo__ilike"], "%bar%",
+ "correct param key and value if passed an LIKE filter (wildcarded true)");
+ }
+
+ function test_regex2value(t) {
+ t.plan(16);
+
+ // setup
+
+ var format = new OpenLayers.Format.QueryStringFilter();
+
+ var value;
+ var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LIKE,
+ property: "prop"
+ });
+
+ function serialize(value) {
+ filter.value = value;
+ return format.write(filter).prop__ilike;
+ }
+
+ // test
+
+ value = serialize("foo");
+ t.eq(value, "foo", 'regex2value converts "foo" to "foo"');
+
+ value = serialize("foo%");
+ t.eq(value, "foo\\%", 'regex2value converts "foo%" to "foo\\%"');
+
+ value = serialize("foo.*");
+ t.eq(value, "foo%", 'regex2value converts "foo.*" to "foo%"');
+
+ value = serialize("f.*oo.*");
+ t.eq(value, "f%oo%", 'regex2value converts "f.*oo.*" to "f%oo%"');
+
+ value = serialize("foo.");
+ t.eq(value, "foo_", 'regex2value converts "foo." to "foo_"');
+
+ value = serialize("f.oo.");
+ t.eq(value, "f_oo_", 'regex2value converts "f.oo." to "f_oo_"');
+
+ value = serialize("f.oo.*");
+ t.eq(value, "f_oo%", 'regex2value converts "f.oo.*" to "f_oo%"');
+
+ value = serialize("foo\\\\");
+ t.eq(value, "foo\\\\", 'regex2value converts "foo\\\\" to "foo\\\\"');
+
+ value = serialize("foo\\.");
+ t.eq(value, "foo.", 'regex2value converts "foo\\." to "foo."');
+
+ value = serialize("foo\\\\.");
+ t.eq(value, "foo\\\\_", 'regex2value converts "foo\\\\." to "foo\\\\_"');
+
+ value = serialize("foo\\*");
+ t.eq(value, "foo*", 'regex2value converts "foo\\*" to "foo*"');
+
+ value = serialize("foo\\\\*");
+ t.eq(value, "foo\\\\*", 'regex2value converts "foo\\\\*" to "foo\\\\*"');
+
+ value = serialize("foo\\\\.*");
+ t.eq(value, "foo\\\\%", 'regex2value converts "foo\\\\.*" to "foo\\\\%"');
+
+ value = serialize("fo\\.o.*");
+ t.eq(value, "fo.o%", 'regex2value converts from "fo\\.o.*" to "fo.o%"');
+
+ value = serialize("fo.*o\\.");
+ t.eq(value, "fo%o.", 'regex2value converts from "fo.*o\\." to "to%o."');
+
+ value = serialize("\\*\\..*.\\\\.*\\\\.%");
+ t.eq(value, "*.%_\\\\%\\\\_\\%",
+ 'regex2value converts from "\\*\\..*.\\\\.*\\\\.%" ' +
+ 'to "*.%_\\\\%\\\\_\\%"');
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/SLD.html b/misc/openlayers/tests/Format/SLD.html
new file mode 100644
index 0000000..bc4bd82
--- /dev/null
+++ b/misc/openlayers/tests/Format/SLD.html
@@ -0,0 +1,36 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var test_content = '<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><sld:NamedLayer><sld:Name>TestLayer</sld:Name><sld:UserStyle><sld:Name>foo</sld:Name><sld:FeatureTypeStyle><sld:Rule><sld:Name>bar</sld:Name><ogc:Filter></ogc:Filter><sld:PolygonSymbolizer><sld:Fill><sld:CssParameter name="fill"><ogc:Literal>blue</ogc:Literal></sld:CssParameter></sld:Fill></sld:PolygonSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';
+
+ function test_Format_SLD_constructor(t) {
+ t.plan(3);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.SLD(options);
+ t.ok(format instanceof OpenLayers.Format.SLD,
+ "new OpenLayers.Format.SLD returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ }
+
+ function test_Format_SLD_read(t) {
+ t.plan(4);
+ var sld = new OpenLayers.Format.SLD().read(this.test_content);
+
+ var testLayer = sld.namedLayers["TestLayer"];
+ var userStyles = testLayer.userStyles;
+
+ t.eq(userStyles[0].name, "foo", "SLD correctly reads a UserStyle named 'foo'");
+ t.eq(userStyles[0].rules.length, 1, "The number of rules for the UserStyle is correct");
+ t.eq(userStyles[0].rules[0].name, "bar", "The first rule's name is 'bar'");
+ t.eq(userStyles[0].rules[0].symbolizer.Polygon.fillColor, "blue", "The fillColor for the Polygon symbolizer is correct");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/SLD/v1_0_0.html b/misc/openlayers/tests/Format/SLD/v1_0_0.html
new file mode 100644
index 0000000..fbc18a6
--- /dev/null
+++ b/misc/openlayers/tests/Format/SLD/v1_0_0.html
@@ -0,0 +1,1028 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var xml = new OpenLayers.Format.XML();
+ function readXML(id) {
+ return xml.read(document.getElementById(id).firstChild.nodeValue);
+ }
+
+ var sld =
+ '<StyledLayerDescriptor version="1.0.0" ' +
+ 'xmlns="http://www.opengis.net/sld" ' +
+ 'xmlns:gml="http://www.opengis.net/gml" ' +
+ 'xmlns:ogc="http://www.opengis.net/ogc" ' +
+ 'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
+ 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+ 'xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">' +
+ '<NamedLayer>' +
+ '<Name>AAA161</Name>' +
+ '<UserStyle>' +
+ '<FeatureTypeStyle>' +
+ '<Rule>' +
+ '<Name>stortsteen</Name>' +
+ '<ogc:Filter>' +
+ '<ogc:PropertyIsEqualTo>' +
+ '<ogc:PropertyName>CTE</ogc:PropertyName>' +
+ '<ogc:Literal>V0305</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>' +
+ '<MaxScaleDenominator>50000</MaxScaleDenominator>' +
+ '<PolygonSymbolizer>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#ffffff</CssParameter>' +
+ '</Fill>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">#000000</CssParameter>' +
+ '</Stroke>' +
+ '</PolygonSymbolizer>' +
+ '<TextSymbolizer>' +
+ '<Label>' +
+ 'A <ogc:PropertyName>FOO</ogc:PropertyName> label' +
+ '</Label>' +
+ '<Font>' +
+ '<CssParameter name="font-family">Arial</CssParameter>' +
+ '<CssParameter name="font-size">14</CssParameter>' +
+ '<CssParameter name="font-weight">bold</CssParameter>' +
+ '<CssParameter name="font-style">normal</CssParameter>' +
+ '</Font>' +
+ '<LabelPlacement>' +
+ '<PointPlacement>' +
+ '<AnchorPoint>' +
+ '<AnchorPointX>0.5</AnchorPointX>' +
+ '<AnchorPointY>0.5</AnchorPointY>' +
+ '</AnchorPoint>' +
+ '<Displacement>' +
+ '<DisplacementX>5</DisplacementX>' +
+ '<DisplacementY>5</DisplacementY>' +
+ '</Displacement>' +
+ '<Rotation>45</Rotation>' +
+ '</PointPlacement>' +
+ '</LabelPlacement>' +
+ '<Halo>' +
+ '<Radius>3</Radius>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#ffffff</CssParameter>' +
+ '</Fill>' +
+ '</Halo>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#000000</CssParameter>' +
+ '</Fill>' +
+ '</TextSymbolizer>' +
+ '</Rule>' +
+ '<Rule>' +
+ '<Name>betonbekleding</Name>' +
+ '<ogc:Filter>' +
+ '<ogc:PropertyIsLessThan>' +
+ '<ogc:PropertyName>CTE</ogc:PropertyName>' +
+ '<ogc:Literal>1000</ogc:Literal>' +
+ '</ogc:PropertyIsLessThan>' +
+ '</ogc:Filter>' +
+ '<MaxScaleDenominator>50000</MaxScaleDenominator>' +
+ '<PolygonSymbolizer>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#ffff00</CssParameter>' +
+ '</Fill>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">#0000ff</CssParameter>' +
+ '</Stroke>' +
+ '</PolygonSymbolizer>' +
+ '</Rule>' +
+ '</FeatureTypeStyle>' +
+ '</UserStyle>' +
+ '</NamedLayer>' +
+ '<NamedLayer>' +
+ '<Name>Second Layer</Name>' +
+ '<UserStyle>' +
+ '<FeatureTypeStyle>' +
+ '<Rule>' +
+ '<Name>first rule second layer</Name>' +
+ '<ogc:Filter>' +
+ '<ogc:Or>' +
+ '<ogc:PropertyIsBetween>' +
+ '<ogc:PropertyName>number</ogc:PropertyName>' +
+ '<ogc:LowerBoundary>' +
+ '<ogc:Literal>1064866676</ogc:Literal>' +
+ '</ogc:LowerBoundary>' +
+ '<ogc:UpperBoundary>' +
+ '<ogc:Literal>1065512599</ogc:Literal>' +
+ '</ogc:UpperBoundary>' +
+ '</ogc:PropertyIsBetween>' +
+ '<ogc:PropertyIsLike wildCard="*" singleChar="." escape="!">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>*dog.food!*good</ogc:Literal>' +
+ '</ogc:PropertyIsLike>' +
+ '<ogc:Not>' +
+ '<ogc:PropertyIsLessThanOrEqualTo>' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Literal>5000</ogc:Literal>' +
+ '</ogc:PropertyIsLessThanOrEqualTo>' +
+ '</ogc:Not>' +
+ '</ogc:Or>' +
+ '</ogc:Filter>' +
+ '<MaxScaleDenominator>10000</MaxScaleDenominator>' +
+ '<PointSymbolizer>' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<WellKnownName>star</WellKnownName>' +
+ '<Fill>' +
+ '<CssParameter name="fill">lime</CssParameter>' +
+ '</Fill>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">olive</CssParameter>' +
+ '<CssParameter name="stroke-width">2</CssParameter>' +
+ '</Stroke>' +
+ '</Mark>' +
+ '<Size><ogc:PropertyName>SIZE</ogc:PropertyName></Size>' +
+ '</Graphic>' +
+ '</PointSymbolizer>' +
+ '</Rule>' +
+ '</FeatureTypeStyle>' +
+ '</UserStyle>' +
+ '</NamedLayer>' +
+ '</StyledLayerDescriptor>';
+
+ function test_read(t) {
+ t.plan(23);
+
+ var xml = new OpenLayers.Format.XML();
+ var sldxml = xml.read(sld);
+
+ // test that format options are considered in read
+ var parser = new OpenLayers.Format.SLD({
+ version: "1.0.0",
+ namedLayersAsArray: true
+ });
+ var obj = parser.read(sldxml);
+ t.ok(obj.namedLayers instanceof Array, "namedLayersAsArray option for read works");
+
+ parser = new OpenLayers.Format.SLD.v1_0_0();
+ var obj = parser.read(sldxml, {namedLayersAsArray: true});
+ t.ok(obj.namedLayers instanceof Array, "namedLayersAsArray option for read works");
+ var arrayLen = obj.namedLayers.length;
+
+ var obj = parser.read(sldxml);
+ t.eq(typeof obj.namedLayers, "object", "read returns a namedLayers object by default");
+ // test the named layer count
+ var count = 0;
+ for(var key in obj.namedLayers) {
+ ++count;
+ }
+ t.eq(count, arrayLen, "number of named layers in array equals number of named layers in object");
+
+ var layer, style, rule;
+
+ // check the first named layer
+ layer = obj.namedLayers["AAA161"];
+ t.ok(layer, "first named layer exists");
+ t.ok(layer.userStyles instanceof Array, "(AAA161) layer has array of user styles");
+ t.eq(layer.userStyles.length, 1, "(AAA161) first layer has a single user style");
+ t.eq(layer.userStyles[0].rules.length, 2, "(AAA161) first style has two rules");
+ var rule = layer.userStyles[0].rules[0];
+ t.ok(rule.filter, "(AAA161) first rule has a filter");
+ var symbolizer = rule.symbolizer;
+ t.ok(symbolizer, "(AAA161) first rule has a symbolizer");
+ var poly = symbolizer["Polygon"];
+ t.eq(poly.fillColor, "#ffffff", "(AAA161) first rule has proper fill");
+ t.eq(poly.strokeColor, "#000000", "(AAA161) first rule has proper stroke");
+ var text = symbolizer["Text"];
+ t.eq(text.label, "A ${FOO} label", "(AAA161) first rule has proper text label");
+ t.eq(layer.userStyles[0].propertyStyles["label"], true, "label added to propertyStyles");
+ t.eq(text.fontFamily, "Arial", "(AAA161) first rule has proper font family");
+ t.eq(text.fontColor, "#000000", "(AAA161) first rule has proper text fill");
+ t.eq(text.haloRadius, "3", "(AAA161) first rule has proper halo radius");
+ t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color");
+
+
+ // check the first user style
+ style = layer.userStyles[0];
+ t.ok(style instanceof OpenLayers.Style, "(AAA161,0) user style is instance of OpenLayers.Style");
+ t.eq(style.rules.length, 2, "(AAA161,0) user style has 2 rules");
+
+ // check the second rule
+ rule = style.rules[1];
+ var feature = {
+ layer: {
+ map: {
+ getScale: function(){
+ return 40000;
+ }
+ }
+ },
+ attributes: {
+ CTE: "900"
+ }
+ };
+ t.ok(typeof rule.maxScaleDenominator == "number", "MaxScaleDenominator is a number");
+ t.eq(rule.evaluate(feature), true, "numeric filter comparison evaluates correctly");
+
+ // check for PropertyName size
+ layer = obj.namedLayers["Second Layer"];
+ style = layer.userStyles[0];
+ rule = style.rules[0];
+ t.eq(rule.symbolizer["Point"].graphicWidth, "${SIZE}", "dynamic size correctly set on graphicWidth");
+
+ // etc. I'm convinced read works, really wanted to test write (since examples don't test that)
+ // I'll add more tests here later.
+
+ }
+
+ function test_write(t) {
+ t.plan(3);
+
+ // read first - testing that write produces the SLD above
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var xml = new OpenLayers.Format.XML();
+ var sldxml = xml.read(sld);
+ var obj = parser.read(sldxml);
+
+ var node = parser.write(obj);
+ t.xml_eq(node, sld, "SLD correctly written");
+
+ obj = parser.read(sldxml, {namedLayersAsArray: true});
+ node = parser.write(obj);
+ t.xml_eq(node, sld, "SLD from namedLayers array correctly written");
+
+ // test that 0 fill opacity gets written
+ var symbolizer = {
+ fillColor: "red",
+ fillOpacity: 0
+ };
+ var root = parser.createElementNSPlus("PolygonSymbolizer");
+ var got = parser.writeNode("Fill", symbolizer, root);
+ var expect =
+ '<Fill xmlns="http://www.opengis.net/sld">' +
+ '<CssParameter name="fill">red</CssParameter>' +
+ '<CssParameter name="fill-opacity">0</CssParameter>' +
+ '</Fill>';
+ t.xml_eq(got, expect, "zero fill opacity written");
+ }
+
+ function test_writePointSymbolizer(t) {
+
+ t.plan(3);
+
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var symbolizer, node, exp;
+
+ // test symbolizer with fill color only
+ symbolizer = {
+ "fillColor": "blue"
+ };
+ node = parser.writeNode("sld:PointSymbolizer", symbolizer);
+ exp =
+ '<PointSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<Fill>' +
+ '<CssParameter name="fill">blue</CssParameter>' +
+ '</Fill>' +
+ '<Stroke/>' +
+ '</Mark>' +
+ '</Graphic>' +
+ '</PointSymbolizer>';
+ t.xml_eq(node, exp, "fillColor only written");
+
+ // test symbolizer with stroke color only
+ symbolizer = {
+ "strokeColor": "blue"
+ };
+ node = parser.writeNode("sld:PointSymbolizer", symbolizer);
+ exp =
+ '<PointSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<Fill/>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">blue</CssParameter>' +
+ '</Stroke>' +
+ '</Mark>' +
+ '</Graphic>' +
+ '</PointSymbolizer>';
+ t.xml_eq(node, exp, "strokeColor only written");
+
+ // test symbolizer with graphic name only
+ symbolizer = {
+ "graphicName": "star"
+ };
+ node = parser.writeNode("sld:PointSymbolizer", symbolizer);
+ exp =
+ '<PointSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<WellKnownName>star</WellKnownName>' +
+ '<Fill/>' +
+ '<Stroke/>' +
+ '</Mark>' +
+ '</Graphic>' +
+ '</PointSymbolizer>';
+ t.xml_eq(node, exp, "graphicName only written");
+
+
+ }
+
+
+ function test_writeLineSymbolizer(t) {
+
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var symbolizer, node, exp;
+
+ // test symbolizer with fill color only
+ symbolizer = {
+ strokeDashstyle: "4 4",
+ strokeLinecap: "round",
+ strokeColor: "#0000ff",
+ strokeWidth: 2
+ };
+ node = parser.writeNode("sld:LineSymbolizer", symbolizer);
+ exp =
+ '<LineSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">#0000ff</CssParameter>' +
+ '<CssParameter name="stroke-width">2</CssParameter>' +
+ '<CssParameter name="stroke-dasharray">4 4</CssParameter>' +
+ '<CssParameter name="stroke-linecap">round</CssParameter>' +
+ '</Stroke>' +
+ '</LineSymbolizer>';
+ t.xml_eq(node, exp, "line symbolizer correctly written");
+
+
+ }
+
+ function test_writeTextSymbolizer(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var symbolizer = {
+ "Text": {
+ "label": "This is the ${city} in ${state}.",
+ "fontFamily": "Arial",
+ "fontSize": 10,
+ "fontColor": "blue",
+ "fontWeight": "bold",
+ "fontStyle": "normal",
+ "haloRadius": 2,
+ "haloColor": "white"
+ }
+ };
+ var node = parser.writers["sld"]["TextSymbolizer"].apply(
+ parser, [symbolizer["Text"]]
+ );
+
+ var expected =
+ '<TextSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Label>' +
+ 'This is the ' +
+ '<ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">city</ogc:PropertyName>' +
+ ' in ' +
+ '<ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">state</ogc:PropertyName>' +
+ '.' +
+ '</Label>' +
+ '<Font>' +
+ '<CssParameter name="font-family">Arial</CssParameter>' +
+ '<CssParameter name="font-size">10</CssParameter>' +
+ '<CssParameter name="font-weight">bold</CssParameter>' +
+ '<CssParameter name="font-style">normal</CssParameter>' +
+ '</Font>' +
+ '<Halo>' +
+ '<Radius>2</Radius>' +
+ '<Fill>' +
+ '<CssParameter name="fill">white</CssParameter>' +
+ '</Fill>' +
+ '</Halo>' +
+ '<Fill>' +
+ '<CssParameter name="fill">blue</CssParameter>' +
+ '</Fill>' +
+ '</TextSymbolizer>';
+
+ t.xml_eq(node, expected, "TextSymbolizer correctly written");
+
+ }
+
+ function test_writeSpatialFilter(t) {
+
+ t.plan(1);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0();
+
+ var rule = new OpenLayers.Rule({
+ name: "test",
+ filter: new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(0, 0, 10, 10)
+ })
+ });
+
+ var sld = format.writeNode("sld:Rule", rule);
+
+ var expect =
+ '<Rule xmlns="http://www.opengis.net/sld">' +
+ '<Name>test</Name>' +
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:BBOX>' +
+ '<gml:Box xmlns:gml="http://www.opengis.net/gml">' +
+ '<gml:coordinates decimal="." cs="," ts=" ">0,0 10,10</gml:coordinates>' +
+ '</gml:Box>' +
+ '</ogc:BBOX>' +
+ '</ogc:Filter>' +
+ '</Rule>';
+
+ t.xml_eq(sld, expect, "rule with spatial filter correctly written");
+
+ }
+
+ function test_RasterSymbolizer(t) {
+ t.plan(4);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0();
+
+ var snippet =
+ '<sld:RasterSymbolizer xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<sld:Geometry>' +
+ '<ogc:PropertyName>geom</ogc:PropertyName>' +
+ '</sld:Geometry>' +
+ '<sld:Opacity>1</sld:Opacity>' +
+ '<sld:ColorMap>' +
+ '<sld:ColorMapEntry color="#000000" opacity="0.5" quantity="0" label="nodata"/>' +
+ '<sld:ColorMapEntry color="#00FFFF" quantity="1" label="values"/>' +
+ '<sld:ColorMapEntry color="#FF0000" quantity="1000" label="values"/>' +
+ '</sld:ColorMap>' +
+ '</sld:RasterSymbolizer>';
+ var expected = new OpenLayers.Format.XML().read(snippet).documentElement;
+
+ var symbolizer = {};
+ format.readNode(expected, {symbolizer: symbolizer});
+
+ t.eq(symbolizer.Raster.colorMap[0].quantity, 0, "quantity set correctly");
+ t.eq(symbolizer.Raster.colorMap[0].opacity, 0.5, "opacity set correctly");
+ t.eq(symbolizer.Raster.colorMap[1].opacity, undefined, "non-existent opacity results in undefined");
+
+ var got = format.writeNode("sld:RasterSymbolizer", symbolizer["Raster"]);
+
+ t.xml_eq(got, expected, "Successfully round tripped RasterSymbolizer");
+ }
+
+ function test_zIndex(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+
+ // three zIndex values -> three FeatureTypeStyle elements
+ var style = new OpenLayers.Style2({
+ rules: [
+ new OpenLayers.Rule({
+ filter: new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ }),
+ minScaleDenominator: 100000,
+ maxScaleDenominator: 200000,
+ symbolizers: [
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "green",
+ strokeWidth: 2,
+ zIndex: 2
+ }),
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "red",
+ strokeWidth: 3,
+ zIndex: -1
+ }),
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "blue",
+ strokeWidth: 1,
+ zIndex: 5
+ })
+ ]
+ }),
+ new OpenLayers.Rule({
+ filter: new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "foo",
+ value: "baz"
+ }),
+ symbolizers: [
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "#000000",
+ strokeWidth: 2,
+ zIndex: 2
+ })
+ ]
+ })
+ ]
+ });
+
+ var got = format.writeNode("sld:UserStyle", style);
+ var exp = readXML("zindex_test.sld").documentElement;
+ t.xml_eq(got, exp, "duplicated rules to write zIndex as FeatureTypeStyle elements");
+
+ }
+
+ function test_whitespace(t) {
+ t.plan(1);
+ var xml = readXML("propertyisbetweenwhitespace.sld");
+ var output = new OpenLayers.Format.SLD().read(xml);
+ var filter = output.namedLayers['geonode:US_Stat0'].userStyles[0].rules[0].filter;
+ t.eq(filter.lowerBoundary, 29.7, "whitespace ignored in values and value transformed to number");
+ }
+
+ function test_label_LinePlacement(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+ // labelPerpendicularOffset takes precedence over labelAlign
+ var style = new OpenLayers.Style2({
+ rules: [
+ new OpenLayers.Rule({
+ symbolizers: [
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "red",
+ strokeWidth: 3
+ }),
+ new OpenLayers.Symbolizer.Text({
+ label: "${FOO}",
+ labelPerpendicularOffset: 10,
+ labelAlign: "rb"
+ })
+ ]
+ })
+ ]
+ });
+ var got = format.writeNode("sld:UserStyle", style);
+ var exp = readXML("label_lineplacement_test.sld").documentElement;
+ t.xml_eq(got, exp, "LinePlacement written out correctly");
+ }
+
+ function test_labelAlignToAnchorPosition(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+ var style = new OpenLayers.Style2({
+ rules: [
+ new OpenLayers.Rule({
+ symbolizers: [
+ new OpenLayers.Symbolizer.Text({
+ label: "${FOO}",
+ labelAlign: "rb"
+ })
+ ]
+ })
+ ]
+ });
+ var got = format.writeNode("sld:UserStyle", style);
+ var exp = readXML("label_pointplacement_test.sld").documentElement;
+ t.xml_eq(got, exp, "PointPlacement with labelAlign written out correctly");
+ }
+
+ function test_read_FeatureTypeStyles(t) {
+
+ t.plan(13);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true,
+ namedLayersAsArray: true
+ });
+ var doc = readXML("line_linewithborder.sld");
+
+ var obj = format.read(doc);
+
+ t.eq(obj.namedLayers.length, 1, "got one named layer");
+ var namedLayer = obj.namedLayers[0];
+
+ t.eq(namedLayer.userStyles.length, 1, "got one user style");
+ var userStyle = namedLayer.userStyles[0];
+ t.ok(userStyle instanceof OpenLayers.Style2, "user style represented with OpenLayers.Style2");
+
+ // check rules and symbolizers
+ var rule, symbolizer;
+
+ t.eq(userStyle.rules.length, 2, "pulled two rules (from two FeatureTypeStyle elements)");
+ rule = userStyle.rules[0];
+ t.ok(rule instanceof OpenLayers.Rule, "first rule is an OpenLayers.Rule");
+
+ t.eq(rule.symbolizers && rule.symbolizers.length, 1, "first rule has one symbolizer");
+ symbolizer = rule.symbolizers[0];
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer, "first symbolizer in first rule is an OpenLayers.Symbolizer");
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, "first symbolizer in first rule is an OpenLayers.Symbolizer.Line");
+ t.eq(symbolizer.zIndex, 0, "symbolizer from first FeatureTypeStyle element has zIndex 0");
+
+ rule = userStyle.rules[1];
+ t.eq(rule.symbolizers && rule.symbolizers.length, 1, "second rule has one symbolizer");
+ symbolizer = rule.symbolizers[0];
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer, "first symbolizer in second rule is an OpenLayers.Symbolizer");
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, "first symbolizer in second rule is an OpenLayers.Symbolizer.Line");
+ t.eq(symbolizer.zIndex, 1, "symbolizer from second FeatureTypeStyle element has zIndex 1");
+
+ }
+
+ function test_roundtrip(t) {
+
+ t.plan(5);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true,
+ namedLayersAsArray: true
+ });
+ var doc, out;
+
+ // two FeatureTypeStyle elements and line symbolizers
+ doc = readXML("line_linewithborder.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped line_linewithborder.sld");
+
+ // three FeatureTypeStyle elements and line symbolizers
+ doc = readXML("line_attributebasedline.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped line_attributebasedline.sld");
+
+ // point symbolizer and text symbolizer
+ doc = readXML("point_pointwithdefaultlabel.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped point_pointwithdefaultlabel.sld");
+
+ // polygon symbolizer with fill only
+ doc = readXML("polygon_simplepolygon.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped polygon_simplepolygon.sld");
+
+ // polygon symbolizer and text symbolizer with halo
+ doc = readXML("polygon_labelhalo.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped polygon_labelhalo.sld");
+ }
+
+ </script>
+</head>
+<body>
+<div id="line_linewithborder.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Line with border</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Line w2th border</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#333333</CssParameter>
+ <CssParameter name="stroke-width">5</CssParameter>
+ <CssParameter name="stroke-linecap">round</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#6699FF</CssParameter>
+ <CssParameter name="stroke-width">3</CssParameter>
+ <CssParameter name="stroke-linecap">round</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="line_attributebasedline.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Attribute-based line</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Attribute-based line</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <Name>local-road</Name>
+ <ogc:Filter>
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>type</ogc:PropertyName>
+ <ogc:Literal>local-road</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#009933</CssParameter>
+ <CssParameter name="stroke-width">2</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <Name>secondary</Name>
+ <ogc:Filter>
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>type</ogc:PropertyName>
+ <ogc:Literal>secondary</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#0055CC</CssParameter>
+ <CssParameter name="stroke-width">3</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <Name>highway</Name>
+ <ogc:Filter>
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>type</ogc:PropertyName>
+ <ogc:Literal>highway</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#FF0000</CssParameter>
+ <CssParameter name="stroke-width">6</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="point_pointwithdefaultlabel.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Point with default label</Name>
+ <UserStyle>
+ <Title>GeoServer SLD Cook Book: Point with default label</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PointSymbolizer>
+ <Graphic>
+ <Mark>
+ <WellKnownName>circle</WellKnownName>
+ <Fill>
+ <CssParameter name="fill">#FF0000</CssParameter>
+ </Fill>
+ </Mark>
+ <Size>6</Size>
+ </Graphic>
+ </PointSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Fill>
+ <CssParameter name="fill">#000000</CssParameter>
+ </Fill>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="polygon_simplepolygon.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Simple polygon</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Simple polygon</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#000080</CssParameter>
+ </Fill>
+ </PolygonSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="polygon_labelhalo.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Label halo</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Label halo</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#40FF40</CssParameter>
+ </Fill>
+ <Stroke>
+ <CssParameter name="stroke">#FFFFFF</CssParameter>
+ <CssParameter name="stroke-width">2</CssParameter>
+ </Stroke>
+ </PolygonSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Halo>
+ <Radius>3</Radius>
+ <Fill>
+ <CssParameter name="fill">#FFFFFF</CssParameter>
+ </Fill>
+ </Halo>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="zindex_test.sld"><!--
+<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>bar</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>
+ <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">red</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">3</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>bar</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>
+ <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">green</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">2</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>baz</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">#000000</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">2</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>bar</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>
+ <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">blue</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">1</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+</sld:UserStyle>
+--></div>
+<div id="label_lineplacement_test.sld"><!--
+<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">red</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">3</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ <sld:TextSymbolizer>
+ <sld:Label><ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">FOO</ogc:PropertyName></sld:Label>
+ <sld:LabelPlacement>
+ <sld:LinePlacement>
+ <sld:PerpendicularOffset>10</sld:PerpendicularOffset>
+ </sld:LinePlacement>
+ </sld:LabelPlacement>
+ </sld:TextSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+</sld:UserStyle>
+--></div>
+<div id="label_pointplacement_test.sld"><!--
+<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <sld:TextSymbolizer>
+ <sld:Label><ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">FOO</ogc:PropertyName></sld:Label>
+ <sld:LabelPlacement>
+ <sld:PointPlacement>
+ <sld:AnchorPoint>
+ <sld:AnchorPointX>1</sld:AnchorPointX>
+ <sld:AnchorPointY>0</sld:AnchorPointY>
+ </sld:AnchorPoint>
+ </sld:PointPlacement>
+ </sld:LabelPlacement>
+ </sld:TextSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+</sld:UserStyle>
+--></div>
+<div id="propertyisbetweenwhitespace.sld"><!--
+<sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0">
+ <sld:NamedLayer>
+ <sld:Name>geonode:US_Stat0</sld:Name>
+ <sld:UserStyle>
+ <sld:Name>US_Stat0_5cbbe918</sld:Name>
+ <sld:Title>BMI&lt;25</sld:Title>
+ <sld:FeatureTypeStyle>
+ <sld:Name>name</sld:Name>
+ <sld:Rule>
+ <sld:Title>BMI&lt;25</sld:Title>
+ <ogc:Filter>
+ <ogc:PropertyIsBetween>
+ <ogc:PropertyName>Hlt_st_BMI</ogc:PropertyName>
+ <ogc:LowerBoundary>
+ <ogc:Literal>
+
+
+ 29.7
+
+
+ </ogc:Literal>
+ </ogc:LowerBoundary>
+ <ogc:UpperBoundary>
+ <ogc:Literal>
+
+
+ 36.2
+
+
+ </ogc:Literal>
+ </ogc:UpperBoundary>
+ </ogc:PropertyIsBetween>
+ </ogc:Filter>
+ <sld:PolygonSymbolizer>
+ <sld:Fill>
+ <sld:CssParameter name="fill">#C0F58C</sld:CssParameter>
+ </sld:Fill>
+ <sld:Stroke/>
+ </sld:PolygonSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+ </sld:UserStyle>
+ </sld:NamedLayer>
+</sld:StyledLayerDescriptor>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/SLD/v1_0_0_GeoServer.html b/misc/openlayers/tests/Format/SLD/v1_0_0_GeoServer.html
new file mode 100644
index 0000000..96a3ef6
--- /dev/null
+++ b/misc/openlayers/tests/Format/SLD/v1_0_0_GeoServer.html
@@ -0,0 +1,228 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var xml = new OpenLayers.Format.XML();
+ function readXML(id) {
+ return xml.read(document.getElementById(id).firstChild.nodeValue);
+ }
+
+ function test_VendorExtensions(t) {
+
+ var cases = [
+ "poly_label.sld"
+ ];
+ var len = cases.length;
+ t.plan(len+1);
+
+ var format = new OpenLayers.Format.SLD({
+ profile: "GeoServer",
+ multipleSymbolizers: true,
+ namedLayersAsArray: true,
+ schemaLocation: "http://www.opengis.net/sld StyledLayerDescriptor.xsd"
+ });
+
+ var c, doc, data, out;
+ for (var i=0; i<len; ++i) {
+ c = cases[i];
+ doc = readXML(c);
+ data = format.read(doc);
+ out = format.write(data);
+ t.xml_eq(out, doc.documentElement, "round-tripped " + c);
+ }
+ doc = readXML("poly_label.sld");
+ data = format.read(doc);
+ data.namedLayers[0].userStyles[0].rules[0].symbolizers[1].graphic = false;
+ out = format.write(data);
+ t.xml_eq(out, readXML("poly_label_nographic.sld").documentElement, "If graphic is false no Graphic is outputted");
+ }
+
+ function test_readTextSymbolizer(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.SLD({
+ profile: "GeoServer",
+ multipleSymbolizers: true,
+ namedLayersAsArray: true
+ });
+ doc = readXML("point_pointwithdefaultlabel.sld");
+ var sld = format.read(doc);
+ t.eq(sld.namedLayers[0].userStyles[0].rules[0].symbolizers[1].graphic, false, "graphic set to false on TextSymbolizer");
+ }
+
+ </script>
+</head>
+<body>
+<div id="poly_label.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Polygon with styled label</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Polygon with styled label</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#40FF40</CssParameter>
+ </Fill>
+ <Stroke>
+ <CssParameter name="stroke">#FFFFFF</CssParameter>
+ <CssParameter name="stroke-width">2</CssParameter>
+ </Stroke>
+ </PolygonSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Font>
+ <CssParameter name="font-family">Arial</CssParameter>
+ <CssParameter name="font-size">11</CssParameter>
+ <CssParameter name="font-weight">bold</CssParameter>
+ <CssParameter name="font-style">normal</CssParameter>
+ </Font>
+ <Fill>
+ <CssParameter name="fill">#000000</CssParameter>
+ <CssParameter name="fill-opacity">0.5</CssParameter>
+ </Fill>
+ <Graphic>
+ <Mark>
+ <WellKnownName>square</WellKnownName>
+ <Fill>
+ <CssParameter name="fill">#59BF34</CssParameter>
+ <CssParameter name="fill-opacity">0.8</CssParameter>
+ </Fill>
+ <Stroke>
+ <CssParameter name="stroke">#2D6917</CssParameter>
+ </Stroke>
+ </Mark>
+ <Size>24</Size>
+ </Graphic>
+ <Priority>
+ <ogc:PropertyName>population</ogc:PropertyName>
+ </Priority>
+ <VendorOption name="autoWrap">60</VendorOption>
+ <VendorOption name="followLine">true</VendorOption>
+ <VendorOption name="repeat">300</VendorOption>
+ <VendorOption name="maxDisplacement">150</VendorOption>
+ <VendorOption name="forceLeftToRight">false</VendorOption>
+ <VendorOption name="graphic-margin">3</VendorOption>
+ <VendorOption name="graphic-resize">stretch</VendorOption>
+ <VendorOption name="group">yes</VendorOption>
+ <VendorOption name="spaceAround">10</VendorOption>
+ <VendorOption name="labelAllGroup">true</VendorOption>
+ <VendorOption name="maxAngleDelta">15</VendorOption>
+ <VendorOption name="conflictResolution">false</VendorOption>
+ <VendorOption name="goodnessOfFit">0.3</VendorOption>
+ <VendorOption name="polygonAlign">mbr</VendorOption>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="poly_label_nographic.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Polygon with styled label</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Polygon with styled label</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#40FF40</CssParameter>
+ </Fill>
+ <Stroke>
+ <CssParameter name="stroke">#FFFFFF</CssParameter>
+ <CssParameter name="stroke-width">2</CssParameter>
+ </Stroke>
+ </PolygonSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Font>
+ <CssParameter name="font-family">Arial</CssParameter>
+ <CssParameter name="font-size">11</CssParameter>
+ <CssParameter name="font-weight">bold</CssParameter>
+ <CssParameter name="font-style">normal</CssParameter>
+ </Font>
+ <Fill>
+ <CssParameter name="fill">#000000</CssParameter>
+ <CssParameter name="fill-opacity">0.5</CssParameter>
+ </Fill>
+ <Priority>
+ <ogc:PropertyName>population</ogc:PropertyName>
+ </Priority>
+ <VendorOption name="autoWrap">60</VendorOption>
+ <VendorOption name="followLine">true</VendorOption>
+ <VendorOption name="repeat">300</VendorOption>
+ <VendorOption name="maxDisplacement">150</VendorOption>
+ <VendorOption name="forceLeftToRight">false</VendorOption>
+ <VendorOption name="graphic-margin">3</VendorOption>
+ <VendorOption name="graphic-resize">stretch</VendorOption>
+ <VendorOption name="group">yes</VendorOption>
+ <VendorOption name="spaceAround">10</VendorOption>
+ <VendorOption name="labelAllGroup">true</VendorOption>
+ <VendorOption name="maxAngleDelta">15</VendorOption>
+ <VendorOption name="conflictResolution">false</VendorOption>
+ <VendorOption name="goodnessOfFit">0.3</VendorOption>
+ <VendorOption name="polygonAlign">mbr</VendorOption>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="point_pointwithdefaultlabel.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Point with default label</Name>
+ <UserStyle>
+ <Title>GeoServer SLD Cook Book: Point with default label</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PointSymbolizer>
+ <Graphic>
+ <Mark>
+ <WellKnownName>circle</WellKnownName>
+ <Fill>
+ <CssParameter name="fill">#FF0000</CssParameter>
+ </Fill>
+ </Mark>
+ <Size>6</Size>
+ </Graphic>
+ </PointSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Fill>
+ <CssParameter name="fill">#000000</CssParameter>
+ </Fill>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.html b/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.html
new file mode 100644
index 0000000..6713685
--- /dev/null
+++ b/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.html
@@ -0,0 +1,80 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script src="v1_0_0.js"></script>
+ <script type="text/javascript">
+
+ function test_read(t) {
+
+ t.plan(41);
+
+ var format = new OpenLayers.Format.SOSCapabilities();
+ var obj = format.read(doc);
+
+ t.eq(obj.version, "1.0.0", "Version parsed correctly");
+
+ // service identification (from OWSCommon)
+ t.eq(obj.serviceIdentification.abstract, "WeatherSOS (stable) at IfGI, Muenster, Germany. For more info: http://ifgipedia.uni-muenster.de/kms/documentation/swsl/sos/", "Abstract parsed correctly");
+ t.eq(obj.serviceIdentification.accessConstraints, "NONE", "AccessConstraints parsed correctly");
+ t.eq(obj.serviceIdentification.fees, "NONE", "Fees parsed correctly");
+ for (var key in obj.serviceIdentification.keywords) {
+ t.eq(key, "rain gauge, radiation, pressure, windspeed, winddirection, temperature", "Keywords parsed correctly");
+ }
+ t.eq(obj.serviceIdentification.serviceType.codeSpace, "http://opengeospatial.net", "codeSpace correctly parsed");
+ t.eq(obj.serviceIdentification.serviceType.value, "OGC:SOS", "ServiceType correctly parsed");
+ t.eq(obj.serviceIdentification.serviceTypeVersion, "1.0.0", "ServiceTypeVersion correctly parsed");
+ t.eq(obj.serviceIdentification.title, "IFGI WeatherSOS (stable)", "Title correctly parsed");
+
+ // service provider (from OWSCommon)
+ t.eq(obj.serviceProvider.providerName, "Institute for Geoinformatics, University of Muenster", "ProviderName correctly parsed");
+ t.eq(obj.serviceProvider.providerSite, "http://ifgi.uni-muenster.de", "ProviderSite correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.individualName, "Eike Hinderk Juerrens", "IndividualName parsed correctly");
+ t.eq(obj.serviceProvider.serviceContact.positionName, "Student Associate", "PositionName parsed correctly");
+ t.eq(obj.serviceProvider.serviceContact.role, "", "Role parsed correctly");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.address.administrativeArea, "NRW", "AdministrativeArea correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.address.city, "Muenster", "City correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.address.country, "Germany", "Country correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.address.deliveryPoint, "Weselerstrasse 253", "DeliveryPoint correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.address.electronicMailAddress, "ehjuerrens@uni-muenster.de", "ElectronicMailAddress correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.address.postalCode, "48149", "Postalcode correctly parsed");
+ t.eq(obj.serviceProvider.serviceContact.contactInfo.phone.voice, "+49-251-83-30088", "Voice phone correctly parsed");
+
+ // operationsMetadata (from OWSCommon)
+ t.eq(obj.operationsMetadata.DescribeSensor.dcp.http.post[0].url, "http://v-swe.uni-muenster.de:8080/WeatherSOS/sos", "POST url for DescribeSensor correctly parsed");
+ var counter = 0;
+ for (var key in obj.operationsMetadata.DescribeSensor.parameters.procedure.allowedValues) {
+ if (counter == 0) {
+ t.eq(key, "urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111", "Allowed value (1) for procedure parameter in DescribeSensor request correctly parsed");
+ } else if (counter == 1) {
+ t.eq(key, "urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93", "Allowed value (2) for procedure parameter in DescribeSensor request correctly parsed");
+ }
+ counter++;
+ }
+ t.eq(obj.operationsMetadata.GetFeatureOfInterest.parameters.location.anyValue, true, "AnyValue parsed correctly");
+
+ t.eq(obj.operationsMetadata.GetObservation.parameters.eventTime.allowedValues.range.maxValue, "2009-11-04T14:45:00+01", "Range maxValue parsed correctly");
+ t.eq(obj.operationsMetadata.GetObservation.parameters.eventTime.allowedValues.range.minValue, "2008-02-14T11:03:02+01", "Range minValue parsed correctly");
+
+ // Contents (from SOS)
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.name, "Pressure of the atmosphere", "Name of offering correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.observedProperties[0], "urn:x-ogc:def:property:OGC::BarometricPressure", "ObservedProperty correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.featureOfInterestIds[0], "urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93", "Allowed value (1) for featureOfInterest correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.featureOfInterestIds[1], "urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111", "Allowed value (2) for featureOfInterest correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.procedures[0], "urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93", "Allowed value (1) for procedures correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.procedures[1], "urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111", "Allowed value (2) for procedures correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseFormats[0], 'text/xml;subtype="om/1.0.0"', "Allowed value (1) for responseFormats correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseFormats[1], "application/zip", "Allowed value (2) for responseFormats correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseModes[0], "inline", "Allowed value (1) for responseModes correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseModes[1], "resultTemplate", "Allowed value (2) for responseModes correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.resultModels[0], "ns:Measurement", "Allowed value (1) for resultModels correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.resultModels[1], "ns:Observation", "Allowed value (2) for resultModels correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.time.timePeriod.beginPosition, "2008-12-20T02:29:27+01:00", "TimePeriod beginPosition correctly parsed");
+ t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.time.timePeriod.endPosition, "2009-11-04T14:45:00+01:00", "TimePeriod endPosition correctly parsed");
+
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.js b/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.js
new file mode 100644
index 0000000..78556f5
--- /dev/null
+++ b/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.js
@@ -0,0 +1,484 @@
+var doc = new OpenLayers.Format.XML().read(
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<sos:Capabilities version="1.0.0" updateSequence="2005-12-14T10:12:39+01" xsi:schemaLocation="http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd" xmlns:sos="http://www.opengis.net/sos/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">' +
+ '<ows:ServiceIdentification xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0">' +
+ '<ows:Title>IFGI WeatherSOS (stable)</ows:Title>' +
+ '<ows:Abstract>WeatherSOS (stable) at IfGI, Muenster, Germany. For more info: http://ifgipedia.uni-muenster.de/kms/documentation/swsl/sos/</ows:Abstract>' +
+ '<ows:Keywords>' +
+ '<ows:Keyword>rain gauge, radiation, pressure, windspeed, winddirection, temperature</ows:Keyword>' +
+ '</ows:Keywords>' +
+ '<ows:ServiceType codeSpace="http://opengeospatial.net">OGC:SOS</ows:ServiceType>' +
+ '<ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>' +
+ '<ows:Fees>NONE</ows:Fees>' +
+ '<ows:AccessConstraints>NONE</ows:AccessConstraints>' +
+ '</ows:ServiceIdentification>' +
+ '<ows:ServiceProvider xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0">' +
+ '<ows:ProviderName>Institute for Geoinformatics, University of Muenster</ows:ProviderName>' +
+ '<ows:ProviderSite xlink:href="http://ifgi.uni-muenster.de"/>' +
+ '<ows:ServiceContact>' +
+ '<ows:IndividualName>Eike Hinderk Juerrens</ows:IndividualName>' +
+ '<ows:PositionName>Student Associate</ows:PositionName>' +
+ '<ows:ContactInfo>' +
+ '<ows:Phone>' +
+ '<ows:Voice>+49-251-83-30088</ows:Voice>' +
+ '</ows:Phone>' +
+ '<ows:Address>' +
+ '<ows:DeliveryPoint>Weselerstrasse 253</ows:DeliveryPoint>' +
+ '<ows:City>Muenster</ows:City>' +
+ '<ows:AdministrativeArea>NRW</ows:AdministrativeArea>' +
+ '<ows:PostalCode>48149</ows:PostalCode>' +
+ '<ows:Country>Germany</ows:Country>' +
+ '<ows:ElectronicMailAddress>ehjuerrens@uni-muenster.de</ows:ElectronicMailAddress>' +
+ '</ows:Address>' +
+ '</ows:ContactInfo>' +
+ '<ows:Role/>' +
+ '</ows:ServiceContact>' +
+ '</ows:ServiceProvider>' +
+ '<ows:OperationsMetadata xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0">' +
+ '<ows:Operation name="GetCapabilities">' +
+ '<ows:DCP>' +
+ '<ows:HTTP>' +
+ '<ows:Get xlink:href="http://v-swe.uni-muenster.de:8080/WeatherSOS/sos?"/>' +
+ '<ows:Post xlink:href="http://v-swe.uni-muenster.de:8080/WeatherSOS/sos"/>' +
+ '</ows:HTTP>' +
+ '</ows:DCP>' +
+ '<ows:Parameter name="service">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>SOS</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="updateSequence">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="AcceptVersions">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>1.0.0</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="Sections">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>ServiceIdentification</ows:Value>' +
+ '<ows:Value>ServiceProvider</ows:Value>' +
+ '<ows:Value>OperationsMetadata</ows:Value>' +
+ '<ows:Value>Contents</ows:Value>' +
+ '<ows:Value>All</ows:Value>' +
+ '<ows:Value>Filter_Capabilities</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="AcceptFormats">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>text/xml</ows:Value>' +
+ '<ows:Value>application/zip</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '</ows:Operation>' +
+ '<ows:Operation name="GetObservation">' +
+ '<ows:DCP>' +
+ '<ows:HTTP>' +
+ '<ows:Post xlink:href="http://v-swe.uni-muenster.de:8080/WeatherSOS/sos"/>' +
+ '</ows:HTTP>' +
+ '</ows:DCP>' +
+ '<ows:Parameter name="version">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>1.0.0</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="service">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>SOS</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="srsName">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="offering">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>ATMOSPHERIC_TEMPERATURE</ows:Value>' +
+ '<ows:Value>RAIN_GAUGE</ows:Value>' +
+ '<ows:Value>WIND_DIRECTION</ows:Value>' +
+ '<ows:Value>WIND_SPEED</ows:Value>' +
+ '<ows:Value>HUMIDITY</ows:Value>' +
+ '<ows:Value>LUMINANCE</ows:Value>' +
+ '<ows:Value>ATMOSPHERIC_PRESSURE</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="eventTime">' +
+ '<ows:AllowedValues>' +
+ '<ows:Range>' +
+ '<ows:MinimumValue>2008-02-14T11:03:02+01</ows:MinimumValue>' +
+ '<ows:MaximumValue>2009-11-04T14:45:00+01</ows:MaximumValue>' +
+ '</ows:Range>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="procedure">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</ows:Value>' +
+ '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="observedProperty">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::Temperature</ows:Value>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::Precipitation1Hour</ows:Value>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::WindDirection</ows:Value>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::WindSpeed</ows:Value>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::RelativeHumidity</ows:Value>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::Luminance</ows:Value>' +
+ '<ows:Value>urn:x-ogc:def:property:OGC::BarometricPressure</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="featureOfInterest">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="result">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="responseFormat">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>text/xml;subtype="OM/1.0.0"</ows:Value>' +
+ '<ows:Value>application/zip</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="resultModel">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>om:Observation</ows:Value>' +
+ '<ows:Value>om:CategoryObservation</ows:Value>' +
+ '<ows:Value>om:Measurement</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="responseMode">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>resultTemplate</ows:Value>' +
+ '<ows:Value>inline</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '</ows:Operation>' +
+ '<ows:Operation name="GetObservationById">' +
+ '<ows:DCP>' +
+ '<ows:HTTP>' +
+ '<ows:Post xlink:href="http://v-swe.uni-muenster.de:8080/WeatherSOS/sos"/>' +
+ '</ows:HTTP>' +
+ '</ows:DCP>' +
+ '<ows:Parameter name="version">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>1.0.0</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="service">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>SOS</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="srsName">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="ObservationId">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="responseFormat">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>text/xml;subtype="OM/1.0.0"</ows:Value>' +
+ '<ows:Value>application/zip</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="resultModel">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>om:Observation</ows:Value>' +
+ '<ows:Value>om:CategoryObservation</ows:Value>' +
+ '<ows:Value>om:Measurement</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="responseMode">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>inline</ows:Value>' +
+ '<ows:Value>resultTemplate</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '</ows:Operation>' +
+ '<ows:Operation name="DescribeSensor">' +
+ '<ows:DCP>' +
+ '<ows:HTTP>' +
+ '<ows:Post xlink:href="http://v-swe.uni-muenster.de:8080/WeatherSOS/sos"/>' +
+ '</ows:HTTP>' +
+ '</ows:DCP>' +
+ '<ows:Parameter name="version">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>1.0.0</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="service">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>SOS</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="outputFormat">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>text/xml;subtype="sensorML/1.0.1"</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="procedure">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</ows:Value>' +
+ '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '</ows:Operation>' +
+ '<ows:Operation name="GetFeatureOfInterest">' +
+ '<ows:DCP>' +
+ '<ows:HTTP>' +
+ '<ows:Post xlink:href="http://v-swe.uni-muenster.de:8080/WeatherSOS/sos"/>' +
+ '</ows:HTTP>' +
+ '</ows:DCP>' +
+ '<ows:Parameter name="service">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>SOS</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="version">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>1.0.0</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="featureOfInterestId">' +
+ '<ows:AllowedValues>' +
+ '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ows:Value>' +
+ '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</ows:Value>' +
+ '</ows:AllowedValues>' +
+ '</ows:Parameter>' +
+ '<ows:Parameter name="location">' +
+ '<ows:AnyValue/>' +
+ '</ows:Parameter>' +
+ '</ows:Operation>' +
+ '</ows:OperationsMetadata>' +
+ '<sos:Filter_Capabilities xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:om="http://www.opengis.net/om/1.0" xmlns:swe="http://www.opengis.net/swe/1.0">' +
+ '<ogc:Spatial_Capabilities>' +
+ '<ogc:GeometryOperands>' +
+ '<ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>' +
+ '<ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>' +
+ '<ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>' +
+ '<ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>' +
+ '</ogc:GeometryOperands>' +
+ '<ogc:SpatialOperators>' +
+ '<ogc:SpatialOperator name="BBOX"/>' +
+ '<ogc:SpatialOperator name="Contains"/>' +
+ '<ogc:SpatialOperator name="Intersects"/>' +
+ '<ogc:SpatialOperator name="Overlaps"/>' +
+ '</ogc:SpatialOperators>' +
+ '</ogc:Spatial_Capabilities>' +
+ '<ogc:Temporal_Capabilities>' +
+ '<ogc:TemporalOperands>' +
+ '<ogc:TemporalOperand>gml:TimeInstant</ogc:TemporalOperand>' +
+ '<ogc:TemporalOperand>gml:TimePeriod</ogc:TemporalOperand>' +
+ '</ogc:TemporalOperands>' +
+ '<ogc:TemporalOperators>' +
+ '<ogc:TemporalOperator name="TM_During"/>' +
+ '<ogc:TemporalOperator name="TM_Equals"/>' +
+ '<ogc:TemporalOperator name="TM_After"/>' +
+ '<ogc:TemporalOperator name="TM_Before"/>' +
+ '</ogc:TemporalOperators>' +
+ '</ogc:Temporal_Capabilities>' +
+ '<ogc:Scalar_Capabilities>' +
+ '<ogc:ComparisonOperators>' +
+ '<ogc:ComparisonOperator>Between</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>' +
+ '<ogc:ComparisonOperator>Like</ogc:ComparisonOperator>' +
+ '</ogc:ComparisonOperators>' +
+ '</ogc:Scalar_Capabilities>' +
+ '<ogc:Id_Capabilities>' +
+ '<ogc:FID/>' +
+ '<ogc:EID/>' +
+ '</ogc:Id_Capabilities>' +
+ '</sos:Filter_Capabilities>' +
+ '<sos:Contents>' +
+ '<sos:ObservationOfferingList>' +
+ '<sos:ObservationOffering gml:id="ATMOSPHERIC_TEMPERATURE">' +
+ '<gml:name>Temperature of the atmosphere</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::Temperature"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '<sos:ObservationOffering gml:id="RAIN_GAUGE">' +
+ '<gml:name>Rain</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-11-20T15:35:22+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::Precipitation1Hour"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '<sos:ObservationOffering gml:id="WIND_DIRECTION">' +
+ '<gml:name>Direction of the wind</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::WindDirection"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '<sos:ObservationOffering gml:id="WIND_SPEED">' +
+ '<gml:name>Speed of the wind</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::WindSpeed"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '<sos:ObservationOffering gml:id="HUMIDITY">' +
+ '<gml:name>Humidity of the atmosphere</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-02-14T11:03:02+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::RelativeHumidity"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '<sos:ObservationOffering gml:id="LUMINANCE">' +
+ '<gml:name>Luminance</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::Luminance"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '<sos:ObservationOffering gml:id="ATMOSPHERIC_PRESSURE">' +
+ '<gml:name>Pressure of the atmosphere</gml:name>' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +
+ '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<sos:time>' +
+ '<gml:TimePeriod xsi:type="gml:TimePeriodType">' +
+ '<gml:beginPosition>2008-12-20T02:29:27+01:00</gml:beginPosition>' +
+ '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +
+ '</gml:TimePeriod>' +
+ '</sos:time>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:observedProperty xlink:href="urn:x-ogc:def:property:OGC::BarometricPressure"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93"/>' +
+ '<sos:featureOfInterest xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>' +
+ '<sos:responseFormat>text/xml;subtype="om/1.0.0"</sos:responseFormat>' +
+ '<sos:responseFormat>application/zip</sos:responseFormat>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Measurement</sos:resultModel>' +
+ '<sos:resultModel xmlns:ns="http://www.opengis.net/om/1.0">ns:Observation</sos:resultModel>' +
+ '<sos:responseMode>inline</sos:responseMode>' +
+ '<sos:responseMode>resultTemplate</sos:responseMode>' +
+ '</sos:ObservationOffering>' +
+ '</sos:ObservationOfferingList>' +
+ '</sos:Contents>' +
+'</sos:Capabilities>'
+); \ No newline at end of file
diff --git a/misc/openlayers/tests/Format/SOSGetFeatureOfInterest.html b/misc/openlayers/tests/Format/SOSGetFeatureOfInterest.html
new file mode 100644
index 0000000..c80078f
--- /dev/null
+++ b/misc/openlayers/tests/Format/SOSGetFeatureOfInterest.html
@@ -0,0 +1,80 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_SOSGetFeatureOfInterest_single(t) {
+ t.plan(6);
+
+ var parser = new OpenLayers.Format.SOSGetFeatureOfInterest();
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<sa:SamplingPoint xmlns:sa="http://www.opengis.net/sampling/1.0" xmlns:gml="http://www.opengis.net/gml" gml:id="urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56">' +
+ '<gml:name>Roof of the IfGI</gml:name>' +
+ '<sa:position>' +
+ '<gml:Point>' +
+ '<gml:pos srsName="urn:ogc:def:crs:EPSG:4326">52.1524 5.3722</gml:pos>' +
+ '</gml:Point>' +
+ '</sa:position>' +
+ '</sa:SamplingPoint>';
+
+ var res = parser.read(text);
+ t.eq(res.length, 1, "One feature parsed from response");
+ t.eq(res[0].attributes.id, "urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56", "gml:id correctly parsed");
+ t.eq(res[0].attributes.name, "Roof of the IfGI", "gml:name correctly parsed");
+ t.eq(res[0].geometry instanceof OpenLayers.Geometry.Point, true, "Geometry is a point geometry");
+ t.eq(res[0].geometry.x, 5.3722, "Geometry x coordinate correctly parsed");
+ t.eq(res[0].geometry.y, 52.1524, "Geometry y coordinate correctly parsed");
+ }
+
+ function test_read_SOSGetFeatureOfInterest_multiple(t) {
+ t.plan(6);
+
+ var parser = new OpenLayers.Format.SOSGetFeatureOfInterest();
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<gml:FeatureCollection xmlns:gml="http://www.opengis.net/gml" xmlns:sa="http://www.opengis.net/sampling/1.0">' +
+ '<gml:featureMember>' +
+ '<sa:SamplingPoint gml:id="urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93">' +
+ '<gml:name>weather @ roof of the ifgi, MS, Germany</gml:name>' +
+ '<sa:position>' +
+ '<gml:Point>' +
+ '<gml:pos srsName="urn:ogc:def:crs:EPSG:4326">51.9412 7.6103</gml:pos>' +
+ '</gml:Point>' +
+ '</sa:position>' +
+ '</sa:SamplingPoint>' +
+ '</gml:featureMember>' +
+ '<gml:featureMember>' +
+ '<sa:SamplingPoint gml:id="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111">' +
+ '<gml:name>waether @ roof of the FH Kaernten, Villach, Austria</gml:name>' +
+ '<sa:position>' +
+ '<gml:Point>' +
+ '<gml:pos srsName="urn:ogc:def:crs:EPSG:4326">46.611644 13.883498</gml:pos>' +
+ '</gml:Point>' +
+ '</sa:position>' +
+ '</sa:SamplingPoint>' +
+ '</gml:featureMember>' +
+ '</gml:FeatureCollection>';
+
+ var res = parser.read(text);
+ t.eq(res.length, 2, "Two features parsed from response");
+ t.eq(res[0].attributes.id, "urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93", "gml:id correctly parsed");
+ t.eq(res[1].attributes.name, "waether @ roof of the FH Kaernten, Villach, Austria", "gml:name correctly parsed");
+ t.eq(res[1].geometry instanceof OpenLayers.Geometry.Point, true, "Geometry is a point geometry");
+ t.eq(res[1].geometry.x, 13.883498, "Geometry x coordinate correctly parsed");
+ t.eq(res[1].geometry.y, 46.611644, "Geometry y coordinate correctly parsed");
+ }
+
+ function test_write_SOSGetFeatureOfInterest(t) {
+ t.plan(1);
+ var expect = '<GetFeatureOfInterest xmlns="http://www.opengis.net/sos/1.0" version="1.0.0" service="SOS" xsi:schemaLocation="http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><FeatureOfInterestId>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</FeatureOfInterestId><FeatureOfInterestId>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</FeatureOfInterestId></GetFeatureOfInterest>';
+ var format = new OpenLayers.Format.SOSGetFeatureOfInterest();
+ var output = format.writeNode("sos:GetFeatureOfInterest", {fois: ['urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93', 'urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111']});
+ t.xml_eq(output, expect, "Request XML is written out correctly");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/SOSGetObservation.html b/misc/openlayers/tests/Format/SOSGetObservation.html
new file mode 100644
index 0000000..3256d5a
--- /dev/null
+++ b/misc/openlayers/tests/Format/SOSGetObservation.html
@@ -0,0 +1,183 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_SOSGetObservation(t) {
+ t.plan(13);
+
+ var parser = new OpenLayers.Format.SOSGetObservation();
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<om:ObservationCollection xmlns:om="http://www.opengis.net/om/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sa="http://www.opengis.net/sampling/1.0" gml:id="oc_0" xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd http://www.opengis.net/sampling/1.0 http://schemas.opengis.net/sampling/1.0.0/sampling.xsd">' +
+ '<gml:boundedBy>' +
+ '<gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">' +
+ '<gml:lowerCorner>52.1524 5.3722</gml:lowerCorner>' +
+ '<gml:upperCorner>52.1524 5.3722</gml:upperCorner>' +
+ '</gml:Envelope>' +
+ '</gml:boundedBy>' +
+ '<om:member>' +
+ '<om:Measurement gml:id="o_51082">' +
+ '<om:samplingTime>' +
+ '<gml:TimeInstant xsi:type="gml:TimeInstantType">' +
+ '<gml:timePosition>2009-12-02T10:35:00.000+01:00</gml:timePosition>' +
+ '</gml:TimeInstant>' +
+ '</om:samplingTime>' +
+ '<om:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56"/>' +
+ '<om:observedProperty xlink:href="urn:x-ogc:def:property:OGC::Temperature"/>' +
+ '<om:featureOfInterest>' +
+ '<sa:SamplingPoint gml:id="urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56">' +
+ '<gml:name>Roof of the IfGI</gml:name>' +
+ '<sa:position>' +
+ '<gml:Point>' +
+ '<gml:pos srsName="urn:ogc:def:crs:EPSG:4326">52.1524 5.3722</gml:pos>' +
+ '</gml:Point>' +
+ '</sa:position>' +
+ '</sa:SamplingPoint>' +
+ '</om:featureOfInterest>' +
+ '<om:result uom="Cel">4.9</om:result>' +
+ '</om:Measurement>' +
+ '</om:member>' +
+ '</om:ObservationCollection>';
+
+ var res = parser.read(text);
+ t.eq(res.measurements.length, 1, "One measurement parsed");
+ t.eq(res.id, "oc_0", "Observation collection id correctly parsed");
+ var measurement = res.measurements[0];
+ t.eq(measurement.observedProperty, "urn:x-ogc:def:property:OGC::Temperature", "Observed property correctly parsed");
+ t.eq(measurement.procedure, "urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56", "Procedure correctly parsed");
+ t.eq(measurement.result.uom, "Cel", "Units of measurement correctly parsed");
+ t.eq(measurement.result.value, "4.9", "Value correctly parsed");
+ t.eq(measurement.samplingTime.timeInstant.timePosition, "2009-12-02T10:35:00.000+01:00", "Sampling time correctly parsed");
+
+ var response = [];
+ response.push('<?xml version="1.0" encoding="UTF-8"?>',
+'<om:ObservationCollection gml:id="oc_0" xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd http://www.opengis.net/sampling/1.0 http://schemas.opengis.net/sampling/1.0.0/sampling.xsd" xmlns:om="http://www.opengis.net/om/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:swe="http://www.opengis.net/swe/1.0.1" xmlns:sa="http://www.opengis.net/sampling/1.0">',
+' <gml:boundedBy>',
+' <gml:Envelope srsName="urn:ogc:def:crs:EPSG:4326">',
+' <gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>',
+' <gml:upperCorner>51.9412 13.883498</gml:upperCorner>',
+' </gml:Envelope>',
+' </gml:boundedBy>',
+' <om:member>',
+' <om:Observation gml:id="ot_583227">',
+' <om:samplingTime>',
+' <gml:TimePeriod xsi:type="gml:TimePeriodType">',
+' <gml:beginPosition>2009-09-28T13:45:00.000+02:00</gml:beginPosition>',
+' <gml:endPosition>2009-09-28T13:45:00.000+02:00</gml:endPosition>',
+' </gml:TimePeriod>',
+' </om:samplingTime>',
+' <om:procedure xlink:href="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111"/>',
+' <om:observedProperty>',
+' <swe:CompositePhenomenon gml:id="cpid0" dimension="1">',
+' <gml:name>resultComponents</gml:name>',
+' <swe:component xlink:href="urn:ogc:data:time:iso8601"/>',
+' <swe:component xlink:href="urn:ogc:def:property:OGC::Precipitation1Hour"/>',
+' </swe:CompositePhenomenon>',
+' </om:observedProperty>',
+' <om:featureOfInterest>',
+' <gml:FeatureCollection>',
+' <gml:featureMember>',
+' <sa:SamplingPoint gml:id="urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111" xsi:schemaLocation=" http://www.opengis.net/sampling/1.0 http://schemas.opengis.net/sampling/1.0.0/sampling.xsd">',
+' <gml:name>waether @ roof of the FH Kaernten, Villach, Austria</gml:name>',
+' <sa:sampledFeature xlink:href="urn:ogc:def:nil:OGC:unknown"/>',
+' <sa:position>',
+' <gml:Point>',
+' <gml:pos srsName="urn:ogc:def:crs:EPSG:4326">46.611644 13.883498</gml:pos>',
+' </gml:Point>',
+' </sa:position>',
+' </sa:SamplingPoint>',
+' </gml:featureMember>',
+' </gml:FeatureCollection>',
+' </om:featureOfInterest>',
+' <om:result>',
+' <swe:DataArray>',
+' <swe:elementCount>',
+' <swe:Count>',
+' <swe:value>1</swe:value>',
+' </swe:Count>',
+' </swe:elementCount>',
+' <swe:elementType name="Components">',
+' <swe:DataRecord>',
+' <swe:field name="Time">',
+' <swe:Time definition="urn:ogc:data:time:iso8601"/>',
+' </swe:field>',
+' <swe:field name="feature">',
+' <swe:Text definition="urn:ogc:data:feature"/>',
+' </swe:field>',
+' <swe:field name="urn:ogc:def:property:OGC::Precipitation1Hour">',
+' <swe:Quantity definition="urn:ogc:def:property:OGC::Precipitation1Hour">',
+' <swe:uom code="mm"/>',
+' </swe:Quantity>',
+' </swe:field>',
+' </swe:DataRecord>',
+' </swe:elementType>',
+' <swe:encoding>',
+' <swe:TextBlock decimalSeparator="." tokenSeparator="," blockSeparator=";"/>',
+' </swe:encoding>',
+' <swe:values>2009-09-28T13:45:00.000+02:00,urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111,0.0;</swe:values>',
+' </swe:DataArray>',
+' </om:result>',
+' </om:Observation>',
+' </om:member>',
+'</om:ObservationCollection>');
+ text = response.join("");
+ var res = parser.read(text);
+ t.eq(res.observations.length, 1, "1 observation parsed");
+ var observation = res.observations[0];
+ t.eq(observation.procedure, "urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111", "procedure parsed correctly");
+ t.eq(observation.fois.length, 1, "One foi parsed for the observation");
+ var foi = observation.fois[0];
+ var feature = foi.features[0];
+ t.eq(feature.attributes.id, "urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111", "Foi id correctly parsed");
+ t.eq(feature.attributes.name, "waether @ roof of the FH Kaernten, Villach, Austria", "Foi name correctly parsed");
+ t.ok(feature.geometry instanceof OpenLayers.Geometry.Point, "Geometry correctly parsed");
+ }
+
+ function test_write_SOSGetObservation(t) {
+ t.plan(2);
+ var expect = '<GetObservation xmlns="http://www.opengis.net/sos/1.0" version="1.0.0" service="SOS" xsi:schemaLocation="http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><offering>TEMPERATURE</offering><eventTime><ogc:TM_Equals xmlns:ogc="http://www.opengis.net/ogc"><ogc:PropertyName>urn:ogc:data:time:iso8601</ogc:PropertyName><gml:TimeInstant xmlns:gml="http://www.opengis.net/gml"><gml:timePosition>latest</gml:timePosition></gml:TimeInstant></ogc:TM_Equals></eventTime><procedure>urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56</procedure><observedProperty>urn:x-ogc:def:property:OGC::Temperature</observedProperty><responseFormat>text/xml;subtype="om/1.0.0"</responseFormat><resultModel>Measurement</resultModel><responseMode>inline</responseMode></GetObservation>';
+ var format = new OpenLayers.Format.SOSGetObservation();
+ var output = format.write({eventTime: 'latest', resultModel: 'Measurement', responseMode: 'inline',
+ procedures: ['urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56'], responseFormat: 'text/xml;subtype="om/1.0.0"',
+ offering: 'TEMPERATURE', observedProperties: ['urn:x-ogc:def:property:OGC::Temperature']});
+ t.xml_eq(output, expect, "Request XML is written out correctly");
+
+ var expected = [];
+
+ expected.push('<?xml version="1.0" encoding="UTF-8"?>',
+'<GetObservation xmlns="http://www.opengis.net/sos/1.0"',
+' xmlns:gml="http://www.opengis.net/gml"',
+' xmlns:om="http://www.opengis.net/om/1.0"',
+' xmlns:ogc="http://www.opengis.net/ogc"',
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',
+' xsi:schemaLocation="http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd"',
+' service="SOS" version="1.0.0">',
+' <offering>RAIN_GAUGE</offering>',
+' <eventTime>',
+' <ogc:TM_Equals>',
+' <ogc:PropertyName>urn:ogc:data:time:iso8601</ogc:PropertyName>',
+' <gml:TimeInstant>',
+' <gml:timePosition>latest</gml:timePosition>',
+' </gml:TimeInstant>',
+' </ogc:TM_Equals>',
+' </eventTime>',
+' <observedProperty>urn:ogc:def:property:OGC::Precipitation1Hour</observedProperty>',
+' <featureOfInterest>',
+' <ObjectID>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ObjectID>',
+' </featureOfInterest>',
+' <responseFormat>text/xml;subtype="om/1.0.0"</responseFormat>',
+'</GetObservation>');
+ expect = expected.join("");
+ var output = format.write({eventTime: 'latest', offering: 'RAIN_GAUGE',
+ observedProperties: ['urn:ogc:def:property:OGC::Precipitation1Hour'],
+ responseFormat: 'text/xml;subtype="om/1.0.0"',
+ foi: {objectId: 'urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93'}});
+ t.xml_eq(output, expect, "Request XML is written out correctly");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/Text.html b/misc/openlayers/tests/Format/Text.html
new file mode 100644
index 0000000..9b18bb5
--- /dev/null
+++ b/misc/openlayers/tests/Format/Text.html
@@ -0,0 +1,49 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_basic(t) {
+ t.plan(5);
+ var format = new OpenLayers.Format.Text({extractStyles: true});
+ var features = format.read(OpenLayers.Util.getElement("content").value);
+ t.eq(features[0].style.externalGraphic, format.defaultStyle.externalGraphic, "style is set to defaults if no style props set in text file");
+ var features = format.read(OpenLayers.Util.getElement("contentMarker").value);
+ t.eq(features[0].style.externalGraphic, OpenLayers.Util.getImagesLocation() + "marker.png", "marker set correctly by default.");
+
+ var features = format.read(OpenLayers.Util.getElement("content2").value);
+ t.eq(features.length, 2, "two features read");
+ t.eq(features[0].style.externalGraphic, "marker.png", "marker set correctly from data.");
+ // t.eq(format.defaultStyle.externalGraphic, "../../img/marker.png", "defaultStyle externalGraphic not changed by pulling from data");
+
+ var format = new OpenLayers.Format.Text({extractStyles: false});
+ var features = format.read(OpenLayers.Util.getElement("content2").value);
+ t.eq(features[0].style, null, "extractStyles: false results in null style property, even with style properties used");
+ }
+ function test_extra(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.Text();
+ var features = format.read(OpenLayers.Util.getElement("content3").value);
+ t.eq(features[0].attributes.whee, "chicken", "extra attributes are stored for later use");
+ }
+ </script>
+</head>
+<body>
+<textarea id="content">
+point
+5,5
+</textarea>
+<textarea id="contentMarker">
+point iconSize
+5,5 8,8
+</textarea>
+<textarea id="content2">
+point icon
+5,5 marker.png
+10,10 marker2.png
+</textarea>
+<textarea id="content3">
+point whee
+5,5 chicken
+</textarea>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WCSCapabilities.html b/misc/openlayers/tests/Format/WCSCapabilities.html
new file mode 100644
index 0000000..b3e90b6
--- /dev/null
+++ b/misc/openlayers/tests/Format/WCSCapabilities.html
@@ -0,0 +1,43 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read(t) {
+ t.plan(4);
+
+ var _v1_0_0 = OpenLayers.Format.WCSCapabilities.v1_0_0.prototype.read;
+ var _v1_1_0 = OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read;
+
+ var parser = new OpenLayers.Format.WCSCapabilities();
+
+ // version 1.0.0
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<wcs:WCS_Capabilities version="1.0.0" xmlns:wcs="http://www.opengis.net/wcs"></wcs:WCS_Capabilities>';
+ OpenLayers.Format.WCSCapabilities.v1_0_0.prototype.read = function() {
+ t.ok(true, "Version 1.0.0 detected");
+ return {};
+ }
+ var res = parser.read(text);
+ t.eq(res.version, "1.0.0", "version 1.0.0 written to result object");
+ OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read = _v1_1_0;
+
+ // version 1.1.0
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<wcs:WCS_Capabilities version="1.1.0" xmlns:wcs="http://www.opengis.net/wcs/1.1"></wcs:WCS_Capabilities>';
+ OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read = function() {
+ t.ok(true, "Version 1.1.0 detected");
+ return {};
+ }
+ var res = parser.read(text);
+ t.eq(res.version, "1.1.0", "version 1.1.0 written to result object");
+ OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read = _v1_1_0;
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WCSCapabilities/v1.html b/misc/openlayers/tests/Format/WCSCapabilities/v1.html
new file mode 100644
index 0000000..180edc7
--- /dev/null
+++ b/misc/openlayers/tests/Format/WCSCapabilities/v1.html
@@ -0,0 +1,87 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.WCSCapabilities();
+ var text = '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<ows:ExceptionReport language="en" version="1.0.0"' +
+ ' xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows">' +
+ ' <ows:Exception locator="foo" exceptionCode="InvalidParameterValue">' +
+ ' <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +
+ ' <ows:ExceptionText>Second exception line</ows:ExceptionText>' +
+ ' </ows:Exception>' +
+ '</ows:ExceptionReport>';
+
+ var obj = parser.read(text);
+ t.ok(!!obj.error, "Error reported correctly"); // The above should place an error in obj.error
+ }
+
+ function test_read(t) {
+ t.plan(34); // Number of tests performed: If you add a test below, be sure to increment this accordingly
+
+ var parser = new OpenLayers.Format.WCSCapabilities();
+
+ // MapServer, v1.0.0
+ var text = '<?xml version="1.0" encoding="UTF-8"?><WCS_Capabilities xmlns="http://www.opengis.net/wcs" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" updateSequence="0" xsi:schemaLocation="http://www.opengis.net/wcs http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd"><Service><name>MapServer WCS</name><label>WCS Sample Data Server 1.0.0</label><keywords><keyword>Geospatial WebServices</keyword><keyword>Luxembourg!</keyword></keywords><responsibleParty><individualName>Franko Lemmer</individualName><organisationName>CRP Henri Tudor</organisationName><positionName>R+D engineer</positionName><contactInfo><phone><voice>6463320</voice><facsimile>6465955</facsimile></phone><address><deliveryPoint>66, rue de Luxembourg</deliveryPoint><city>Esch-sur-Alzette</city><administrativeArea/><postalCode>97202</postalCode><country>Luxembourg</country><electronicMailAddress>franko.lemmer@flensburger.de</electronicMailAddress></address><onlineResource xlink:type="simple" xlink:href="http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></contactInfo></responsibleParty><fees>mucho dinero</fees><accessConstraints>Open to the public</accessConstraints></Service><Capability><Request><GetCapabilities><DCPType><HTTP><Get><OnlineResource xlink:type="simple" xlink:href="http://services.magnificent.get.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></Get></HTTP></DCPType><DCPType><HTTP><Post><OnlineResource xlink:type="simple" xlink:href="http://services.magnificent.post.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></Post></HTTP></DCPType></GetCapabilities><DescribeCoverage><DCPType><HTTP><Get><OnlineResource xlink:type="simple" xlink:href="http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></Get></HTTP></DCPType><DCPType><HTTP><Post><OnlineResource xlink:type="simple" xlink:href="http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></Post></HTTP></DCPType></DescribeCoverage><GetCoverage><DCPType><HTTP><Get><OnlineResource xlink:type="simple" xlink:href="http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></Get></HTTP></DCPType><DCPType><HTTP><Post><OnlineResource xlink:type="simple" xlink:href="http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;"/></Post></HTTP></DCPType></GetCoverage></Request><Exception><Format>application/vnd.ogc.se_xml</Format></Exception></Capability><ContentMetadata><CoverageOfferingBrief><name>ro_dsm</name><label>Rotterdam DSM</label><lonLatEnvelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84"><gml:pos>4.44444 51.515151</gml:pos><gml:pos>5.55555 52.525252</gml:pos></lonLatEnvelope></CoverageOfferingBrief><CoverageOfferingBrief><name>ro_dsm_mini</name><label>ro_dsm_mini</label><lonLatEnvelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84"><gml:pos>4.47489346945755 51.9159453786927</gml:pos><gml:pos>4.47687824892444 51.9170706688033</gml:pos></lonLatEnvelope></CoverageOfferingBrief><CoverageOfferingBrief><name>ro_irra</name><label>ro_irra</label><lonLatEnvelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84"><gml:pos>4.471333734139 51.912813427383</gml:pos><gml:pos>4.4808508475645 51.9248713705576</gml:pos></lonLatEnvelope></CoverageOfferingBrief><CoverageOfferingBrief><name>ro_irra_ext</name><label>ro_irra_ext</label><lonLatEnvelope srsName="urn:ogc:def:crs:OGC:1.3:CRS84"><gml:pos>4.10024171314823 51.9359764992844</gml:pos><gml:pos>4.21909054278063 52.001415228243</gml:pos></lonLatEnvelope></CoverageOfferingBrief></ContentMetadata></WCS_Capabilities>';
+
+ var res = parser.read(text);
+
+ t.ok(!res.error, "Parsing XML generated no errors");
+ t.eq(res.service.fees, "mucho dinero", "Service>Fees correctly parsed");
+ t.eq(res.service.accessConstraints, "Open to the public", "Service>AccessConstraints correctly parsed");
+ t.eq(res.service.keywords.length, 2, "Correct number of Service>Keywords found");
+ t.eq(res.service.keywords[0], "Geospatial WebServices", "Service>Keywords correctly parsed");
+ t.eq(res.service.label, "WCS Sample Data Server 1.0.0", "Service>Label correctly parsed");
+ t.eq(res.service.name, "MapServer WCS", "Service>Name correctly parsed");
+
+ var responsibleParty = res.service.responsibleParty;
+ t.eq(responsibleParty.individualName, "Franko Lemmer", "Service>ResponsibleParty>IndividualName correctly parsed");
+ t.eq(responsibleParty.organisationName, "CRP Henri Tudor", "Service>ResponsibleParty>OrganisationName correctly parsed");
+ t.eq(responsibleParty.positionName, "R+D engineer", "Service>ResponsibleParty>PositionName correctly parsed");
+ t.eq(responsibleParty.contactInfo.address.city, "Esch-sur-Alzette", "Service>responsibleParty>ContactInfo>Address>City correctly parsed");
+ t.eq(responsibleParty.contactInfo.address.country, "Luxembourg", "Service>responsibleParty>ContactInfo>Address>Country correctly parsed");
+ t.eq(responsibleParty.contactInfo.address.deliveryPoint, "66, rue de Luxembourg", "Service>responsibleParty>ContactInfo>Address>DeliveryPoint correctly parsed");
+ t.eq(responsibleParty.contactInfo.address.electronicMailAddress, "franko.lemmer@flensburger.de", "Service>responsibleParty>ContactInfo>Address>ElectronicMailAddress correctly parsed");
+ t.eq(responsibleParty.contactInfo.address.postalCode, "97202", "Service>responsibleParty>ContactInfo>Address>PostalCode correctly parsed");
+ t.eq(responsibleParty.contactInfo.phone.facsimile, "6465955", "Service>responsibleParty>ContactInfo>Phone>Facsimile correctly parsed");
+ t.eq(responsibleParty.contactInfo.phone.voice, "6463320", "Service>responsibleParty>ContactInfo>Phone>Voice correctly parsed");
+
+ var metadata = res.contentMetadata[0];
+
+ t.eq(metadata.name, "ro_dsm", "ContentMetadata>Name correctly parsed");
+ t.eq(metadata.label, "Rotterdam DSM", "ContentMetadata>Label correctly parsed");
+ t.eq(metadata.lonLatEnvelope.min.x, 51.515151, "ContentMetadata>lonLatEnvelope>Min>Lat correctly parsed");
+ t.eq(metadata.lonLatEnvelope.min.y, 4.44444, "ContentMetadata>lonLatEnvelope>Min>Lon correctly parsed");
+ t.eq(metadata.lonLatEnvelope.max.x, 52.525252, "ContentMetadata>lonLatEnvelope>Max>Lat correctly parsed");
+ t.eq(metadata.lonLatEnvelope.max.y, 5.55555, "ContentMetadata>lonLatEnvelope>Max>Lon correctly parsed");
+ t.eq(metadata.lonLatEnvelope.srsName, "urn:ogc:def:crs:OGC:1.3:CRS84", "ContentMetadata>lonLatEnvelope>SrsName correctly parsed");
+ t.eq(res.contentMetadata.length, 4, "Correct number of metadata records found");
+
+
+ // MapServer, v1.1.0
+ text = '<?xml version="1.0" encoding="UTF-8"?><Capabilities xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ogc="http://www.opengis.net/ogc" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsGetCapabilities.xsd http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsAll.xsd"><ows:ServiceIdentification><ows:Title>Web-Service Demo with data stored at TUDOR site</ows:Title><ows:Abstract>This installation serves different Web-Service types (WMS, WFS) for testing</ows:Abstract><ows:Keywords><ows:Keyword>Geospatial WebServices</ows:Keyword><ows:Keyword>Keyword One</ows:Keyword><ows:Keyword>Keyword Two!!</ows:Keyword></ows:Keywords><ows:ServiceType codeSpace="OGC">OGC WCS</ows:ServiceType><ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion><ows:Fees>No fee!</ows:Fees><ows:AccessConstraints>Unconstrained!</ows:AccessConstraints></ows:ServiceIdentification><ows:ServiceProvider><ows:ProviderName>CRP Henri Tudor</ows:ProviderName><ows:ProviderSite xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/><ows:ServiceContact><ows:IndividualName>Roy Dumerde</ows:IndividualName><ows:PositionName>R+D engineer</ows:PositionName><ows:ContactInfo><ows:Phone><ows:Voice>6463320</ows:Voice><ows:Facsimile>6465955</ows:Facsimile></ows:Phone><ows:Address><ows:DeliveryPoint>66, rue de Luxembourg</ows:DeliveryPoint><ows:City>Esch-sur-Alzette</ows:City><ows:AdministrativeArea/><ows:PostalCode>97202</ows:PostalCode><ows:Country>Luxembourg</ows:Country><ows:ElectronicMailAddress>flappy@tutones.com</ows:ElectronicMailAddress></ows:Address><ows:OnlineResource xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/><ows:HoursOfService>24/7</ows:HoursOfService><ows:ContactInstructions>by phone</ows:ContactInstructions></ows:ContactInfo><ows:Role>GIS-Analyst</ows:Role></ows:ServiceContact></ows:ServiceProvider><ows:OperationsMetadata><ows:Operation name="GetCapabilities"><ows:DCP><ows:HTTP><ows:Get xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/><ows:Post xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/></ows:HTTP></ows:DCP><ows:Parameter name="service"><ows:AllowedValues><ows:Value>WCS</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="version"><ows:AllowedValues><ows:Value>1.1.0</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name="DescribeCoverage"><ows:DCP><ows:HTTP><ows:Get xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/><ows:Post xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/></ows:HTTP></ows:DCP><ows:Parameter name="service"><ows:AllowedValues><ows:Value>WCS</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="version"><ows:AllowedValues><ows:Value>1.1.0</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="identifiers"><ows:AllowedValues><ows:Value>ro_dsm</ows:Value><ows:Value>ro_dsm_mini</ows:Value><ows:Value>ro_irra</ows:Value><ows:Value>ro_irra_ext</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name="GetCoverage"><ows:DCP><ows:HTTP><ows:Get xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/><ows:Post xlink:type="simple" xlink:href="http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;"/></ows:HTTP></ows:DCP><ows:Parameter name="service"><ows:AllowedValues><ows:Value>WCS</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="version"><ows:AllowedValues><ows:Value>1.1.0</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="Identifier"><ows:AllowedValues><ows:Value>ro_dsm</ows:Value><ows:Value>ro_dsm_mini</ows:Value><ows:Value>ro_irra</ows:Value><ows:Value>ro_irra_ext</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="InterpolationType"><ows:AllowedValues><ows:Value>NEAREST_NEIGHBOUR</ows:Value><ows:Value>BILINEAR</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="format"><ows:AllowedValues><ows:Value>image/tiff</ows:Value><ows:Value>image/png</ows:Value><ows:Value>image/jpeg</ows:Value><ows:Value>image/gif</ows:Value><ows:Value>image/png; mode=8bit</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="store"><ows:AllowedValues><ows:Value>false</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name="GridBaseCRS"><ows:AllowedValues><ows:Value>urn:ogc:def:crs:epsg::4326</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation></ows:OperationsMetadata><Contents><CoverageSummary><ows:Title>Rotterdam DSM</ows:Title><ows:Abstract>Digital Surface Model (DSM) raster data set of inner city Rotterdam</ows:Abstract><ows:WGS84BoundingBox dimensions="2"><ows:LowerCorner>4.471333734139 51.912813427383</ows:LowerCorner><ows:UpperCorner>4.4808508475645 51.9248713705576</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_dsm</Identifier></CoverageSummary><CoverageSummary><ows:Title>Rotterdam sample DSM subset</ows:Title><ows:Abstract>This a test data set of Rotterdams DSM subset</ows:Abstract><ows:WGS84BoundingBox dimensions="2"><ows:LowerCorner>4.47489346945755 51.9159453786927</ows:LowerCorner><ows:UpperCorner>4.47687824892444 51.9170706688033</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_dsm_mini</Identifier></CoverageSummary><CoverageSummary><ows:Title>Rotterdam (Ljinbaan) solar irradiation data 2010</ows:Title><ows:Abstract>This a result data set of a solar computation of Ljinbaan area. It shows the sum of kWh/a per sqmeter for 2010</ows:Abstract><ows:WGS84BoundingBox dimensions="2"><ows:LowerCorner>4.471333734139 51.912813427383</ows:LowerCorner><ows:UpperCorner>4.4808508475645 51.9248713705576</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_irra</Identifier></CoverageSummary><CoverageSummary><ows:Title>Rotterdam (extended) solar irradiation data 2010</ows:Title><ows:Abstract>This a result data set of a solar computation of extended Rotterdam area. It shows the sum of kWh/a per sqmeter for 2010</ows:Abstract><ows:WGS84BoundingBox dimensions="2"><ows:LowerCorner>4.10024171314823 51.9359764992844</ows:LowerCorner><ows:UpperCorner>4.21909054278063 52.001415228243</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_irra_ext</Identifier></CoverageSummary></Contents></Capabilities>';
+
+ res = parser.read(text);
+
+ // Most of the parsing is handled by other objects, so not much actually requires testing here
+ t.ok(!res.error, "Parsing XML generated no errors");
+ t.eq(res.contentMetadata.length, 4, "number of features correct");
+
+ var metadata = res.contentMetadata[0];
+ t.eq(metadata.identifier, "ro_dsm", "correct identifier");
+ t.eq(metadata.title, "Rotterdam DSM", "correct title");
+ t.eq(metadata.abstract, "Digital Surface Model (DSM) raster data set of inner city Rotterdam", "correct abstract");
+ t.eq(metadata.supportedFormat.length, 1, "correct number of supported formats");
+ t.eq(metadata.supportedFormat[0], "image/tiff", "correct format");
+ t.eq(metadata.supportedCRS.length, 4, "correct number of CRS records");
+ t.eq(metadata.supportedCRS[2], "urn:ogc:def:crs:EPSG::3857", "correct CRS");
+ }
+
+ </script>
+</head>
+<body> </body>
+</html>
diff --git a/misc/openlayers/tests/Format/WCSGetCoverage.html b/misc/openlayers/tests/Format/WCSGetCoverage.html
new file mode 100644
index 0000000..6379b2b
--- /dev/null
+++ b/misc/openlayers/tests/Format/WCSGetCoverage.html
@@ -0,0 +1,80 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_write_WCSGetCoverage(t) {
+ t.plan(1);
+ var expected = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<GetCoverage xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+' xsi:schemaLocation="http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsGetCoverage.xsd"' +
+' service="WCS" version="1.1.2">' +
+' <ows:Identifier>Cov123</ows:Identifier>' +
+' <DomainSubset>' +
+' <ows:BoundingBox crs="urn:ogc:def:crs:OGC:2:84">' +
+' <ows:LowerCorner>-71 47</ows:LowerCorner>' +
+' <ows:UpperCorner>-66 51</ows:UpperCorner>' +
+' </ows:BoundingBox>' +
+' <TemporalSubset>' +
+' <TimePeriod>' +
+' <BeginPosition>2006-08-01</BeginPosition>' +
+' <EndPosition>2006-09-01</EndPosition>' +
+' <TimeResolution>P1D</TimeResolution>' +
+' </TimePeriod>' +
+' <TimePeriod>' +
+' <BeginPosition>2007-08-01</BeginPosition>' +
+' <EndPosition>2007-09-01</EndPosition>' +
+' <TimeResolution>P1D</TimeResolution>' +
+' </TimePeriod>' +
+' </TemporalSubset>' +
+' </DomainSubset>' +
+' <Output format="image/netcdf">' +
+' <GridCRS>' +
+' <GridBaseCRS>urn:ogc:def:crs:EPSG:6.6:32618</GridBaseCRS>' +
+' <GridType>urn:ogc:def:method:WCS:1.1:2dGridin2dCrs</GridType>' +
+' <GridOrigin>3000 4000</GridOrigin>' +
+' <GridOffsets>6.0 8.0 -8.0 6.0</GridOffsets>' +
+' <GridCS>urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS</GridCS>' +
+' </GridCRS>' +
+' </Output>' +
+'</GetCoverage>';
+
+ var format = new OpenLayers.Format.WCSGetCoverage();
+ var result = format.write({
+ identifier: 'Cov123',
+ domainSubset: {
+ boundingBox: {projection: 'urn:ogc:def:crs:OGC:2:84', bounds: new OpenLayers.Bounds(-71, 47, -66, 51)},
+ temporalSubset: {
+ timePeriods: [
+ {
+ begin: '2006-08-01',
+ end: '2006-09-01',
+ resolution: 'P1D'
+ }, {
+ begin: '2007-08-01',
+ end: '2007-09-01',
+ resolution: 'P1D'
+ }
+ ]
+ }
+ },
+ output: {
+ format: 'image/netcdf',
+ gridCRS: {
+ baseCRS: 'urn:ogc:def:crs:EPSG:6.6:32618',
+ type: 'urn:ogc:def:method:WCS:1.1:2dGridin2dCrs',
+ origin: '3000 4000',
+ offsets: '6.0 8.0 -8.0 6.0',
+ CS: 'urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS'
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WCS GetCoverage written out correctly");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFS.html b/misc/openlayers/tests/Format/WFS.html
new file mode 100644
index 0000000..7b3b737
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFS.html
@@ -0,0 +1,81 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script>
+ function test_wfs_update_node(t) {
+ t.plan(2);
+ var expected = readXML("Update");
+ var updateFeature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(1,2),
+ {foo: "bar"});
+ updateFeature.fid = "fid.42";
+ updateFeature.state = OpenLayers.State.UPDATE;
+ var format = new OpenLayers.Format.WFS({
+ 'featureNS':'http://www.openplans.org/topp',
+ 'featureName': 'states',
+ 'geometryName': 'the_geom',
+ 'featurePrefix': 'topp'
+ }, {options:{}});
+ var updateNode = format.update(updateFeature);
+ t.xml_eq(updateNode, expected, "update node matches expected XML value.");
+ var format = new OpenLayers.Format.WFS({
+ 'featurePrefix': 'topp'
+ }, {options:{typename: 'states', 'featureNS': 'http://www.openplans.org/topp', 'geometry_column': 'the_geom' }});
+ var updateNode = format.update(updateFeature);
+ t.xml_eq(updateNode, expected, "update node matches expected XML value.");
+ }
+ function test_wfs_delete_node(t) {
+ t.plan(2);
+ var expected = readXML("Delete");
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));
+ feature.state = OpenLayers.State.DELETE;
+ feature.fid = "fid.37";
+ var format = new OpenLayers.Format.WFS({
+ 'featureNS':'http://www.openplans.org/topp',
+ 'featureName': 'states',
+ 'featurePrefix': 'topp'
+ }, {options:{}});
+ var deleteNode = format.remove(feature);
+ t.xml_eq(deleteNode, expected, "delete node matches expected XML value.");
+ var format = new OpenLayers.Format.WFS({
+ 'featurePrefix': 'topp'
+ }, {options:{typename: 'states', 'featureNS': 'http://www.openplans.org/topp'}});
+ var deleteNode = format.remove(feature);
+ t.xml_eq(deleteNode, expected, "delete node matches expected XML value.");
+ }
+ function readXML(id) {
+ var xml = document.getElementById(id).firstChild.nodeValue;
+ return new OpenLayers.Format.XML().read(xml).documentElement;
+ }
+
+ </script>
+</head>
+<body>
+<div id="Update"><!--
+<wfs:Update xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>the_geom</wfs:Name>
+ <wfs:Value>
+ <gml:Point xmlns:gml="http://www.opengis.net/gml">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>bar</wfs:Value>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.42"/>
+ </ogc:Filter>
+</wfs:Update>
+--></div>
+<div id="Delete"><!--
+<wfs:Delete xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.37"/>
+ </ogc:Filter>
+</wfs:Delete>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFSCapabilities.html b/misc/openlayers/tests/Format/WFSCapabilities.html
new file mode 100644
index 0000000..fc2ff2d
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFSCapabilities.html
@@ -0,0 +1,43 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read(t) {
+ t.plan(4);
+
+ var _v1_0_0 = OpenLayers.Format.WFSCapabilities.v1_0_0.prototype.read;
+ var _v1_1_0 = OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read;
+
+ var parser = new OpenLayers.Format.WFSCapabilities();
+
+ // version 1.0.0
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<wfs:WFS_Capabilities version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs"></wfs:WFS_Capabilities>';
+ OpenLayers.Format.WFSCapabilities.v1_0_0.prototype.read = function() {
+ t.ok(true, "Version 1.0.0 detected");
+ return {};
+ }
+ var res = parser.read(text);
+ t.eq(res.version, "1.0.0", "version 1.0.0 written to result object");
+ OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read = _v1_1_0;
+
+ // version 1.1.0
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<wfs:WFS_Capabilities version="1.1.0" xmlns:wfs="http://www.opengis.net/wfs"></wfs:WFS_Capabilities>';
+ OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read = function() {
+ t.ok(true, "Version 1.1.0 detected");
+ return {};
+ }
+ var res = parser.read(text);
+ t.eq(res.version, "1.1.0", "version 1.1.0 written to result object");
+ OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read = _v1_1_0;
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFSCapabilities/v1.html b/misc/openlayers/tests/Format/WFSCapabilities/v1.html
new file mode 100644
index 0000000..0bc1705
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFSCapabilities/v1.html
@@ -0,0 +1,179 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.WFSCapabilities();
+ var text = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<ows:ExceptionReport language="en" version="1.0.0"' +
+' xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows">' +
+' <ows:Exception locator="foo" exceptionCode="InvalidParameterValue">' +
+' <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +
+' <ows:ExceptionText>Second exception line</ows:ExceptionText>' +
+' </ows:Exception>' +
+'</ows:ExceptionReport>';
+
+ var obj = parser.read(text);
+ t.ok(!!obj.error, "Error reported correctly"); // The above should place an error in obj.error
+ }
+
+ function test_read(t) {
+ t.plan(37); // Number of tests performed: If you add a test below, be sure to increment this accordingly
+
+ var parser = new OpenLayers.Format.WFSCapabilities();
+
+ // GeoServer, v1.1.0
+ var text = '<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_Capabilities version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:80/geoserver/schemas/wfs/1.1.0/wfs.xsd" xmlns:it.geosolutions="http://www.geo-solutions.it" xmlns:cite="http://www.opengeospatial.net/cite" xmlns:tiger="http://www.census.gov" xmlns:sde="http://geoserver.sf.net" xmlns:topp="http://www.openplans.org/topp" xmlns:sf="http://www.openplans.org/spearfish" xmlns:nurc="http://www.nurc.nato.int" updateSequence="57"><ows:ServiceIdentification><ows:Title>GeoServer Web Feature Service</ows:Title><ows:Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.</ows:Abstract><ows:Keywords><ows:Keyword>WFS</ows:Keyword><ows:Keyword>WMS</ows:Keyword><ows:Keyword>GEOSERVER</ows:Keyword></ows:Keywords><ows:ServiceType>WFS</ows:ServiceType><ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion><ows:Fees>NONE</ows:Fees><ows:AccessConstraints>NONE</ows:AccessConstraints></ows:ServiceIdentification><ows:ServiceProvider><ows:ProviderName>The ancient geographes INC</ows:ProviderName><ows:ServiceContact><ows:IndividualName>Claudius Ptolomaeus</ows:IndividualName><ows:PositionName>Chief geographer</ows:PositionName><ows:ContactInfo><ows:Phone><ows:Voice/><ows:Facsimile/></ows:Phone><ows:Address><ows:City>Alexandria</ows:City><ows:AdministrativeArea/><ows:PostalCode/><ows:Country>Egypt</ows:Country></ows:Address></ows:ContactInfo></ows:ServiceContact></ows:ServiceProvider><ows:OperationsMetadata><ows:Operation name="GetCapabilities"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP><ows:Parameter name="AcceptVersions"><ows:Value>1.0.0</ows:Value><ows:Value>1.1.0</ows:Value></ows:Parameter><ows:Parameter name="AcceptFormats"><ows:Value>text/xml</ows:Value></ows:Parameter></ows:Operation><ows:Operation name="DescribeFeatureType"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP><ows:Parameter name="outputFormat"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value></ows:Parameter></ows:Operation><ows:Operation name="GetFeature"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP><ows:Parameter name="resultType"><ows:Value>results</ows:Value><ows:Value>hits</ows:Value></ows:Parameter><ows:Parameter name="outputFormat"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value><ows:Value>GML2</ows:Value><ows:Value>GML2-GZIP</ows:Value><ows:Value>SHAPE-ZIP</ows:Value><ows:Value>csv</ows:Value><ows:Value>gml3</ows:Value><ows:Value>json</ows:Value><ows:Value>text/xml; subtype=gml/2.1.2</ows:Value></ows:Parameter><ows:Constraint name="LocalTraverseXLinkScope"><ows:Value>2</ows:Value></ows:Constraint></ows:Operation><ows:Operation name="GetGmlObject"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP></ows:Operation><ows:Operation name="LockFeature"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP><ows:Parameter name="releaseAction"><ows:Value>ALL</ows:Value><ows:Value>SOME</ows:Value></ows:Parameter></ows:Operation><ows:Operation name="GetFeatureWithLock"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP><ows:Parameter name="resultType"><ows:Value>results</ows:Value><ows:Value>hits</ows:Value></ows:Parameter><ows:Parameter name="outputFormat"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value><ows:Value>GML2</ows:Value><ows:Value>GML2-GZIP</ows:Value><ows:Value>SHAPE-ZIP</ows:Value><ows:Value>csv</ows:Value><ows:Value>gml3</ows:Value><ows:Value>json</ows:Value><ows:Value>text/xml; subtype=gml/2.1.2</ows:Value></ows:Parameter></ows:Operation><ows:Operation name="Transaction"><ows:DCP><ows:HTTP><ows:Get xlink:href="http://localhost:80/geoserver/wfs?"/><ows:Post xlink:href="http://localhost:80/geoserver/wfs?"/></ows:HTTP></ows:DCP><ows:Parameter name="inputFormat"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value></ows:Parameter><ows:Parameter name="idgen"><ows:Value>GenerateNew</ows:Value><ows:Value>UseExisting</ows:Value><ows:Value>ReplaceDuplicate</ows:Value></ows:Parameter><ows:Parameter name="releaseAction"><ows:Value>ALL</ows:Value><ows:Value>SOME</ows:Value></ows:Parameter></ows:Operation></ows:OperationsMetadata><FeatureTypeList><Operations><Operation>Query</Operation><Operation>Insert</Operation><Operation>Update</Operation><Operation>Delete</Operation><Operation>Lock</Operation></Operations><FeatureType xmlns:tiger="http://www.census.gov"><Name>tiger:poly_landmarks</Name><Title>Manhattan (NY) landmarks</Title><Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract><ows:Keywords><ows:Keyword>DS_poly_landmarks</ows:Keyword><ows:Keyword>poly_landmarks</ows:Keyword><ows:Keyword>landmarks</ows:Keyword><ows:Keyword>manhattan</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.047185 40.679648</ows:LowerCorner><ows:UpperCorner>-73.90782 40.882078</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger="http://www.census.gov"><Name>tiger:poi</Name><Title>Manhattan (NY) points of interest</Title><Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract><ows:Keywords><ows:Keyword>poi</ows:Keyword><ows:Keyword>DS_poi</ows:Keyword><ows:Keyword>points_of_interest</ows:Keyword><ows:Keyword>Manhattan</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.0118315772888 40.70754683896324</ows:LowerCorner><ows:UpperCorner>-74.00857344353275 40.711945649065406</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger="http://www.census.gov"><Name>tiger:tiger_roads</Name><Title>Manhattan (NY) roads</Title><Abstract>Highly simplified road layout of Manhattan in New York..</Abstract><ows:Keywords><ows:Keyword>DS_tiger_roads</ows:Keyword><ows:Keyword>tiger_roads</ows:Keyword><ows:Keyword>roads</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.02722 40.684221</ows:LowerCorner><ows:UpperCorner>-73.907005 40.878178</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf="http://www.openplans.org/spearfish"><Name>sf:archsites</Name><Title>Spearfish archeological sites</Title><Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>archsites</ows:Keyword><ows:Keyword>sfArchsites</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>archeology</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.8725637911543 44.37740330855979</ows:LowerCorner><ows:UpperCorner>-103.63794182141925 44.48804280772808</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf="http://www.openplans.org/spearfish"><Name>sf:bugsites</Name><Title>Spearfish bug locations</Title><Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfBugsites</ows:Keyword><ows:Keyword>bugsites</ows:Keyword><ows:Keyword>insects</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>tiger_beetles</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.86796131703647 44.373938816704396</ows:LowerCorner><ows:UpperCorner>-103.63773523234195 44.43418821380063</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf="http://www.openplans.org/spearfish"><Name>sf:restricted</Name><Title>Spearfish restricted areas</Title><Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>restricted</ows:Keyword><ows:Keyword>sfRestricted</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>areas</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.85057172920756 44.39436387625042</ows:LowerCorner><ows:UpperCorner>-103.74741494853805 44.48215752041131</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf="http://www.openplans.org/spearfish"><Name>sf:roads</Name><Title>Spearfish roads</Title><Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfRoads</ows:Keyword><ows:Keyword>roads</ows:Keyword><ows:Keyword>spearfish</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.87741691493184 44.37087275281798</ows:LowerCorner><ows:UpperCorner>-103.62231404880659 44.50015918338962</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf="http://www.openplans.org/spearfish"><Name>sf:streams</Name><Title>Spearfish streams</Title><Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfStreams</ows:Keyword><ows:Keyword>streams</ows:Keyword><ows:Keyword>spearfish</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.87789019829768 44.372335260095554</ows:LowerCorner><ows:UpperCorner>-103.62287788915457 44.502218486214815</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp="http://www.openplans.org/topp"><Name>topp:tasmania_cities</Name><Title>Tasmania cities</Title><Abstract>Cities in Tasmania (actually, just the capital)</Abstract><ows:Keywords><ows:Keyword>cities</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner><ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp="http://www.openplans.org/topp"><Name>topp:tasmania_roads</Name><Title>Tasmania roads</Title><Abstract>Main Tasmania roads</Abstract><ows:Keywords><ows:Keyword>Roads</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner><ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp="http://www.openplans.org/topp"><Name>topp:tasmania_state_boundaries</Name><Title>Tasmania state boundaries</Title><Abstract>Tasmania state boundaries</Abstract><ows:Keywords><ows:Keyword>tasmania_state_boundaries</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword><ows:Keyword>boundaries</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>143.83482400000003 -43.648056</ows:LowerCorner><ows:UpperCorner>148.47914100000003 -39.573891</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp="http://www.openplans.org/topp"><Name>topp:tasmania_water_bodies</Name><Title>Tasmania water bodies</Title><Abstract>Tasmania water bodies</Abstract><ows:Keywords><ows:Keyword>Lakes</ows:Keyword><ows:Keyword>Bodies</ows:Keyword><ows:Keyword>Australia</ows:Keyword><ows:Keyword>Water</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>145.97161899999998 -43.031944</ows:LowerCorner><ows:UpperCorner>147.219696 -41.775558</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp="http://www.openplans.org/topp"><Name>topp:states</Name><Title>USA Population</Title><Abstract>This is some census data on the states.</Abstract><ows:Keywords><ows:Keyword>census</ows:Keyword><ows:Keyword>united</ows:Keyword><ows:Keyword>boundaries</ows:Keyword><ows:Keyword>state</ows:Keyword><ows:Keyword>states</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-124.731422 24.955967</ows:LowerCorner><ows:UpperCorner>-66.969849 49.371735</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger="http://www.census.gov"><Name>tiger:giant_polygon</Name><Title>World rectangle</Title><Abstract>A simple rectangular polygon covering most of the world, it\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract><ows:Keywords><ows:Keyword>DS_giant_polygon</ows:Keyword><ows:Keyword>giant_polygon</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-180.0 -90.0</ows:LowerCorner><ows:UpperCorner>180.0 90.0</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType></FeatureTypeList><ogc:Filter_Capabilities><ogc:Spatial_Capabilities><ogc:GeometryOperands><ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand><ogc:GeometryOperand>gml:Point</ogc:GeometryOperand><ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand><ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand></ogc:GeometryOperands><ogc:SpatialOperators><ogc:SpatialOperator name="Disjoint"/><ogc:SpatialOperator name="Equals"/><ogc:SpatialOperator name="DWithin"/><ogc:SpatialOperator name="Beyond"/><ogc:SpatialOperator name="Intersects"/><ogc:SpatialOperator name="Touches"/><ogc:SpatialOperator name="Crosses"/><ogc:SpatialOperator name="Contains"/><ogc:SpatialOperator name="Overlaps"/><ogc:SpatialOperator name="BBOX"/></ogc:SpatialOperators></ogc:Spatial_Capabilities><ogc:Scalar_Capabilities><ogc:LogicalOperators/><ogc:ComparisonOperators><ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator><ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator><ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>Like</ogc:ComparisonOperator><ogc:ComparisonOperator>Between</ogc:ComparisonOperator><ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator></ogc:ComparisonOperators><ogc:ArithmeticOperators><ogc:SimpleArithmetic/><ogc:Functions><ogc:FunctionNames><ogc:FunctionName nArgs="1">abs</ogc:FunctionName><ogc:FunctionName nArgs="1">abs_2</ogc:FunctionName><ogc:FunctionName nArgs="1">abs_3</ogc:FunctionName><ogc:FunctionName nArgs="1">abs_4</ogc:FunctionName><ogc:FunctionName nArgs="1">acos</ogc:FunctionName><ogc:FunctionName nArgs="1">Area</ogc:FunctionName><ogc:FunctionName nArgs="1">asin</ogc:FunctionName><ogc:FunctionName nArgs="1">atan</ogc:FunctionName><ogc:FunctionName nArgs="2">atan2</ogc:FunctionName><ogc:FunctionName nArgs="3">between</ogc:FunctionName><ogc:FunctionName nArgs="1">boundary</ogc:FunctionName><ogc:FunctionName nArgs="1">boundaryDimension</ogc:FunctionName><ogc:FunctionName nArgs="2">buffer</ogc:FunctionName><ogc:FunctionName nArgs="3">bufferWithSegments</ogc:FunctionName><ogc:FunctionName nArgs="0">Categorize</ogc:FunctionName><ogc:FunctionName nArgs="1">ceil</ogc:FunctionName><ogc:FunctionName nArgs="1">centroid</ogc:FunctionName><ogc:FunctionName nArgs="2">classify</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Average</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Bounds</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Count</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Max</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Median</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Min</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Sum</ogc:FunctionName><ogc:FunctionName nArgs="1">Collection_Unique</ogc:FunctionName><ogc:FunctionName nArgs="2">Concatenate</ogc:FunctionName><ogc:FunctionName nArgs="2">contains</ogc:FunctionName><ogc:FunctionName nArgs="1">convexHull</ogc:FunctionName><ogc:FunctionName nArgs="1">cos</ogc:FunctionName><ogc:FunctionName nArgs="2">crosses</ogc:FunctionName><ogc:FunctionName nArgs="2">dateFormat</ogc:FunctionName><ogc:FunctionName nArgs="2">dateParse</ogc:FunctionName><ogc:FunctionName nArgs="2">difference</ogc:FunctionName><ogc:FunctionName nArgs="1">dimension</ogc:FunctionName><ogc:FunctionName nArgs="2">disjoint</ogc:FunctionName><ogc:FunctionName nArgs="2">distance</ogc:FunctionName><ogc:FunctionName nArgs="1">double2bool</ogc:FunctionName><ogc:FunctionName nArgs="1">endPoint</ogc:FunctionName><ogc:FunctionName nArgs="1">envelope</ogc:FunctionName><ogc:FunctionName nArgs="2">EqualInterval</ogc:FunctionName><ogc:FunctionName nArgs="2">equalsExact</ogc:FunctionName><ogc:FunctionName nArgs="3">equalsExactTolerance</ogc:FunctionName><ogc:FunctionName nArgs="2">equalTo</ogc:FunctionName><ogc:FunctionName nArgs="1">exp</ogc:FunctionName><ogc:FunctionName nArgs="1">exteriorRing</ogc:FunctionName><ogc:FunctionName nArgs="1">floor</ogc:FunctionName><ogc:FunctionName nArgs="1">geometryType</ogc:FunctionName><ogc:FunctionName nArgs="1">geomFromWKT</ogc:FunctionName><ogc:FunctionName nArgs="1">geomLength</ogc:FunctionName><ogc:FunctionName nArgs="2">getGeometryN</ogc:FunctionName><ogc:FunctionName nArgs="1">getX</ogc:FunctionName><ogc:FunctionName nArgs="1">getY</ogc:FunctionName><ogc:FunctionName nArgs="1">getZ</ogc:FunctionName><ogc:FunctionName nArgs="2">greaterEqualThan</ogc:FunctionName><ogc:FunctionName nArgs="2">greaterThan</ogc:FunctionName><ogc:FunctionName nArgs="0">id</ogc:FunctionName><ogc:FunctionName nArgs="2">IEEEremainder</ogc:FunctionName><ogc:FunctionName nArgs="3">if_then_else</ogc:FunctionName><ogc:FunctionName nArgs="11">in10</ogc:FunctionName><ogc:FunctionName nArgs="3">in2</ogc:FunctionName><ogc:FunctionName nArgs="4">in3</ogc:FunctionName><ogc:FunctionName nArgs="5">in4</ogc:FunctionName><ogc:FunctionName nArgs="6">in5</ogc:FunctionName><ogc:FunctionName nArgs="7">in6</ogc:FunctionName><ogc:FunctionName nArgs="8">in7</ogc:FunctionName><ogc:FunctionName nArgs="9">in8</ogc:FunctionName><ogc:FunctionName nArgs="10">in9</ogc:FunctionName><ogc:FunctionName nArgs="1">int2bbool</ogc:FunctionName><ogc:FunctionName nArgs="1">int2ddouble</ogc:FunctionName><ogc:FunctionName nArgs="1">interiorPoint</ogc:FunctionName><ogc:FunctionName nArgs="2">interiorRingN</ogc:FunctionName><ogc:FunctionName nArgs="2">intersection</ogc:FunctionName><ogc:FunctionName nArgs="2">intersects</ogc:FunctionName><ogc:FunctionName nArgs="1">isClosed</ogc:FunctionName><ogc:FunctionName nArgs="1">isEmpty</ogc:FunctionName><ogc:FunctionName nArgs="2">isLike</ogc:FunctionName><ogc:FunctionName nArgs="1">isNull</ogc:FunctionName><ogc:FunctionName nArgs="1">isRing</ogc:FunctionName><ogc:FunctionName nArgs="1">isSimple</ogc:FunctionName><ogc:FunctionName nArgs="1">isValid</ogc:FunctionName><ogc:FunctionName nArgs="3">isWithinDistance</ogc:FunctionName><ogc:FunctionName nArgs="1">length</ogc:FunctionName><ogc:FunctionName nArgs="2">lessEqualThan</ogc:FunctionName><ogc:FunctionName nArgs="2">lessThan</ogc:FunctionName><ogc:FunctionName nArgs="1">log</ogc:FunctionName><ogc:FunctionName nArgs="2">max</ogc:FunctionName><ogc:FunctionName nArgs="2">max_2</ogc:FunctionName><ogc:FunctionName nArgs="2">max_3</ogc:FunctionName><ogc:FunctionName nArgs="2">max_4</ogc:FunctionName><ogc:FunctionName nArgs="2">min</ogc:FunctionName><ogc:FunctionName nArgs="2">min_2</ogc:FunctionName><ogc:FunctionName nArgs="2">min_3</ogc:FunctionName><ogc:FunctionName nArgs="2">min_4</ogc:FunctionName><ogc:FunctionName nArgs="1">not</ogc:FunctionName><ogc:FunctionName nArgs="2">notEqualTo</ogc:FunctionName><ogc:FunctionName nArgs="1">numGeometries</ogc:FunctionName><ogc:FunctionName nArgs="1">numInteriorRing</ogc:FunctionName><ogc:FunctionName nArgs="1">numPoints</ogc:FunctionName><ogc:FunctionName nArgs="2">overlaps</ogc:FunctionName><ogc:FunctionName nArgs="1">parseBoolean</ogc:FunctionName><ogc:FunctionName nArgs="1">parseDouble</ogc:FunctionName><ogc:FunctionName nArgs="1">parseInt</ogc:FunctionName><ogc:FunctionName nArgs="0">pi</ogc:FunctionName><ogc:FunctionName nArgs="2">pointN</ogc:FunctionName><ogc:FunctionName nArgs="2">pow</ogc:FunctionName><ogc:FunctionName nArgs="1">PropertyExists</ogc:FunctionName><ogc:FunctionName nArgs="2">Quantile</ogc:FunctionName><ogc:FunctionName nArgs="0">random</ogc:FunctionName><ogc:FunctionName nArgs="2">relate</ogc:FunctionName><ogc:FunctionName nArgs="3">relatePattern</ogc:FunctionName><ogc:FunctionName nArgs="1">rint</ogc:FunctionName><ogc:FunctionName nArgs="1">round</ogc:FunctionName><ogc:FunctionName nArgs="1">round_2</ogc:FunctionName><ogc:FunctionName nArgs="1">roundDouble</ogc:FunctionName><ogc:FunctionName nArgs="1">sin</ogc:FunctionName><ogc:FunctionName nArgs="1">sqrt</ogc:FunctionName><ogc:FunctionName nArgs="2">StandardDeviation</ogc:FunctionName><ogc:FunctionName nArgs="1">startPoint</ogc:FunctionName><ogc:FunctionName nArgs="2">strConcat</ogc:FunctionName><ogc:FunctionName nArgs="2">strEndsWith</ogc:FunctionName><ogc:FunctionName nArgs="2">strEqualsIgnoreCase</ogc:FunctionName><ogc:FunctionName nArgs="2">strIndexOf</ogc:FunctionName><ogc:FunctionName nArgs="2">strLastIndexOf</ogc:FunctionName><ogc:FunctionName nArgs="1">strLength</ogc:FunctionName><ogc:FunctionName nArgs="2">strMatches</ogc:FunctionName><ogc:FunctionName nArgs="4">strReplace</ogc:FunctionName><ogc:FunctionName nArgs="2">strStartsWith</ogc:FunctionName><ogc:FunctionName nArgs="3">strSubstring</ogc:FunctionName><ogc:FunctionName nArgs="2">strSubstringStart</ogc:FunctionName><ogc:FunctionName nArgs="1">strToLowerCase</ogc:FunctionName><ogc:FunctionName nArgs="1">strToUpperCase</ogc:FunctionName><ogc:FunctionName nArgs="1">strTrim</ogc:FunctionName><ogc:FunctionName nArgs="2">symDifference</ogc:FunctionName><ogc:FunctionName nArgs="1">tan</ogc:FunctionName><ogc:FunctionName nArgs="1">toDegrees</ogc:FunctionName><ogc:FunctionName nArgs="1">toRadians</ogc:FunctionName><ogc:FunctionName nArgs="2">touches</ogc:FunctionName><ogc:FunctionName nArgs="1">toWKT</ogc:FunctionName><ogc:FunctionName nArgs="2">union</ogc:FunctionName><ogc:FunctionName nArgs="2">UniqueInterval</ogc:FunctionName><ogc:FunctionName nArgs="2">within</ogc:FunctionName></ogc:FunctionNames></ogc:Functions></ogc:ArithmeticOperators></ogc:Scalar_Capabilities><ogc:Id_Capabilities><ogc:FID/><ogc:EID/></ogc:Id_Capabilities></ogc:Filter_Capabilities></wfs:WFS_Capabilities>';
+ var res = parser.read(text);
+
+ t.ok(!res.error, "Parsing XML generated no errors");
+ t.eq(res.operationsMetadata["GetFeature"].dcp.http.get[0].url, "http://localhost:80/geoserver/wfs?", "GetFeature GET endpoint correctly parsed");
+ t.eq(res.operationsMetadata["GetFeature"].dcp.http.post[0].url, "http://localhost:80/geoserver/wfs?", "GetFeature POST endpoint correctly parsed");
+ var ft = res.featureTypeList.featureTypes;
+ t.eq(ft.length, 14, "number of feature types correct");
+ t.eq(ft[0]["abstract"], "Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs", "abstract of first feature type correct");
+ t.eq(ft[0]["title"], "Manhattan (NY) landmarks", "title of first feature type correct");
+ t.eq(ft[0]["name"], "poly_landmarks", "name of first feature type correct");
+ t.eq(ft[0]["featureNS"], "http://www.census.gov", "ns of first feature type correct");
+ t.eq(ft[0]["srs"], "urn:x-ogc:def:crs:EPSG:4326", "srs of first feature type correct");
+
+ // GeoServer, v1.0.0
+ text = '<?xml version="1.0" encoding="UTF-8"?><WFS_Capabilities version="1.0.0" xmlns="http://www.opengis.net/wfs" xmlns:it.geosolutions="http://www.geo-solutions.it" xmlns:cite="http://www.opengeospatial.net/cite" xmlns:tiger="http://www.census.gov" xmlns:sde="http://geoserver.sf.net" xmlns:topp="http://www.openplans.org/topp" xmlns:sf="http://www.openplans.org/spearfish" xmlns:nurc="http://www.nurc.nato.int" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd"><Service><Name>WFS</Name><Title>GeoServer Web Feature Service</Title><Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.</Abstract><Keywords>WFS, WMS, GEOSERVER</Keywords><OnlineResource>http://localhost:80/geoserver/wfs</OnlineResource><Fees>NONE</Fees><AccessConstraints>NONE</AccessConstraints></Service><Capability><Request><GetCapabilities><DCPType><HTTP><Get onlineResource="http://localhost:80/geoserver/wfs?request=GetCapabilities"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource="http://localhost:80/geoserver/wfs?"/></HTTP></DCPType></GetCapabilities><DescribeFeatureType><SchemaDescriptionLanguage><XMLSCHEMA/></SchemaDescriptionLanguage><DCPType><HTTP><Get onlineResource="http://localhost:80/geoserver/wfs?request=DescribeFeatureType"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource="http://localhost:80/geoserver/wfs?"/></HTTP></DCPType></DescribeFeatureType><GetFeature><ResultFormat><GML2/><SHAPE-ZIP/><GEOJSON/><csv/><GML3/></ResultFormat><DCPType><HTTP><Get onlineResource="http://localhost:80/geoserver/wfs?request=GetFeature"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource="http://localhost:80/geoserver/wfs?"/></HTTP></DCPType></GetFeature><Transaction><DCPType><HTTP><Get onlineResource="http://localhost:80/geoserver/wfs?request=Transaction"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource="http://localhost:80/geoserver/wfs?"/></HTTP></DCPType></Transaction><LockFeature><DCPType><HTTP><Get onlineResource="http://localhost:80/geoserver/wfs?request=LockFeature"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource="http://localhost:80/geoserver/wfs?"/></HTTP></DCPType></LockFeature><GetFeatureWithLock><ResultFormat><GML2/></ResultFormat><DCPType><HTTP><Get onlineResource="http://localhost:80/geoserver/wfs?request=GetFeatureWithLock"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource="http://localhost:80/geoserver/wfs?"/></HTTP></DCPType></GetFeatureWithLock></Request></Capability><FeatureTypeList><Operations><Query/><Insert/><Update/><Delete/><Lock/></Operations><FeatureType><Name>tiger:poly_landmarks</Name><Title>Manhattan (NY) landmarks</Title><Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract><Keywords>DS_poly_landmarks, poly_landmarks, landmarks, manhattan</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="-74.047185" miny="40.679648" maxx="-73.90782" maxy="40.882078"/></FeatureType><FeatureType><Name>tiger:poi</Name><Title>Manhattan (NY) points of interest</Title><Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract><Keywords>poi, DS_poi, points_of_interest, Manhattan</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="-74.0118315772888" miny="40.70754683896324" maxx="-74.00857344353275" maxy="40.711945649065406"/></FeatureType><FeatureType><Name>tiger:tiger_roads</Name><Title>Manhattan (NY) roads</Title><Abstract>Highly simplified road layout of Manhattan in New York..</Abstract><Keywords>DS_tiger_roads, tiger_roads, roads</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="-74.02722" miny="40.684221" maxx="-73.907005" maxy="40.878178"/></FeatureType><FeatureType><Name>sf:archsites</Name><Title>Spearfish archeological sites</Title><Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract><Keywords>archsites, sfArchsites, spearfish, archeology</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx="-103.8725637911543" miny="44.37740330855979" maxx="-103.63794182141925" maxy="44.48804280772808"/></FeatureType><FeatureType><Name>sf:bugsites</Name><Title>Spearfish bug locations</Title><Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract><Keywords>sfBugsites, bugsites, insects, spearfish, tiger_beetles</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx="-103.86796131703647" miny="44.373938816704396" maxx="-103.63773523234195" maxy="44.43418821380063"/></FeatureType><FeatureType><Name>sf:restricted</Name><Title>Spearfish restricted areas</Title><Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract><Keywords>restricted, sfRestricted, spearfish, areas</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx="-103.85057172920756" miny="44.39436387625042" maxx="-103.74741494853805" maxy="44.48215752041131"/></FeatureType><FeatureType><Name>sf:roads</Name><Title>Spearfish roads</Title><Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract><Keywords>sfRoads, roads, spearfish</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx="-103.87741691493184" miny="44.37087275281798" maxx="-103.62231404880659" maxy="44.50015918338962"/></FeatureType><FeatureType><Name>sf:streams</Name><Title>Spearfish streams</Title><Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract><Keywords>sfStreams, streams, spearfish</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx="-103.87789019829768" miny="44.372335260095554" maxx="-103.62287788915457" maxy="44.502218486214815"/></FeatureType><FeatureType><Name>topp:tasmania_cities</Name><Title>Tasmania cities</Title><Abstract>Cities in Tasmania (actually, just the capital)</Abstract><Keywords>cities, Tasmania</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="145.19754" miny="-43.423512" maxx="148.27298000000002" maxy="-40.852802"/></FeatureType><FeatureType><Name>topp:tasmania_roads</Name><Title>Tasmania roads</Title><Abstract>Main Tasmania roads</Abstract><Keywords>Roads, Tasmania</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="145.19754" miny="-43.423512" maxx="148.27298000000002" maxy="-40.852802"/></FeatureType><FeatureType><Name>topp:tasmania_state_boundaries</Name><Title>Tasmania state boundaries</Title><Abstract>Tasmania state boundaries</Abstract><Keywords>tasmania_state_boundaries, Tasmania, boundaries</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="143.83482400000003" miny="-43.648056" maxx="148.47914100000003" maxy="-39.573891"/></FeatureType><FeatureType><Name>topp:tasmania_water_bodies</Name><Title>Tasmania water bodies</Title><Abstract>Tasmania water bodies</Abstract><Keywords>Lakes, Bodies, Australia, Water, Tasmania</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="145.97161899999998" miny="-43.031944" maxx="147.219696" maxy="-41.775558"/></FeatureType><FeatureType><Name>topp:states</Name><Title>USA Population</Title><Abstract>This is some census data on the states.</Abstract><Keywords>census, united, boundaries, state, states</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="-124.731422" miny="24.955967" maxx="-66.969849" maxy="49.371735"/></FeatureType><FeatureType><Name>tiger:giant_polygon</Name><Title>World rectangle</Title><Abstract>A simple rectangular polygon covering most of the world, it\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract><Keywords>DS_giant_polygon, giant_polygon</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx="-180.0" miny="-90.0" maxx="180.0" maxy="90.0"/></FeatureType></FeatureTypeList><ogc:Filter_Capabilities><ogc:Spatial_Capabilities><ogc:Spatial_Operators><ogc:Disjoint/><ogc:Equals/><ogc:DWithin/><ogc:Beyond/><ogc:Intersect/><ogc:Touches/><ogc:Crosses/><ogc:Within/><ogc:Contains/><ogc:Overlaps/><ogc:BBOX/></ogc:Spatial_Operators></ogc:Spatial_Capabilities><ogc:Scalar_Capabilities><ogc:Logical_Operators/><ogc:Comparison_Operators><ogc:Simple_Comparisons/><ogc:Between/><ogc:Like/><ogc:NullCheck/></ogc:Comparison_Operators><ogc:Arithmetic_Operators><ogc:Simple_Arithmetic/><ogc:Functions><ogc:Function_Names><ogc:Function_Name nArgs="1">abs</ogc:Function_Name><ogc:Function_Name nArgs="1">abs_2</ogc:Function_Name><ogc:Function_Name nArgs="1">abs_3</ogc:Function_Name><ogc:Function_Name nArgs="1">abs_4</ogc:Function_Name><ogc:Function_Name nArgs="1">acos</ogc:Function_Name><ogc:Function_Name nArgs="1">Area</ogc:Function_Name><ogc:Function_Name nArgs="1">asin</ogc:Function_Name><ogc:Function_Name nArgs="1">atan</ogc:Function_Name><ogc:Function_Name nArgs="2">atan2</ogc:Function_Name><ogc:Function_Name nArgs="3">between</ogc:Function_Name><ogc:Function_Name nArgs="1">boundary</ogc:Function_Name><ogc:Function_Name nArgs="1">boundaryDimension</ogc:Function_Name><ogc:Function_Name nArgs="2">buffer</ogc:Function_Name><ogc:Function_Name nArgs="3">bufferWithSegments</ogc:Function_Name><ogc:Function_Name nArgs="1">ceil</ogc:Function_Name><ogc:Function_Name nArgs="1">centroid</ogc:Function_Name><ogc:Function_Name nArgs="2">classify</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Average</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Bounds</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Count</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Max</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Median</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Min</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Sum</ogc:Function_Name><ogc:Function_Name nArgs="1">Collection_Unique</ogc:Function_Name><ogc:Function_Name nArgs="2">Concatenate</ogc:Function_Name><ogc:Function_Name nArgs="2">contains</ogc:Function_Name><ogc:Function_Name nArgs="1">convexHull</ogc:Function_Name><ogc:Function_Name nArgs="1">cos</ogc:Function_Name><ogc:Function_Name nArgs="2">crosses</ogc:Function_Name><ogc:Function_Name nArgs="2">dateFormat</ogc:Function_Name><ogc:Function_Name nArgs="2">dateParse</ogc:Function_Name><ogc:Function_Name nArgs="2">difference</ogc:Function_Name><ogc:Function_Name nArgs="1">dimension</ogc:Function_Name><ogc:Function_Name nArgs="2">disjoint</ogc:Function_Name><ogc:Function_Name nArgs="2">distance</ogc:Function_Name><ogc:Function_Name nArgs="1">double2bool</ogc:Function_Name><ogc:Function_Name nArgs="1">endPoint</ogc:Function_Name><ogc:Function_Name nArgs="1">envelope</ogc:Function_Name><ogc:Function_Name nArgs="2">EqualInterval</ogc:Function_Name><ogc:Function_Name nArgs="2">equalsExact</ogc:Function_Name><ogc:Function_Name nArgs="3">equalsExactTolerance</ogc:Function_Name><ogc:Function_Name nArgs="2">equalTo</ogc:Function_Name><ogc:Function_Name nArgs="1">exp</ogc:Function_Name><ogc:Function_Name nArgs="1">exteriorRing</ogc:Function_Name><ogc:Function_Name nArgs="1">floor</ogc:Function_Name><ogc:Function_Name nArgs="1">geometryType</ogc:Function_Name><ogc:Function_Name nArgs="1">geomFromWKT</ogc:Function_Name><ogc:Function_Name nArgs="1">geomLength</ogc:Function_Name><ogc:Function_Name nArgs="2">getGeometryN</ogc:Function_Name><ogc:Function_Name nArgs="1">getX</ogc:Function_Name><ogc:Function_Name nArgs="1">getY</ogc:Function_Name><ogc:Function_Name nArgs="1">getZ</ogc:Function_Name><ogc:Function_Name nArgs="2">greaterEqualThan</ogc:Function_Name><ogc:Function_Name nArgs="2">greaterThan</ogc:Function_Name><ogc:Function_Name nArgs="0">id</ogc:Function_Name><ogc:Function_Name nArgs="2">IEEEremainder</ogc:Function_Name><ogc:Function_Name nArgs="3">if_then_else</ogc:Function_Name><ogc:Function_Name nArgs="11">in10</ogc:Function_Name><ogc:Function_Name nArgs="3">in2</ogc:Function_Name><ogc:Function_Name nArgs="4">in3</ogc:Function_Name><ogc:Function_Name nArgs="5">in4</ogc:Function_Name><ogc:Function_Name nArgs="6">in5</ogc:Function_Name><ogc:Function_Name nArgs="7">in6</ogc:Function_Name><ogc:Function_Name nArgs="8">in7</ogc:Function_Name><ogc:Function_Name nArgs="9">in8</ogc:Function_Name><ogc:Function_Name nArgs="10">in9</ogc:Function_Name><ogc:Function_Name nArgs="1">int2bbool</ogc:Function_Name><ogc:Function_Name nArgs="1">int2ddouble</ogc:Function_Name><ogc:Function_Name nArgs="1">interiorPoint</ogc:Function_Name><ogc:Function_Name nArgs="2">interiorRingN</ogc:Function_Name><ogc:Function_Name nArgs="2">intersection</ogc:Function_Name><ogc:Function_Name nArgs="2">intersects</ogc:Function_Name><ogc:Function_Name nArgs="1">isClosed</ogc:Function_Name><ogc:Function_Name nArgs="1">isEmpty</ogc:Function_Name><ogc:Function_Name nArgs="2">isLike</ogc:Function_Name><ogc:Function_Name nArgs="1">isNull</ogc:Function_Name><ogc:Function_Name nArgs="1">isRing</ogc:Function_Name><ogc:Function_Name nArgs="1">isSimple</ogc:Function_Name><ogc:Function_Name nArgs="1">isValid</ogc:Function_Name><ogc:Function_Name nArgs="3">isWithinDistance</ogc:Function_Name><ogc:Function_Name nArgs="1">length</ogc:Function_Name><ogc:Function_Name nArgs="2">lessEqualThan</ogc:Function_Name><ogc:Function_Name nArgs="2">lessThan</ogc:Function_Name><ogc:Function_Name nArgs="1">log</ogc:Function_Name><ogc:Function_Name nArgs="2">max</ogc:Function_Name><ogc:Function_Name nArgs="2">max_2</ogc:Function_Name><ogc:Function_Name nArgs="2">max_3</ogc:Function_Name><ogc:Function_Name nArgs="2">max_4</ogc:Function_Name><ogc:Function_Name nArgs="2">min</ogc:Function_Name><ogc:Function_Name nArgs="2">min_2</ogc:Function_Name><ogc:Function_Name nArgs="2">min_3</ogc:Function_Name><ogc:Function_Name nArgs="2">min_4</ogc:Function_Name><ogc:Function_Name nArgs="1">not</ogc:Function_Name><ogc:Function_Name nArgs="2">notEqualTo</ogc:Function_Name><ogc:Function_Name nArgs="1">numGeometries</ogc:Function_Name><ogc:Function_Name nArgs="1">numInteriorRing</ogc:Function_Name><ogc:Function_Name nArgs="1">numPoints</ogc:Function_Name><ogc:Function_Name nArgs="2">overlaps</ogc:Function_Name><ogc:Function_Name nArgs="1">parseBoolean</ogc:Function_Name><ogc:Function_Name nArgs="1">parseDouble</ogc:Function_Name><ogc:Function_Name nArgs="1">parseInt</ogc:Function_Name><ogc:Function_Name nArgs="0">pi</ogc:Function_Name><ogc:Function_Name nArgs="2">pointN</ogc:Function_Name><ogc:Function_Name nArgs="2">pow</ogc:Function_Name><ogc:Function_Name nArgs="1">PropertyExists</ogc:Function_Name><ogc:Function_Name nArgs="2">Quantile</ogc:Function_Name><ogc:Function_Name nArgs="0">random</ogc:Function_Name><ogc:Function_Name nArgs="2">relate</ogc:Function_Name><ogc:Function_Name nArgs="3">relatePattern</ogc:Function_Name><ogc:Function_Name nArgs="1">rint</ogc:Function_Name><ogc:Function_Name nArgs="1">round</ogc:Function_Name><ogc:Function_Name nArgs="1">round_2</ogc:Function_Name><ogc:Function_Name nArgs="1">roundDouble</ogc:Function_Name><ogc:Function_Name nArgs="1">sin</ogc:Function_Name><ogc:Function_Name nArgs="1">sqrt</ogc:Function_Name><ogc:Function_Name nArgs="2">StandardDeviation</ogc:Function_Name><ogc:Function_Name nArgs="1">startPoint</ogc:Function_Name><ogc:Function_Name nArgs="2">strConcat</ogc:Function_Name><ogc:Function_Name nArgs="2">strEndsWith</ogc:Function_Name><ogc:Function_Name nArgs="2">strEqualsIgnoreCase</ogc:Function_Name><ogc:Function_Name nArgs="2">strIndexOf</ogc:Function_Name><ogc:Function_Name nArgs="2">strLastIndexOf</ogc:Function_Name><ogc:Function_Name nArgs="1">strLength</ogc:Function_Name><ogc:Function_Name nArgs="2">strMatches</ogc:Function_Name><ogc:Function_Name nArgs="4">strReplace</ogc:Function_Name><ogc:Function_Name nArgs="2">strStartsWith</ogc:Function_Name><ogc:Function_Name nArgs="3">strSubstring</ogc:Function_Name><ogc:Function_Name nArgs="2">strSubstringStart</ogc:Function_Name><ogc:Function_Name nArgs="1">strToLowerCase</ogc:Function_Name><ogc:Function_Name nArgs="1">strToUpperCase</ogc:Function_Name><ogc:Function_Name nArgs="1">strTrim</ogc:Function_Name><ogc:Function_Name nArgs="2">symDifference</ogc:Function_Name><ogc:Function_Name nArgs="1">tan</ogc:Function_Name><ogc:Function_Name nArgs="1">toDegrees</ogc:Function_Name><ogc:Function_Name nArgs="1">toRadians</ogc:Function_Name><ogc:Function_Name nArgs="2">touches</ogc:Function_Name><ogc:Function_Name nArgs="1">toWKT</ogc:Function_Name><ogc:Function_Name nArgs="2">union</ogc:Function_Name><ogc:Function_Name nArgs="2">UniqueInterval</ogc:Function_Name><ogc:Function_Name nArgs="2">within</ogc:Function_Name></ogc:Function_Names></ogc:Functions></ogc:Arithmetic_Operators></ogc:Scalar_Capabilities></ogc:Filter_Capabilities></WFS_Capabilities>';
+ res = parser.read(text);
+
+ t.ok(!res.error, "Parsing XML generated no errors");
+ ft = res.featureTypeList.featureTypes;
+ t.eq(ft.length, 14, "number of feature types correct");
+ t.eq(ft[0]["abstract"], "Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs", "abstract of first feature type correct");
+ t.eq(ft[0]["title"], "Manhattan (NY) landmarks", "title of first feature type correct");
+ t.eq(ft[0]["name"], "poly_landmarks", "name of first feature type correct");
+ t.eq(ft[0]["featureNS"], "http://www.census.gov", "ns of first feature type correct");
+ t.eq(ft[0]["srs"], "EPSG:4326", "srs of first feature type correct");
+
+ var service = res.service;
+ t.eq(service.name, 'WFS', "service name correct");
+ t.eq(service.title, 'GeoServer Web Feature Service', "service title correct");
+ t.eq(service.abstract, 'This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.', "service title correct");
+ t.eq(service.keywords[0], 'WFS', "service keyword [0] correct");
+ t.eq(service.keywords[2], 'GEOSERVER', "service keyword [2] correct");
+ t.eq(service.onlineResource, 'http://localhost:80/geoserver/wfs', "service onlineresource correct");
+ t.ok(typeof service.fees == 'undefined', "service fees correct");
+ t.ok(typeof service.accessConstraints == 'undefined', "service accessconstraints correct");
+
+ t.eq(res.capability.request.getfeature.href.post, "http://localhost:80/geoserver/wfs?", "getfeature request post href correct");
+ t.eq(res.capability.request.getfeature.href.get, "http://localhost:80/geoserver/wfs?request=GetFeature", "getfeature request get href correct");
+
+ t.eq(res.capability.request.getfeature.formats[0], "GML2", "getfeature response format [0] correct");
+ t.eq(res.capability.request.getfeature.formats[4], "GML3", "getfeature response format [4] correct");
+
+ // UMN Mapserer, v1.0.0
+ text =
+ '<?xml version="1.0" encoding="ISO-8859-1" ?>' +
+ '<WFS_Capabilities' +
+ ' version="1.0.0"' +
+ ' updateSequence="0"' +
+ ' xmlns="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://ogc.dmsolutions.ca/wfs/1.0.0/WFS-capabilities.xsd">' +
+ '' +
+ '<!-- MapServer version 4.0 (development) OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE -->' +
+ '' +
+ '<Service>' +
+ ' <Name>MapServer WFS</Name>' +
+ ' <Title>GMap WMS Demo Server</Title>' +
+ ' <OnlineResource>http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;</OnlineResource>' +
+ '</Service>' +
+ '' +
+ '<Capability>' +
+ ' <Request>' +
+ ' <GetCapabilities>' +
+ ' <DCPType>' +
+ ' <HTTP>' +
+ ' <Get onlineResource="http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;" />' +
+ ' </HTTP>' +
+ ' </DCPType>' +
+ ' </GetCapabilities>' +
+ '' +
+ ' <DescribeFeatureType>' +
+ ' <SchemaDescriptionLanguage>' +
+ ' <XMLSCHEMA/>' +
+ ' </SchemaDescriptionLanguage>' +
+ ' <DCPType>' +
+ ' <HTTP>' +
+ ' <Get onlineResource="http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;" />' +
+ ' </HTTP>' +
+ ' </DCPType>' +
+ '' +
+ ' </DescribeFeatureType>' +
+ ' <GetFeature>' +
+ ' <ResultFormat>' +
+ ' <GML2/>' +
+ ' </ResultFormat>' +
+ ' <DCPType>' +
+ ' <HTTP>' +
+ ' <Get onlineResource="http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;" />' +
+ ' </HTTP>' +
+ '' +
+ ' </DCPType>' +
+ ' </GetFeature>' +
+ ' </Request>' +
+ '</Capability>' +
+ '' +
+ '<FeatureTypeList>' +
+ ' <Operations>' +
+ ' <Query/>' +
+ ' </Operations>' +
+ ' <FeatureType>' +
+ '' +
+ ' <Name>park</Name>' +
+ ' <Title>Parks</Title>' +
+ ' <SRS>EPSG:42304</SRS>' +
+ ' <LatLongBoundingBox minx="-173.433" miny="41.4271" maxx="-13.3643" maxy="83.7466" />' +
+ ' </FeatureType>' +
+ ' <FeatureType>' +
+ ' <Name>popplace</Name>' +
+ '' +
+ ' <Title>Cities</Title>' +
+ ' <SRS>EPSG:42304</SRS>' +
+ ' <LatLongBoundingBox minx="-172.301" miny="36.3541" maxx="-12.9698" maxy="83.4832" />' +
+ ' </FeatureType>' +
+ '</FeatureTypeList>' +
+ '' +
+ '<ogc:Filter_Capabilities>' +
+ ' <ogc:Spatial_Capabilities>' +
+ ' <ogc:Spatial_Operators>' +
+ '' +
+ ' <ogc:BBOX/>' +
+ ' </ogc:Spatial_Operators>' +
+ ' </ogc:Spatial_Capabilities>' +
+ ' <!-- Provide some ScalarCapabilties just for the XML to validate against the schema even if we don\'t support any. (Yes this is stupid!) -->' +
+ ' <ogc:Scalar_Capabilities>' +
+ ' <ogc:Logical_Operators />' +
+ ' </ogc:Scalar_Capabilities>' +
+ '</ogc:Filter_Capabilities>' +
+ '' +
+ '</WFS_Capabilities>';
+ res = parser.read(text);
+ var ft = res.featureTypeList.featureTypes;
+ t.eq(ft.length, 2, "number of feature types correct");
+ t.eq(ft[0]["title"], "Parks", "title of first feature type correct");
+ t.eq(ft[0]["name"], "park", "name of first feature type correct");
+ t.eq(ft[0]["srs"], "EPSG:42304", "srs of first feature type correct");
+
+ var service = res.service;
+ t.eq(service.name, 'MapServer WFS', "service name correct");
+ t.eq(service.title, 'GMap WMS Demo Server', "service title correct");
+ t.eq(service.onlineResource, 'http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&service=WFS&', "service onlineresource correct");
+ t.eq(res.capability.request.getfeature.href.get, "http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&service=WFS&", "getfeature request get href correct");
+ t.eq(res.capability.request.getfeature.formats[0], "GML2", "getfeature response format [0] correct");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFSDescribeFeatureType.html b/misc/openlayers/tests/Format/WFSDescribeFeatureType.html
new file mode 100644
index 0000000..77f348d
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFSDescribeFeatureType.html
@@ -0,0 +1,436 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_WFSDescribeFeatureType(t) {
+ t.plan(39);
+
+ var parser = new OpenLayers.Format.WFSDescribeFeatureType();
+
+ // single typeName from UMN Mapserver
+ var text =
+ '<?xml version="1.0" encoding="ISO-8859-1" ?>' +
+ '<schema' +
+ ' targetNamespace="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:rws="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:ogc="http://www.opengis.net/ogc"' +
+ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' elementFormDefault="qualified" version="0.1" >' +
+ ' <import namespace="http://www.opengis.net/gml"' +
+ ' schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />' +
+ ' <element name="AAA64" ' +
+ ' type="rws:AAA64Type" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="AAA64Type">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiLineStringPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' <element name="OBJECTID" type="string"/>' +
+ ' <element name="ROUTE" type="string"/>' +
+ ' <element name="ROUTE_CH" type="string"/>' +
+ ' <element name="COUNT" type="string"/>' +
+ ' <element name="BEHEERDER" type="string"/>' +
+ ' <element name="LENGTH" type="string"/>' +
+ ' <element name="SHAPE" type="string"/>' +
+ ' <element name="SE_ANNO_CAD_DATA" type="string"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ '</schema>';
+ var res = parser.read(text);
+
+ t.eq(res.featureTypes.length, 1,
+ "There is only 1 typename, so length should be 1");
+
+ t.eq(res.featureTypes[0].properties[0].type, 'gml:MultiLineStringPropertyType',
+ "The first attribute is of type multi line string");
+
+ t.eq(res.featureTypes[0].properties[2].name, 'ROUTE',
+ "The third attribute is named ROUTE");
+
+ t.eq(res.featureTypes[0].properties[2].type, 'string',
+ "The third attribute is of type string");
+
+ // three typeNames in one response from UMN Mapserver
+ text =
+ '<?xml version="1.0" encoding="ISO-8859-1" ?>' +
+ '<schema' +
+ ' targetNamespace="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:rws="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:ogc="http://www.opengis.net/ogc"' +
+ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' elementFormDefault="qualified" version="0.1" >' +
+ ' <import namespace="http://www.opengis.net/gml"' +
+ ' schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />' +
+ ' <element name="KGNAT.VKUNSTWERK" ' +
+ ' type="rws:KGNAT.VKUNSTWERKType" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="KGNAT.VKUNSTWERKType">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiPolygonPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' <element name="OBJECTID" type="string"/>' +
+ ' <element name="OBJECTSUBCATEGORIE" type="string"/>' +
+ ' <element name="DIENSTCODE" type="string"/>' +
+ ' <element name="DISTRICTNAAM" type="string"/>' +
+ ' <element name="CODEBPN" type="string"/>' +
+ ' <element name="WSD" type="string"/>' +
+ ' <element name="SUBCAT" type="string"/>' +
+ ' <element name="ZIJDE" type="string"/>' +
+ ' <element name="KM" type="string"/>' +
+ ' <element name="ELEMENTCODE" type="string"/>' +
+ ' <element name="COMPLEXCODE" type="string"/>' +
+ ' <element name="BEHEEROBJECTCODE" type="string"/>' +
+ ' <element name="BEGINDATUM" type="string"/>' +
+ ' <element name="NAAMCONTACTPERSOON" type="string"/>' +
+ ' <element name="KMTOT" type="string"/>' +
+ ' <element name="HOOFDWATERSYSTEEM" type="string"/>' +
+ ' <element name="WATERSYSTEEMNAAM" type="string"/>' +
+ ' <element name="OBJECTNAAM" type="string"/>' +
+ ' <element name="HERKOMST" type="string"/>' +
+ ' <element name="BEHEERSREGIME" type="string"/>' +
+ ' <element name="VERSIE" type="string"/>' +
+ ' <element name="KWALITEITSNIVEAU" type="string"/>' +
+ ' <element name="STICHTINGSJAAR" type="string"/>' +
+ ' <element name="OBJECTTYPE" type="string"/>' +
+ ' <element name="OPMERKING" type="string"/>' +
+ ' <element name="OPPERVLAKTE" type="string"/>' +
+ ' <element name="SE_ANNO_CAD_DATA" type="string"/>' +
+ ' <element name="SHAPE" type="string"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ ' <element name="KGNAT.LKUNSTWERK" ' +
+ ' type="rws:KGNAT.LKUNSTWERKType" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="KGNAT.LKUNSTWERKType">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiLineStringPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' <element name="OBJECTID" type="string"/>' +
+ ' <element name="OBJECTSUBCATEGORIE" type="string"/>' +
+ ' <element name="DIENSTCODE" type="string"/>' +
+ ' <element name="DISTRICTNAAM" type="string"/>' +
+ ' <element name="CODEBPN" type="string"/>' +
+ ' <element name="WSD" type="string"/>' +
+ ' <element name="SUBCAT" type="string"/>' +
+ ' <element name="ZIJDE" type="string"/>' +
+ ' <element name="KM" type="string"/>' +
+ ' <element name="ELEMENTCODE" type="string"/>' +
+ ' <element name="COMPLEXCODE" type="string"/>' +
+ ' <element name="BEHEEROBJECTCODE" type="string"/>' +
+ ' <element name="BEGINDATUM" type="string"/>' +
+ ' <element name="NAAMCONTACTPERSOON" type="string"/>' +
+ ' <element name="KMTOT" type="string"/>' +
+ ' <element name="HOOFDWATERSYSTEEM" type="string"/>' +
+ ' <element name="WATERSYSTEEMNAAM" type="string"/>' +
+ ' <element name="OBJECTNAAM" type="string"/>' +
+ ' <element name="HERKOMST" type="string"/>' +
+ ' <element name="BEHEERSREGIME" type="string"/>' +
+ ' <element name="VERSIE" type="string"/>' +
+ ' <element name="KWALITEITSNIVEAU" type="string"/>' +
+ ' <element name="STICHTINGSJAAR" type="string"/>' +
+ ' <element name="OBJECTTYPE" type="string"/>' +
+ ' <element name="OPMERKING" type="string"/>' +
+ ' <element name="LENGTE" type="string"/>' +
+ ' <element name="SE_ANNO_CAD_DATA" type="string"/>' +
+ ' <element name="SHAPE" type="string"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ ' <element name="KGNAT.PKUNSTWERK" ' +
+ ' type="rws:KGNAT.PKUNSTWERKType" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="KGNAT.PKUNSTWERKType">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiPointPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' <element name="OBJECTID" type="string"/>' +
+ ' <element name="OBJECTSUBCATEGORIE" type="string"/>' +
+ ' <element name="DIENSTCODE" type="string"/>' +
+ ' <element name="DISTRICTNAAM" type="string"/>' +
+ ' <element name="CODEBPN" type="string"/>' +
+ ' <element name="WSD" type="string"/>' +
+ ' <element name="SUBCAT" type="string"/>' +
+ ' <element name="ZIJDE" type="string"/>' +
+ ' <element name="KM" type="string"/>' +
+ ' <element name="ELEMENTCODE" type="string"/>' +
+ ' <element name="COMPLEXCODE" type="string"/>' +
+ ' <element name="BEHEEROBJECTCODE" type="string"/>' +
+ ' <element name="BEGINDATUM" type="string"/>' +
+ ' <element name="NAAMCONTACTPERSOON" type="string"/>' +
+ ' <element name="KMTOT" type="string"/>' +
+ ' <element name="HOOFDWATERSYSTEEM" type="string"/>' +
+ ' <element name="WATERSYSTEEMNAAM" type="string"/>' +
+ ' <element name="OBJECTNAAM" type="string"/>' +
+ ' <element name="HERKOMST" type="string"/>' +
+ ' <element name="BEHEERSREGIME" type="string"/>' +
+ ' <element name="VERSIE" type="string"/>' +
+ ' <element name="KWALITEITSNIVEAU" type="string"/>' +
+ ' <element name="STICHTINGSJAAR" type="string"/>' +
+ ' <element name="OBJECTTYPE" type="string"/>' +
+ ' <element name="OPMERKING" type="string"/>' +
+ ' <element name="X" type="string"/>' +
+ ' <element name="Y" type="string"/>' +
+ ' <element name="SE_ANNO_CAD_DATA" type="string"/>' +
+ ' <element name="SHAPE" type="string"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ '</schema>';
+
+ parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ res = parser.read(text);
+
+ t.eq(res.featureTypes.length, 3,
+ "There are 3 typenames, so length should be 3");
+
+ t.eq(res.featureTypes[0].typeName, 'KGNAT.VKUNSTWERK',
+ "There name of the first typename is KGNAT.VKUNSTWERK");
+
+ t.eq(res.featureTypes[2].properties.length, 30,
+ "We expect 30 attributes in the third typename");
+
+ t.eq(res.featureTypes[2].properties[1].name, 'OBJECTID',
+ "The second attribute has name OBJECTID");
+
+ t.eq(res.featureTypes[2].properties[1].type, 'string',
+ "The second attribute has type string");
+
+ t.eq(res.targetNamespace, 'http://mapserver.gis.umn.edu/mapserver',
+ "The targetNamespace should be http://mapserver.gis.umn.edu/mapserver");
+
+ t.eq(res.targetPrefix, 'rws', "the targetPrefix should be rws");
+
+ // response from Ionic WFS, taken from:
+ // http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA?service=WFS&request=DescribeFeatureType&version=1.0.0&typename=wfs:highways
+ text =
+ "<?xml version='1.0' encoding='utf-8' ?>" +
+ ' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:wfs="http://www.ionicsoft.com/wfs" targetNamespace="http://www.ionicsoft.com/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" elementFormDefault="qualified" version="0.1">' +
+ ' <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>' +
+ ' <xsd:element name="highways" substitutionGroup="gml:_Feature" type="wfs:highways"/>' +
+ ' <xsd:complexType name="highways">' +
+ ' <xsd:complexContent>' +
+ ' <xsd:extension base="gml:AbstractFeatureType">' +
+ ' <xsd:sequence>' +
+ ' <xsd:element name="ROUTE_" minOccurs="0" nillable="true" type="xsd:int"/>' +
+ ' <xsd:element name="ROUTE_ID" minOccurs="0" nillable="true" type="xsd:int"/>' +
+ ' <xsd:element name="RT_NUMBER" minOccurs="0" nillable="true" type="xsd:string"/>' +
+ ' <xsd:element name="GEOMETRY" minOccurs="0" nillable="true" type="gml:GeometryAssociationType"/>' +
+ ' </xsd:sequence>' +
+ ' </xsd:extension>' +
+ ' </xsd:complexContent>' +
+ ' </xsd:complexType>' +
+ ' </xsd:schema>';
+
+ parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ res = parser.read(text);
+
+ t.eq(res.featureTypes.length, 1,
+ "There is 1 typename, so length should be 1");
+
+ t.eq(res.featureTypes[0].typeName, "highways",
+ "The name of the typename is highways");
+
+ t.eq(res.featureTypes[0].properties.length, 4,
+ "We expect 4 attributes in the first typename");
+
+ t.eq(res.featureTypes[0].properties[1].name, 'ROUTE_ID',
+ "The second attribute has name ROUTE_ID");
+
+ t.eq(res.featureTypes[0].properties[1].type, 'xsd:int',
+ "The second attribute has type integer");
+
+ t.eq(parseInt(res.featureTypes[0].properties[1].minOccurs), 0,
+ "The second attribute has minOccurs 0");
+
+ t.eq(res.targetNamespace, 'http://www.ionicsoft.com/wfs',
+ "The targetNamespace should be http://www.ionicsoft.com/wfs");
+
+ t.eq(res.targetPrefix, 'wfs', "the targetPrefix should be wfs");
+
+
+ // GeoServer tests
+
+ function geoServerTests(text) {
+ parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ res = parser.read(text);
+
+ t.eq(res.featureTypes.length, 1,
+ "There is 1 typename, so length should be 1");
+
+ t.eq(res.featureTypes[0].typeName, "railroads",
+ "The name of the typeName is railroads");
+
+ t.eq(res.featureTypes[0].properties.length, 2,
+ "We expect 2 attributes in the typename");
+
+ t.eq(res.featureTypes[0].properties[0].name, 'cat',
+ "The first attribute has name cat");
+
+ t.eq(res.featureTypes[0].properties[0].type.split(":")[1], 'long',
+ "The first attribute has type long with a prefix");
+
+ t.eq(res.featureTypes[0].properties[0].localType, 'long',
+ "The first attribute has localType long");
+
+ t.eq(res.targetNamespace, 'http://opengeo.org',
+ "The targetNamespace should be http://opengeo.org");
+
+ t.eq(res.targetPrefix, 'opengeo', "the targetPrefix should be opengeo");
+ }
+
+
+ // Read Geoserver WFS 1.0.0 response
+ // Taken from: http://demo.opengeo.org/geoserver/wfs?service=WFS&request=DescribeFeatureType&typename=opengeo:railroads&version=1.0.0
+ text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<xs:schema targetNamespace="http://opengeo.org" xmlns:opengeo="http://opengeo.org" xmlns:gml="http://www.opengis.net/gml" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">' +
+ ' <xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://demo.opengeo.org:80/geoserver/schemas/gml/2.1.2.1/feature.xsd"/>' +
+ ' <xs:complexType xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" name="railroads_Type">' +
+ ' <xs:complexContent>' +
+ ' <xs:extension base="gml:AbstractFeatureType">' +
+ ' <xs:sequence>' +
+ ' <xs:element name="cat" minOccurs="0" nillable="true" type="xs:long"/>' +
+ ' <xs:element name="the_geom" minOccurs="0" nillable="true" type="gml:MultiLineStringPropertyType"/>' +
+ ' </xs:sequence>' +
+ ' </xs:extension>' +
+ ' </xs:complexContent>' +
+ ' </xs:complexType>' +
+ ' <xs:element name="railroads" type="opengeo:railroads_Type" substitutionGroup="gml:_Feature"/>' +
+ '</xs:schema>';
+
+ geoServerTests(text);
+
+
+ // Read GeoServer WFS 1.1.0 response
+ // taken from http://demo.opengeo.org/geoserver/wfs?service=WFS&request=DescribeFeatureType&typename=opengeo:railroads&version=1.1.0
+ text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ ' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:opengeo="http://opengeo.org" elementFormDefault="qualified" targetNamespace="http://opengeo.org">' +
+ ' <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://demo.opengeo.org:80/geoserver/wfs/schemas/gml/3.1.1/base/gml.xsd"/>' +
+ ' <xsd:complexType name="railroadsType">' +
+ ' <xsd:complexContent>' +
+ ' <xsd:extension base="gml:AbstractFeatureType">' +
+ ' <xsd:sequence>' +
+ ' <xsd:element maxOccurs="1" minOccurs="0" name="cat" nillable="true" type="xsd:long"/>' +
+ ' <xsd:element maxOccurs="1" minOccurs="0" name="the_geom" nillable="true" type="gml:MultiLineStringPropertyType"/>' +
+ ' </xsd:sequence>' +
+ ' </xsd:extension>' +
+ ' </xsd:complexContent>' +
+ ' </xsd:complexType>' +
+ ' <xsd:element name="railroads" substitutionGroup="gml:_Feature" type="opengeo:railroadsType"/>' +
+ ' </xsd:schema>';
+
+ geoServerTests(text);
+
+ // Another GeoServer response with type restrictions
+ // taken from http://sigma.openplans.org/geoserver/wfs?service=WFS&request=DescribeFeatureType&typename=topp:states&version=1.0.0
+ text = '<?xml version="1.0" encoding="UTF-8"?><xs:schema targetNamespace="http://www.openplans.org/topp" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"><xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://sigma.openplans.org:80/geoserver/schemas/gml/2.1.2.1/feature.xsd"/><xs:complexType xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" name="states_Type"><xs:complexContent><xs:extension base="gml:AbstractFeatureType"><xs:sequence><xs:element name="the_geom" minOccurs="0" nillable="true" type="gml:MultiPolygonPropertyType"/><xs:element name="STATE_NAME" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="25"/></xs:restriction></xs:simpleType></xs:element><xs:element name="STATE_FIPS" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="2"/></xs:restriction></xs:simpleType></xs:element><xs:element name="SUB_REGION" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="7"/></xs:restriction></xs:simpleType></xs:element><xs:element name="STATE_ABBR" minOccurs="0" nillable="true"><xs:simpleType><xs:restriction base="xs:string"><xs:maxLength value="2"/></xs:restriction></xs:simpleType></xs:element><xs:element name="LAND_KM" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="WATER_KM" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="PERSONS" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="FAMILIES" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="HOUSHOLD" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="MALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="FEMALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="WORKERS" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="DRVALONE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="CARPOOL" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="PUBTRANS" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="EMPLOYED" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="UNEMPLOY" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="SERVICE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="MANUAL" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="P_MALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="P_FEMALE" minOccurs="0" nillable="true" type="xs:double"/><xs:element name="SAMP_POP" minOccurs="0" nillable="true" type="xs:double"/></xs:sequence></xs:extension></xs:complexContent></xs:complexType><xs:element name="states" type="topp:states_Type" substitutionGroup="gml:_Feature"/></xs:schema>';
+
+ parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ res = parser.read(text);
+
+ t.eq(res.featureTypes[0].properties[1].name, "STATE_NAME",
+ "name of 2nd property of 1st featureType should be 'STATE_NAME'");
+
+ t.eq(res.featureTypes[0].properties[1].type, "xs:string",
+ "type of 2nd property of 1st featureType should be 'xs:string'");
+
+ t.eq(res.featureTypes[0].properties[1].localType, "string",
+ "localType of 2nd property of 1st featureType should be 'string'");
+
+ t.eq(res.featureTypes[0].properties[1].restriction.maxLength, "25",
+ "the maxLength restriction should be 25");
+ }
+
+ function test_readRestriction(t) {
+ t.plan(2);
+ var text =
+ '<restriction xmlns="http://www.w3.org/2001/XMLSchema" base="xs:string">' +
+ ' <enumeration value="One"/>' +
+ ' <enumeration value="Two"/>' +
+ '</restriction>';
+ var doc = OpenLayers.Format.XML.prototype.read(text).documentElement;
+ var obj = {};
+ new OpenLayers.Format.WFSDescribeFeatureType().readRestriction(doc, obj);
+
+ t.eq(obj.enumeration.length, 2, "enumeration has a length of 2");
+ t.eq(obj.enumeration[1], "Two", "2nd enumeration value is 'Two'");
+ // other functionality of readRestriction already tested in the last
+ // GeoServer example above
+ }
+
+ function test_read_exception(t) {
+ t.plan(1);
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<ows:ExceptionReport version="1.0.0"' +
+ ' xsi:schemaLocation="http://www.opengis.net/ows http://localhost:8080/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows">' +
+ ' <ows:Exception exceptionCode="NoApplicableCode">' +
+ ' <ows:ExceptionText>Could not find type: {http://geonode.org/}_map_4_annotations</ows:ExceptionText>' +
+ ' </ows:Exception>' +
+ '</ows:ExceptionReport>';
+ var format = new OpenLayers.Format.WFSDescribeFeatureType();
+ var obj = format.read(text);
+ t.ok(!!obj.error, "Error reported correctly");
+ }
+
+ function test_read_annotation(t) {
+ t.plan(2);
+ var text =
+ '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns:analytics="http://opengeo.org/analytics" xmlns:cite="http://www.opengeospatial.net/cite"' +
+ ' xmlns:gml="http://www.opengis.net/gml" xmlns:it.geosolutions="http://www.geo-solutions.it"' +
+ ' xmlns:nurc="http://www.nurc.nato.int" xmlns:og="http://opengeo.org"' +
+ ' xmlns:sde="http://geoserver.sf.net" xmlns:sf="http://www.openplans.org/spearfish"' +
+ ' xmlns:tiger="http://www.census.gov" xmlns:tike="http://opengeo.org/#tike"' +
+ ' xmlns:topp="http://www.openplans.org/topp" xmlns:usgs="http://www.usgs.gov/"' +
+ ' xmlns:za="http://opengeo.org/za" elementFormDefault="qualified"' +
+ ' targetNamespace="http://www.openplans.org/topp">' +
+ ' <xsd:import namespace="http://www.opengis.net/gml"' +
+ ' schemaLocation="http://demo.opengeo.org/geoserver/schemas/gml/3.1.1/base/gml.xsd"/>' +
+ ' <xsd:complexType name="statesType">' +
+ ' <xsd:complexContent>' +
+ ' <xsd:extension base="gml:AbstractFeatureType">' +
+ ' <xsd:sequence>' +
+ ' <xsd:element maxOccurs="1" minOccurs="0" name="PERSONS" nillable="true" type="xsd:double">' +
+ ' <xsd:annotation>' +
+ ' <xsd:appinfo>{"title":{"en":"Population"}}</xsd:appinfo>' +
+ ' <xsd:documentation xml:lang="en"> Number of persons living in the state' +
+ ' </xsd:documentation>' +
+ ' </xsd:annotation>' +
+ ' </xsd:element>' +
+ ' </xsd:sequence>' +
+ ' </xsd:extension>' +
+ ' </xsd:complexContent>' +
+ ' </xsd:complexType>' +
+ ' <xsd:element name="states" substitutionGroup="gml:_Feature" type="topp:statesType"/>' +
+ '</xsd:schema>';
+ var format = new OpenLayers.Format.WFSDescribeFeatureType();
+ var res = format.read(text);
+ var property = res.featureTypes[0].properties[0];
+ t.eq(property.annotation.appinfo[0], '{"title":{"en":"Population"}}', "appinfo read correctly");
+ t.eq(property.annotation.documentation[0], {lang: "en", textContent: 'Number of persons living in the state'}, "documentation read correctly");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFST.html b/misc/openlayers/tests/Format/WFST.html
new file mode 100644
index 0000000..9623b05
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFST.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.WFST();
+ t.ok(format instanceof OpenLayers.Format.WFST.v1_0_0, "constructor returns instance with default versioned format");
+
+ format = new OpenLayers.Format.WFST({
+ version: "1.1.0"
+ });
+ t.ok(format instanceof OpenLayers.Format.WFST.v1_1_0, "constructor returns instance with custom versioned format");
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:512px; height:256px"> </div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFST/v1.html b/misc/openlayers/tests/Format/WFST/v1.html
new file mode 100644
index 0000000..6cfb1ca
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFST/v1.html
@@ -0,0 +1,455 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read(t) {
+ t.plan(1);
+
+ var data = readXML("FeatureCollection");
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states"
+ });
+ var features = format.read(data);
+
+ t.eq(features.length, 1, "number of features read from FeatureCollection is correct");
+ }
+
+ function test_write(t) {
+
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ featurePrefix: "topp",
+ geometryName: "the_geom"
+ });
+
+ var feature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(1,2),
+ {foo: "bar"}
+ );
+
+ var insertFeature = feature.clone();
+ // null value does not show up in insert
+ insertFeature.attributes.nul = null;
+ insertFeature.state = OpenLayers.State.INSERT;
+ var updateFeature = feature.clone();
+ // undefined value means don't create a Property element
+ updateFeature.attributes.unwritten = undefined;
+ // null value gets Property element with no Value
+ updateFeature.attributes.nul = null;
+ updateFeature.fid = "fid.42";
+ updateFeature.state = OpenLayers.State.UPDATE;
+ var deleteFeature = feature.clone();
+ deleteFeature.state = OpenLayers.State.DELETE;
+ deleteFeature.fid = "fid.37";
+
+ t.plan(8);
+ var snippets = {
+ "GetFeature": {handle: "handle_g", maxFeatures: 1, outputFormat: 'json'},
+ "Transaction": {handle: "handle_t"},
+ "Insert": {feature: insertFeature, options: {handle: "handle_i"}},
+ "Update": {feature: updateFeature, options: {handle: "handle_u"}},
+ "Delete": {feature: deleteFeature, options: {handle: "handle_d"}}
+ }
+
+ var arg;
+ for(var snippet in snippets) {
+ arg = snippets[snippet]
+ var expected = readXML(snippet);
+ var got = format.writers["wfs"][snippet].apply(format, [arg]);
+ t.xml_eq(got, expected, snippet + " request created correctly");
+ }
+
+ updateFeature.modified = {geometry: updateFeature.geometry.clone()};
+ updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);
+ var expected = readXML("UpdateModified");
+ var got = format.writers["wfs"]["Update"].apply(format, [{feature: updateFeature}]);
+ t.xml_eq(got, expected, "Update request for feature with modified geometry created correctly");
+
+ updateFeature.modified.attributes = {foo: "bar"};
+ updateFeature.attributes.foo = "baz";
+ delete updateFeature.modified.geometry;
+ var expected = readXML("UpdateModifiedNoGeometry");
+ var got = format.writers["wfs"]["Update"].apply(format, [{feature: updateFeature}]);
+ t.xml_eq(got, expected, "Update request for feature with no modified geometry but modified attributes created correctly");
+
+ // test for a feature that originally had a null geometry and a null value for the attribute
+ updateFeature.modified = {attributes: {foo: null, nul: "nul"}, geometry: null};
+ updateFeature.attributes.foo = "bar";
+ updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);
+ var expected = readXML("UpdateModified");
+ var got = format.writers["wfs"]["Update"].apply(format, [{feature: updateFeature}]);
+ t.xml_eq(got, expected, "Update request for feature with modified geometry created correctly even if original geometry was null");
+ }
+
+ function test_writeNative(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ version: "1.1.0",
+ featurePrefix: "topp",
+ geometryName: null
+ });
+ var output = format.write(null, {nativeElements: [
+ {
+ vendorId: "ORACLE",
+ safeToIgnore: true,
+ value: "ALTER SESSION ENABLE PARALLEL DML"
+ }, {
+ vendorId: "ORACLE",
+ safeToIgnore: false,
+ value: "Another native line goes here"
+ }]
+ });
+ var expected = '<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wfs:Native vendorId="ORACLE" safeToIgnore="true">ALTER SESSION ENABLE PARALLEL DML</wfs:Native><wfs:Native vendorId="ORACLE" safeToIgnore="false">Another native line goes here</wfs:Native></wfs:Transaction>';
+ t.xml_eq(output, expected, "Native elements written out correctly");
+ }
+
+ function test_write_no_geometry(t) {
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ featurePrefix: "topp",
+ geometryName: null
+ });
+
+ var feature = new OpenLayers.Feature.Vector(null, {foo: "bar"});
+ feature.state = OpenLayers.State.UPDATE;
+ feature.fid = "fid.36";
+
+ t.plan(1);
+ var snippets = {
+ "UpdateNoGeometry": {feature: feature}
+ }
+
+ var arg;
+ for(var snippet in snippets) {
+ arg = snippets[snippet]
+ var expected = readXML(snippet);
+ var got = format.writers["wfs"]["Update"].apply(format, [arg]);
+ t.xml_eq(got, expected, snippet + " request without geometry created correctly");
+ }
+ }
+
+ function test_setFilterProperty(t) {
+ t.plan(2);
+ var format = new OpenLayers.Format.WFST({
+ geometryName: "foo"
+ });
+ var filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(1,2,3,4)
+ }), new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.DWITHIN,
+ property: "bar",
+ value: new OpenLayers.Geometry.Point(1,2),
+ distance: 10
+ })]
+ });
+ format.setFilterProperty(filter);
+ t.eq(filter.filters[0].property, "foo", "property set if not set on filter");
+ t.eq(filter.filters[1].property, "bar", "property not set if set on filter");
+ }
+
+ function test_update_null_geometry(t) {
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ featurePrefix: "topp",
+ geometryName: "the_geom"
+ });
+
+ var feature = new OpenLayers.Feature.Vector(null, {foo: "bar"});
+ feature.state = OpenLayers.State.UPDATE;
+ feature.fid = "fid.36";
+
+ t.plan(1);
+ var snippets = {
+ "UpdateNullGeometry": {feature: feature}
+ };
+
+ var arg;
+ for (var snippet in snippets) {
+ arg = snippets[snippet]
+ var expected = readXML(snippet);
+ var got = format.writers["wfs"]["Update"].apply(format, [arg]);
+ t.xml_eq(got, expected, snippet + " request with null geometry created correctly");
+ }
+ }
+
+ function test_write_multiple(t) {
+
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: ["states", "cities"],
+ featurePrefix: "topp",
+ geometryName: "the_geom"
+ });
+
+ t.plan(1);
+ var snippets = {
+ "GetFeatureMultiple": {}
+ }
+
+ var arg;
+ for(var snippet in snippets) {
+ arg = snippets[snippet]
+ var expected = readXML(snippet);
+ var got = format.writers["wfs"]["GetFeature"].apply(format, [arg]);
+ t.xml_eq(got, expected, snippet + " request created correctly with multiple typenames");
+ }
+ }
+
+ function test_write_multi(t) {
+ t.plan(2);
+ var format = new OpenLayers.Format.WFST({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ featurePrefix: "topp",
+ geometryName: "the_geom"
+ });
+
+ var feature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(1,2),
+ {foo: "bar"}
+ );
+
+ var insertFeature = feature.clone();
+ // null value does not show up in insert
+ insertFeature.attributes.nul = null;
+ insertFeature.state = OpenLayers.State.INSERT;
+ var updateFeature = feature.clone();
+ // undefined value means don't create a Property element
+ updateFeature.attributes.unwritten = undefined;
+ // null value gets Property element with no Value
+ updateFeature.attributes.nul = null;
+ updateFeature.fid = "fid.42";
+ updateFeature.state = OpenLayers.State.UPDATE;
+ var features = [insertFeature, updateFeature];
+
+ var expected = readXML("TransactionMulti");
+ var geomTypes = OpenLayers.Util.extend({}, format.geometryTypes);
+ var got = format.writers["wfs"]["Transaction"].apply(format, [{
+ features: features,
+ options: {multi: true}}
+ ]);
+ t.xml_eq(got, expected, "Transaction request with multi option created correctly");
+ t.eq(format.geometryTypes, geomTypes, "geometry types unchanged after write with multi option");
+ }
+
+ function readXML(id) {
+ var xml = document.getElementById(id).firstChild.nodeValue;
+ return new OpenLayers.Format.XML().read(xml).documentElement;
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:512px; height:256px"> </div>
+
+<div id="FeatureCollection"><!--
+<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml">
+ <gml:featureMember>
+ <topp:states fid="states.3">
+ <topp:the_geom>
+ <gml:MultiPolygon srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
+ <gml:polygonMember>
+ <gml:Polygon>
+ <gml:outerBoundaryIs>
+ <gml:LinearRing>
+ <gml:coordinates decimal="." cs="," ts=" ">-75.70742,38.557476 -75.71106,38.649551 -75.724937,38.83017 -75.752922,39.141548 -75.761658,39.247753 -75.764664,39.295849 -75.772697,39.383007 -75.791435,39.723755 -75.775269,39.724442 -75.745934,39.774818 -75.695114,39.820347 -75.644341,39.838196 -75.583794,39.840008 -75.470345,39.826435 -75.42083,39.79887 -75.412117,39.789658 -75.428009,39.77813 -75.460754,39.763248 -75.475128,39.741718 -75.476334,39.719971 -75.489639,39.714745 -75.610725,39.612793 -75.562996,39.566723 -75.590187,39.463768 -75.515572,39.36694 -75.402481,39.257637 -75.397728,39.073036 -75.324852,39.012386 -75.307899,38.945911 -75.190941,38.80867 -75.083138,38.799812 -75.045998,38.44949 -75.068298,38.449963 -75.093094,38.450451 -75.350204,38.455208 -75.69915,38.463066 -75.70742,38.557476</gml:coordinates>
+ </gml:LinearRing>
+ </gml:outerBoundaryIs>
+ </gml:Polygon>
+ </gml:polygonMember>
+ </gml:MultiPolygon>
+ </topp:the_geom>
+ <topp:STATE_NAME>Delaware</topp:STATE_NAME>
+ <topp:STATE_FIPS>10</topp:STATE_FIPS>
+ <topp:SUB_REGION>S Atl</topp:SUB_REGION>
+ <topp:STATE_ABBR>DE</topp:STATE_ABBR>
+ <topp:LAND_KM>5062.456</topp:LAND_KM>
+ <topp:WATER_KM>1385.022</topp:WATER_KM>
+ <topp:PERSONS>666168.0</topp:PERSONS>
+ <topp:FAMILIES>175867.0</topp:FAMILIES>
+ <topp:HOUSHOLD>247497.0</topp:HOUSHOLD>
+ <topp:MALE>322968.0</topp:MALE>
+ <topp:FEMALE>343200.0</topp:FEMALE>
+ <topp:WORKERS>247566.0</topp:WORKERS>
+ <topp:DRVALONE>258087.0</topp:DRVALONE>
+ <topp:CARPOOL>42968.0</topp:CARPOOL>
+ <topp:PUBTRANS>8069.0</topp:PUBTRANS>
+ <topp:EMPLOYED>335147.0</topp:EMPLOYED>
+ <topp:UNEMPLOY>13945.0</topp:UNEMPLOY>
+ <topp:SERVICE>87973.0</topp:SERVICE>
+ <topp:MANUAL>44140.0</topp:MANUAL>
+ <topp:P_MALE>0.485</topp:P_MALE>
+ <topp:P_FEMALE>0.515</topp:P_FEMALE>
+ <topp:SAMP_POP>102776.0</topp:SAMP_POP>
+ </topp:states>
+ </gml:featureMember>
+</wfs:FeatureCollection>
+--></div>
+
+<div id="GetFeature"><!--
+<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0" handle="handle_g" outputFormat="json" maxFeatures="1" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <wfs:Query typeName="topp:states" xmlns:topp="http://www.openplans.org/topp"/>
+</wfs:GetFeature>
+--></div>
+<div id="GetFeatureMultiple"><!--
+<wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <wfs:Query typeName="topp:states" xmlns:topp="http://www.openplans.org/topp"/>
+ <wfs:Query typeName="topp:cities" xmlns:topp="http://www.openplans.org/topp"/>
+</wfs:GetFeature>
+--></div>
+<div id="Transaction"><!--
+<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0"/>
+--></div>
+<div id="TransactionMulti"><!--
+<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0">
+ <wfs:Insert>
+ <feature:states xmlns:feature="http://www.openplans.org/topp">
+ <feature:the_geom>
+ <gml:MultiPoint xmlns:gml="http://www.opengis.net/gml">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+ </gml:MultiPoint>
+ </feature:the_geom>
+ <feature:foo>bar</feature:foo>
+ </feature:states>
+ </wfs:Insert>
+ <wfs:Update xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>the_geom</wfs:Name>
+ <wfs:Value>
+ <gml:MultiPoint xmlns:gml="http://www.opengis.net/gml">
+ <gml:pointMember>
+ <gml:Point>
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </gml:pointMember>
+ </gml:MultiPoint>
+ </wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>bar</wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>nul</wfs:Name>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.42"/>
+ </ogc:Filter>
+ </wfs:Update>
+</wfs:Transaction>
+--></div>
+<div id="Insert"><!--
+<wfs:Insert xmlns:wfs="http://www.opengis.net/wfs" handle="handle_i">
+ <feature:states xmlns:feature="http://www.openplans.org/topp">
+ <feature:the_geom>
+ <gml:Point xmlns:gml="http://www.opengis.net/gml">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </feature:the_geom>
+ <feature:foo>bar</feature:foo>
+ </feature:states>
+</wfs:Insert>
+--></div>
+<div id="Update"><!--
+<wfs:Update xmlns:wfs="http://www.opengis.net/wfs" handle="handle_u" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>the_geom</wfs:Name>
+ <wfs:Value>
+ <gml:Point xmlns:gml="http://www.opengis.net/gml">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
+ </gml:Point>
+ </wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>bar</wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>nul</wfs:Name>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.42"/>
+ </ogc:Filter>
+</wfs:Update>
+--></div>
+<div id="UpdateModified"><!--
+<wfs:Update xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>the_geom</wfs:Name>
+ <wfs:Value>
+ <gml:Point xmlns:gml="http://www.opengis.net/gml">
+ <gml:coordinates decimal="." cs="," ts=" ">2,3</gml:coordinates>
+ </gml:Point>
+ </wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>bar</wfs:Value>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>nul</wfs:Name>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.42"/>
+ </ogc:Filter>
+</wfs:Update>
+--></div>
+<div id="UpdateModifiedNoGeometry"><!--
+<wfs:Update xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>baz</wfs:Value>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.42"/>
+ </ogc:Filter>
+</wfs:Update>
+--></div>
+<div id="Delete"><!--
+<wfs:Delete xmlns:wfs="http://www.opengis.net/wfs" handle="handle_d" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.37"/>
+ </ogc:Filter>
+</wfs:Delete>
+--></div>
+<div id="UpdateNoGeometry"><!--
+<wfs:Update xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>bar</wfs:Value>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.36"/>
+ </ogc:Filter>
+</wfs:Update>
+--></div>
+<div id="UpdateNullGeometry"><!--
+<wfs:Update xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:Property>
+ <wfs:Name>the_geom</wfs:Name>
+ </wfs:Property>
+ <wfs:Property>
+ <wfs:Name>foo</wfs:Name>
+ <wfs:Value>bar</wfs:Value>
+ </wfs:Property>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:FeatureId fid="fid.36"/>
+ </ogc:Filter>
+</wfs:Update>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFST/v1_0_0.html b/misc/openlayers/tests/Format/WFST/v1_0_0.html
new file mode 100644
index 0000000..a8fce79
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFST/v1_0_0.html
@@ -0,0 +1,135 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.WFST.v1_0_0({});
+ t.ok(format instanceof OpenLayers.Format.WFST.v1_0_0, "constructor returns instance");
+ }
+
+ function test_read(t) {
+ t.plan(3);
+
+ var data = readXML("Transaction_Response");
+ var format = new OpenLayers.Format.WFST.v1_0_0({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states"
+ });
+ var result = format.read(data);
+ t.eq(result.insertIds[0], "parcelle.40", "First InsertId read correctly");
+ t.eq(result.insertIds[1], "parcelle.41", "Second InsertId read correctly");
+ t.eq(result.success, true, "Success read correctly");
+ }
+
+ function test_write(t) {
+
+ var format = new OpenLayers.Format.WFST.v1_0_0({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ featurePrefix: "topp",
+ geometryName: "the_geom"
+ });
+
+ var cases = [{
+ id: "query0",
+ writer: "wfs:Query",
+ arg: {
+ filter: new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds (1,2,3,4)
+ })
+ }
+ }, {
+ id: "query1",
+ writer: "wfs:Query",
+ arg: {
+ srsNameInQuery: true,
+ srsName: "EPSG:900913"
+ }
+ }, {
+ id: "getfeature0",
+ writer: "wfs:GetFeature",
+ arg: {
+ propertyNames: ["STATE_NAME", "STATE_FIPS", "STATE_ABBR"]
+ }
+ }];
+
+ t.plan(cases.length);
+
+ var test, got, exp;
+ for(var i=0; i<cases.length; ++i) {
+ test = cases[i];
+ exp = readXML(test.id);
+ got = format.writeNode(test.writer, test.arg);
+ t.xml_eq(got, exp, test.id + ": correct request");
+ }
+
+ }
+
+ function test_write_poorconfig(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.WFST.v1_0_0({
+ featureType: "states",
+ featurePrefix: "topp"
+ });
+ var exp = "topp:states";
+ var got = format.writeNode("wfs:Query").getAttribute("typeName");
+ t.eq(got, exp, "Query without featureNS but with featurePrefix queries for the correct featureType");
+ }
+
+ var xmlFormat = new OpenLayers.Format.XML();
+ function readXML(id) {
+ var xml = document.getElementById(id).firstChild.nodeValue;
+ return xmlFormat.read(xml).documentElement;
+ }
+
+ </script>
+</head>
+<body>
+<div id="Transaction_Response"><!--
+<wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc">
+ <wfs:InsertResult>
+ <ogc:FeatureId fid="parcelle.40"/>
+ <ogc:FeatureId fid="parcelle.41"/>
+ </wfs:InsertResult>
+ <wfs:TransactionResult>
+ <wfs:Status>
+ <wfs:SUCCESS/>
+ </wfs:Status>
+ </wfs:TransactionResult>
+</wfs:WFS_TransactionResponse>
+--></div>
+<div id="query0"><!--
+<wfs:Query xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:BBOX>
+ <ogc:PropertyName>the_geom</ogc:PropertyName>
+ <gml:Box xmlns:gml="http://www.opengis.net/gml">
+ <gml:coordinates decimal="." cs="," ts=" ">1,2 3,4</gml:coordinates>
+ </gml:Box>
+ </ogc:BBOX>
+ </ogc:Filter>
+</wfs:Query>
+--></div>
+<div id="query1"><!--
+<wfs:Query xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" srsName="EPSG:900913" xmlns:topp="http://www.openplans.org/topp">
+</wfs:Query>
+--></div>
+<div id="getfeature0"><!--
+<wfs:GetFeature service="WFS" version="1.0.0" xmlns:topp="http://www.openplans.org/topp"
+ 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://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">
+ <wfs:Query xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" xmlns:topp="http://www.openplans.org/topp">
+ <ogc:PropertyName>STATE_NAME</ogc:PropertyName>
+ <ogc:PropertyName>STATE_FIPS</ogc:PropertyName>
+ <ogc:PropertyName>STATE_ABBR</ogc:PropertyName>
+ </wfs:Query>
+</wfs:GetFeature>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WFST/v1_1_0.html b/misc/openlayers/tests/Format/WFST/v1_1_0.html
new file mode 100644
index 0000000..52c9cee
--- /dev/null
+++ b/misc/openlayers/tests/Format/WFST/v1_1_0.html
@@ -0,0 +1,236 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.WFST.v1_1_0({});
+ t.ok(format instanceof OpenLayers.Format.WFST.v1_1_0, "constructor returns instance");
+ }
+
+ function test_read(t) {
+ t.plan(3);
+
+ var data = readXML("TransactionResponse");
+ var format = new OpenLayers.Format.WFST.v1_1_0({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states"
+ });
+ var result = format.read(data);
+ t.eq(result.insertIds[0], "parcelle.40", "First InsertId read correctly");
+ t.eq(result.insertIds[1], "parcelle.41", "Second InsertId read correctly");
+ t.eq(result.success, true, "Success read correctly");
+ }
+
+ function test_read_hits(t) {
+ t.plan(1);
+ var data = readXML("NumberOfFeatures");
+ var format = new OpenLayers.Format.WFST.v1_1_0({
+ featureNS: "http://mapserver.gis.umn.edu/mapserver",
+ featureType: "AAA64"
+ });
+ var result = format.read(data, {output: "object"});
+ t.eq(result.numberOfFeatures, 625, "numberOfFeatures of FeatureCollection correctly read");
+ }
+
+ function test_read_boundedBy(t) {
+ t.plan(4);
+ var data = readXML("boundedBy");
+ var format = new OpenLayers.Format.WFST.v1_1_0({
+ featureNS: "http://mapserver.gis.umn.edu/mapserver",
+ featureType: "AAA212"
+ });
+ var result = format.read(data, {output: "object"});
+ var bounds = result.bounds;
+ t.eq(bounds.left.toFixed(3), '3197.880', "Left bounds of the feature collection correctly parsed");
+ t.eq(bounds.bottom.toFixed(3), '306457.313', "Bottom bounds of the feature collection correctly parsed");
+ t.eq(bounds.right.toFixed(3), '280339.156', "Right bounds of the feature collection correctly parsed");
+ t.eq(bounds.top.toFixed(3), '613850.438', "Top bounds of the feature collection corectly parsed");
+ }
+
+ function test_write(t) {
+
+ var format = new OpenLayers.Format.WFST.v1_1_0({
+ featureNS: "http://www.openplans.org/topp",
+ featureType: "states",
+ featurePrefix: "topp",
+ srsName: "urn:ogc:def:crs:EPSG::4326",
+ geometryName: "the_geom"
+ });
+
+ var cases = [{
+ id: "query0",
+ writer: "wfs:Query",
+ arg: {
+ filter: new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds (1,2,3,4)
+ })
+ }
+ }, {
+ id: "getfeature0",
+ writer: "wfs:GetFeature",
+ arg: {
+ resultType: "hits",
+ propertyNames: ["STATE_NAME", "STATE_FIPS", "STATE_ABBR"]
+ }
+ }, {
+ id: "getfeature1",
+ writer: "wfs:GetFeature",
+ arg: {
+ count: 10,
+ startIndex: 20
+ }
+ }];
+
+ t.plan(cases.length);
+
+ var test, got, exp;
+ for(var i=0; i<cases.length; ++i) {
+ test = cases[i];
+ exp = readXML(test.id);
+ got = format.writeNode(test.writer, test.arg);
+ t.xml_eq(got, exp, test.id + ": correct request");
+ }
+ }
+
+ function test_write_poorconfig(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.WFST.v1_1_0({
+ featureType: "states",
+ featurePrefix: "topp"
+ });
+ var exp = "topp:states";
+ var got = format.writeNode("wfs:Query").getAttribute("typeName");
+ t.eq(got, exp, "Query without featureNS but with featurePrefix queries for the correct featureType");
+ }
+
+ var xmlFormat = new OpenLayers.Format.XML();
+ function readXML(id) {
+ var xml = document.getElementById(id).firstChild.nodeValue;
+ return xmlFormat.read(xml).documentElement;
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="width:512px; height:256px"> </div>
+<div id="NumberOfFeatures"><!--
+<?xml version='1.0' encoding="ISO-8859-1" ?>
+<wfs:FeatureCollection
+ xmlns:rws="http://mapserver.gis.umn.edu/mapserver"
+ xmlns:gml="http://www.opengis.net/gml"
+ 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://mapserver.gis.umn.edu/mapserver http://intranet.rijkswaterstaat.nl/services/geoservices/nwb_wegen?SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=feature:AAA64&amp;OUTPUTFORMAT=text/xml; subtype=gml/3.1.1 http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" numberOfFeatures="625">
+</wfs:FeatureCollection>
+--></div>
+<div id="TransactionResponse"><!--
+<wfs:TransactionResponse version="1.1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:tiger="http://www.census.gov" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:sf="http://www.openplans.org/spearfish" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <wfs:TransactionSummary>
+ <wfs:totalInserted>0</wfs:totalInserted>
+ <wfs:totalUpdated>1</wfs:totalUpdated>
+ <wfs:totalDeleted>0</wfs:totalDeleted>
+ </wfs:TransactionSummary>
+ <wfs:TransactionResults/>
+ <wfs:InsertResults>
+ <wfs:Feature>
+ <ogc:FeatureId fid="parcelle.40"/>
+ </wfs:Feature>
+ <wfs:Feature>
+ <ogc:FeatureId fid="parcelle.41"/>
+ </wfs:Feature>
+ </wfs:InsertResults>
+</wfs:TransactionResponse>
+--></div>
+<div id="query0"><!--
+<wfs:Query xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" srsName="urn:ogc:def:crs:EPSG::4326" xmlns:topp="http://www.openplans.org/topp">
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:BBOX>
+ <ogc:PropertyName>the_geom</ogc:PropertyName>
+ <gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="urn:ogc:def:crs:EPSG::4326">
+ <gml:lowerCorner>1 2</gml:lowerCorner>
+ <gml:upperCorner>3 4</gml:upperCorner>
+ </gml:Envelope>
+ </ogc:BBOX>
+ </ogc:Filter>
+</wfs:Query>
+--></div>
+<div id="getfeature0"><!--
+<wfs:GetFeature service="WFS" version="1.1.0" resultType="hits" xmlns:topp="http://www.openplans.org/topp"
+ 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://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
+ <wfs:Query xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" srsName="urn:ogc:def:crs:EPSG::4326" xmlns:topp="http://www.openplans.org/topp">
+ <wfs:PropertyName>STATE_NAME</wfs:PropertyName>
+ <wfs:PropertyName>STATE_FIPS</wfs:PropertyName>
+ <wfs:PropertyName>STATE_ABBR</wfs:PropertyName>
+ </wfs:Query>
+</wfs:GetFeature>
+--></div>
+<div id="getfeature1"><!--
+<wfs:GetFeature service="WFS" version="1.1.0" startIndex="20" count="10" xmlns:topp="http://www.openplans.org/topp"
+ 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://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
+ <wfs:Query xmlns:wfs="http://www.opengis.net/wfs" typeName="topp:states" srsName="urn:ogc:def:crs:EPSG::4326" xmlns:topp="http://www.openplans.org/topp">
+ </wfs:Query>
+</wfs:GetFeature>
+--></div>
+<div id="boundedBy"><!--
+<?xml version='1.0' encoding="ISO-8859-1" ?>
+<wfs:FeatureCollection
+ xmlns:rws="http://mapserver.gis.umn.edu/mapserver"
+ xmlns:gml="http://www.opengis.net/gml"
+ 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://mapserver.gis.umn.edu/mapserver http://ontwikkel.intranet.rijkswaterstaat.nl/services/geoservices/ov_zonering?SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=AAA212&amp;OUTPUTFORMAT=text/xml; subtype=gml/3.1.1 http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
+ <gml:boundedBy>
+ <gml:Envelope srsName="EPSG:28992">
+ <gml:lowerCorner>3197.880000 306457.313000</gml:lowerCorner>
+ <gml:upperCorner>280339.156000 613850.438000</gml:upperCorner>
+ </gml:Envelope>
+ </gml:boundedBy>
+ <gml:featureMember>
+
+ <rws:AAA212 gml:id="AAA212.791">
+ <gml:boundedBy>
+ <gml:Envelope srsName="EPSG:28992">
+ <gml:lowerCorner>196507.469000 502347.938000</gml:lowerCorner>
+ <gml:upperCorner>202430.844000 510383.719000</gml:upperCorner>
+ </gml:Envelope>
+ </gml:boundedBy>
+ <rws:geometry>
+
+ <gml:MultiSurface srsName="EPSG:28992">
+ <gml:surfaceMembers>
+ <gml:Polygon>
+ <gml:exterior>
+ <gml:LinearRing>
+ <gml:posList srsDimension="2">200448.047000 510383.719000 198475.031000 509253.875000 198477.422000 507339.688000 196507.469000 505841.969000 196507.625000 504980.281000 196621.359000 505029.969000 196825.328000 505114.000000 197310.031000 505183.469000 197636.609000 505148.750000 197837.594000 505061.563000 197941.031000 504953.688000 198003.094000 504817.719000 198023.781000 504721.688000 198016.391000 504597.531000 197907.234000 504363.219000 197716.734000 504013.969000 197700.156000 503567.563000 197775.531000 503373.969000 197930.688000 503153.781000 198034.234000 503045.594000 198170.078000 502932.125000 198504.047000 502725.250000 198858.719000 502550.875000 199138.000000 502460.719000 199336.000000 502347.938000 199044.125000 504910.969000 199549.359000 507065.781000 200280.594000 506878.938000 202430.844000 507474.625000 202430.844000 508850.906000 200448.047000 510383.719000 </gml:posList>
+ </gml:LinearRing>
+ </gml:exterior>
+
+ </gml:Polygon>
+ </gml:surfaceMembers>
+ </gml:MultiSurface>
+ </rws:geometry>
+ <rws:OBJECTID>791</rws:OBJECTID>
+ <rws:HECTARES>1800.89</rws:HECTARES>
+ <rws:ZONENR>4620</rws:ZONENR>
+
+ <rws:NULZONES> </rws:NULZONES>
+ <rws:AREA>0</rws:AREA>
+ <rws:PERIMETER>24305.1</rws:PERIMETER>
+ </rws:AAA212>
+ </gml:featureMember>
+</wfs:FeatureCollection>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WKT.html b/misc/openlayers/tests/Format/WKT.html
new file mode 100644
index 0000000..bdfc233
--- /dev/null
+++ b/misc/openlayers/tests/Format/WKT.html
@@ -0,0 +1,297 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var points = [];
+ for(var i=0; i<12; ++i) {
+ points.push(new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(Math.random() * 100,
+ Math.random() * 100))
+ );
+ }
+ var multipoint = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.MultiPoint([
+ points[0].geometry,
+ points[1].geometry,
+ points[2].geometry
+ ])
+ );
+
+ var linestrings = [
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.LineString([
+ points[0].geometry,
+ points[1].geometry,
+ points[2].geometry
+ ])
+ ),
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.LineString([
+ points[3].geometry,
+ points[4].geometry,
+ points[5].geometry
+ ])
+ )
+ ];
+
+ var multilinestring = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.MultiLineString([
+ linestrings[0].geometry,
+ linestrings[1].geometry
+ ])
+ );
+
+ var rings = [
+ new OpenLayers.Geometry.LinearRing([
+ points[0].geometry,
+ points[1].geometry,
+ points[2].geometry
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ points[3].geometry,
+ points[4].geometry,
+ points[5].geometry
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ points[6].geometry,
+ points[7].geometry,
+ points[8].geometry
+ ]),
+ new OpenLayers.Geometry.LinearRing([
+ points[9].geometry,
+ points[10].geometry,
+ points[11].geometry
+ ])
+ ];
+
+ var polygons = [
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Polygon([rings[0], rings[1]])
+ ),
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Polygon([rings[2], rings[3]])
+ )
+ ];
+
+ var multipolygon = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.MultiPolygon([
+ polygons[0].geometry,
+ polygons[1].geometry
+ ])
+ );
+
+ var collection = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Collection([
+ points[0].geometry,
+ linestrings[0].geometry
+ ])
+ );
+
+ var geom_array = [points[0], linestrings[0]];
+
+ function test_Format_WKT_constructor(t) {
+ t.plan(4);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.WKT(options);
+ t.ok(format instanceof OpenLayers.Format.WKT,
+ "new OpenLayers.Format.WKT returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+ }
+
+ function test_Format_WKT_write(t) {
+ t.plan(8);
+
+ var format = new OpenLayers.Format.WKT();
+
+ // test a point
+
+ t.eq(format.write(points[0]),
+ "POINT(" + points[0].geometry.x + " " + points[0].geometry.y + ")",
+ "format correctly writes Point WKT");
+
+ // test a multipoint
+ t.eq(format.write(multipoint),
+ "MULTIPOINT((" + points[0].geometry.x + " " + points[0].geometry.y + "),(" +
+ points[1].geometry.x + " " + points[1].geometry.y + "),(" +
+ points[2].geometry.x + " " + points[2].geometry.y + "))",
+ "format correctly writes MultiPoint WKT");
+
+ // test a linestring
+ t.eq(format.write(linestrings[0]),
+ "LINESTRING(" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + ")",
+ "format correctly writes LineString WKT");
+
+ // test a multilinestring
+ t.eq(format.write(multilinestring),
+ "MULTILINESTRING((" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + ")," +
+ "(" + points[3].geometry.x + " " + points[3].geometry.y + "," +
+ points[4].geometry.x + " " + points[4].geometry.y + "," +
+ points[5].geometry.x + " " + points[5].geometry.y + "))",
+ "format correctly writes MultiLineString WKT");
+
+ // test a polygon
+ t.eq(format.write(polygons[0]),
+ "POLYGON((" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + "," +
+ points[0].geometry.x + " " + points[0].geometry.y + ")," +
+ "(" + points[3].geometry.x + " " + points[3].geometry.y + "," +
+ points[4].geometry.x + " " + points[4].geometry.y + "," +
+ points[5].geometry.x + " " + points[5].geometry.y + "," +
+ points[3].geometry.x + " " + points[3].geometry.y + "))",
+ "format correctly writes Polygon WKT");
+
+ // test a multipolygon
+ t.eq(format.write(multipolygon),
+ "MULTIPOLYGON(((" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + "," +
+ points[0].geometry.x + " " + points[0].geometry.y + ")," +
+ "(" + points[3].geometry.x + " " + points[3].geometry.y + "," +
+ points[4].geometry.x + " " + points[4].geometry.y + "," +
+ points[5].geometry.x + " " + points[5].geometry.y + "," +
+ points[3].geometry.x + " " + points[3].geometry.y + "))," +
+ "((" + points[6].geometry.x + " " + points[6].geometry.y + "," +
+ points[7].geometry.x + " " + points[7].geometry.y + "," +
+ points[8].geometry.x + " " + points[8].geometry.y + "," +
+ points[6].geometry.x + " " + points[6].geometry.y + ")," +
+ "(" + points[9].geometry.x + " " + points[9].geometry.y + "," +
+ points[10].geometry.x + " " + points[10].geometry.y + "," +
+ points[11].geometry.x + " " + points[11].geometry.y + "," +
+ points[9].geometry.x + " " + points[9].geometry.y + ")))",
+ "format correctly writes MultiPolygon WKT");
+
+ // test geometrycollection
+ t.eq(format.write(collection),
+ "GEOMETRYCOLLECTION(POINT(" + points[0].geometry.x + " " + points[0].geometry.y + ")," +
+ "LINESTRING(" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + "))",
+ "format correctly writes GeometryCollection WKT");
+
+ // test writing an array of geometries
+ t.eq(format.write(geom_array),
+ "GEOMETRYCOLLECTION(POINT(" + points[0].geometry.x + " " + points[0].geometry.y + ")," +
+ "LINESTRING(" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + "))",
+ "format correctly writes WKT for an array of Geometries");
+
+ }
+
+ function test_Format_WKT_read(t) {
+ t.plan(13);
+
+ var format = new OpenLayers.Format.WKT();
+
+ /**
+ * Since we're explicitly testing calls to write, the read tests
+ * just make sure that geometry can make a round trip from read to write.
+ */
+
+ // test a point
+ t.ok(points[0].geometry.equals(format.read(format.write(points[0])).geometry),
+ "format correctly reads Point WKT");
+
+ // test a multipoint
+ t.ok(multipoint.geometry.equals(format.read(format.write(multipoint)).geometry),
+ "format correctly reads MultiPoint WKT");
+
+ // test a multipoint without separating parens
+ t.ok(multipoint.geometry.equals(format.read(
+ "MULTIPOINT(" + points[0].geometry.x + " " + points[0].geometry.y + "," +
+ points[1].geometry.x + " " + points[1].geometry.y + "," +
+ points[2].geometry.x + " " + points[2].geometry.y + ")").geometry),
+ "format correctly reads MultiPoint WKT without parens");
+
+ // test a linestring
+ t.ok(linestrings[0].geometry.equals(format.read(format.write(linestrings[0])).geometry),
+ "format correctly reads LineString WKT");
+
+ // test a multilinestring
+ t.ok(multilinestring.geometry.equals(format.read(format.write(multilinestring)).geometry),
+ "format correctly reads MultiLineString WKT");
+
+ // test a polygon
+ t.ok(polygons[0].geometry.equals(format.read(format.write(polygons[0])).geometry),
+ "format correctly reads Polygon WKT");
+
+ // test a multipolygon
+ t.ok(multipolygon.geometry.equals(format.read(format.write(multipolygon)).geometry),
+ "format correctly reads MultiPolygon WKT");
+
+ // test a collection
+ var wkt = format.write(collection);
+ var got = format.read(wkt);
+ t.ok(got instanceof Array, "by default, reading a collection returns an array");
+ t.eq(got.length, 2, "read two items");
+ t.ok(got[0] instanceof OpenLayers.Feature.Vector, "first item is a feature");
+ t.geom_eq(got[0].geometry, points[0].geometry, "first feature's geometry is the correct point");
+ t.ok(got[1] instanceof OpenLayers.Feature.Vector, "second item is a feature");
+ t.geom_eq(got[1].geometry, linestrings[0].geometry, "second feature's geometry is the correct linestring");
+
+ }
+
+ function test_whitespace(t) {
+ t.plan(3);
+ var wkt = "LINESTRING(7.120068\t43.583917,\n7.120154 43.583652,\n7.120385\t43.582716,\r\n7.12039 43.582568, 7.120712 43.581511,7.120873\n43.580718)";
+ var format = new OpenLayers.Format.WKT();
+ var got = format.read(wkt);
+ t.ok(got instanceof OpenLayers.Feature.Vector, "read a feature");
+ t.ok(got.geometry instanceof OpenLayers.Geometry.LineString, "read a linestring");
+ t.ok(got.geometry.components.length, 6, "read a geometry with 6 components");
+ }
+
+ function test_Format_WKT_read_projection(t) {
+ t.plan(1);
+
+ var projections = {
+ src: new OpenLayers.Projection("EPSG:4326"),
+ dest: new OpenLayers.Projection("EPSG:900913")
+ },
+ points = {
+ src: new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(-87.9, 41.9)
+ ),
+ dest: new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(-9784983.2393667, 5146011.6785665)
+ )
+ },
+ format = new OpenLayers.Format.WKT({
+ externalProjection: projections["src"],
+ internalProjection: projections["dest"]
+ }),
+ gc_wkt_parts = [
+ "GEOMETRYCOLLECTION(",
+ "POINT(",
+ points["src"].geometry.x,
+ " ",
+ points["src"].geometry.y,
+ ")",
+ ")"
+ ],
+ feature = format.read( gc_wkt_parts.join("") )[0],
+ gotGeom = feature.geometry,
+ expectGeom = points["dest"].geometry,
+ // we don't use geometry::toString because we might run into
+ // precision issues
+ precision = 7,
+ got = gotGeom.x.toFixed(precision) + ' ' + gotGeom.y.toFixed(precision),
+ expected = expectGeom.x.toFixed(precision) + ' ' + expectGeom.y.toFixed(precision);
+
+ t.eq(got, expected,
+ "Geometry collections aren't transformed twice when reprojection.");
+ }
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMC.html b/misc/openlayers/tests/Format/WMC.html
new file mode 100644
index 0000000..fbaec81
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMC.html
@@ -0,0 +1,315 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var v1_0_0 = '<ViewContext xmlns="http://www.opengis.net/context" version="1.0.0" id="OpenLayers_Context_233" xsi:schemaLocation="http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><Window width="512" height="256"/><BoundingBox minx="-109.9709708" miny="27.01451459" maxx="-80.02902918" maxy="41.98548541" SRS="EPSG:4326"/><Title/><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-130.0000000" miny="14.00000000" maxx="-60.00000000" maxy="55.00000000"/></Extension></General><LayerList><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://t1.hypercube.telascience.org/cgi-bin/landsat7"/></Server><Name>landsat7</Name><Title>NASA Global Mosaic</Title><FormatList><Format current="1">image/jpeg</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-130.0000000" miny="14.00000000" maxx="-60.00000000" maxy="55.00000000"/><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">false</ol:singleTile><ol:tileSize xmlns:ol="http://openlayers.org/context" width="512" height="1024"/></Extension></Layer><Layer queryable="1" hidden="1"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://labs.metacarta.com/wms/vmap0"/></Server><Name>basic</Name><Title>OpenLayers WMS</Title><FormatList><Format current="1">image/jpeg</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-130.0000000" miny="14.00000000" maxx="-60.00000000" maxy="55.00000000"/><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">false</ol:singleTile></Extension></Layer><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://lioapp.lrc.gov.on.ca/cubeserv/cubeserv.pl"/></Server><Name>na_road:CCRS</Name><Title>Transportation Network</Title><FormatList><Format current="1">image/png</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-166.5320000" miny="4.050460000" maxx="-0.2068180000" maxy="70.28700000"/><ol:transparent xmlns:ol="http://openlayers.org/context">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">false</ol:isBaseLayer><ol:opacity xmlns:ol="http://openlayers.org/context">0.6</ol:opacity><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">false</ol:singleTile></Extension></Layer><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://columbo.nrlssc.navy.mil/ogcwms/servlet/WMSServlet/AccuWeather_Maps.wms"/></Server><Name>3:1</Name><Title>Radar 3:1</Title><FormatList><Format current="1">image/png</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-131.0294952" miny="14.56289673" maxx="-61.02950287" maxy="54.56289673"/><ol:transparent xmlns:ol="http://openlayers.org/context">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">false</ol:isBaseLayer><ol:opacity xmlns:ol="http://openlayers.org/context">0.8</ol:opacity><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">true</ol:singleTile></Extension></Layer></LayerList></ViewContext>';
+ var v1_1_0 = '<ViewContext xmlns="http://www.opengis.net/context" version="1.1.0" id="OpenLayers_Context_232" xsi:schemaLocation="http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><General><Window width="512" height="256"/><BoundingBox minx="-109.9709708" miny="27.01451459" maxx="-80.02902918" maxy="41.98548541" SRS="EPSG:4326"/><Title/><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-130.0000000" miny="14.00000000" maxx="-60.00000000" maxy="55.00000000"/></Extension></General><LayerList><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://t1.hypercube.telascience.org/cgi-bin/landsat7"/></Server><Name>landsat7</Name><Title>NASA Global Mosaic</Title><sld:MinScaleDenominator xmlns:sld="http://www.opengis.net/sld">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld="http://www.opengis.net/sld">31498228.80</sld:MaxScaleDenominator><FormatList><Format current="1">image/jpeg</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-130.0000000" miny="14.00000000" maxx="-60.00000000" maxy="55.00000000"/><ol:tileSize xmlns:ol="http://openlayers.org/context" width="512" height="1024"/><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">false</ol:singleTile></Extension></Layer><Layer queryable="1" hidden="1"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://labs.metacarta.com/wms/vmap0"/></Server><Name>basic</Name><Title>OpenLayers WMS</Title><sld:MinScaleDenominator xmlns:sld="http://www.opengis.net/sld">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld="http://www.opengis.net/sld">31498228.80</sld:MaxScaleDenominator><FormatList><Format current="1">image/jpeg</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-130.0000000" miny="14.00000000" maxx="-60.00000000" maxy="55.00000000"/><ol:tileSize xmlns:ol="http://openlayers.org/context" width="512" height="1024"/><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">false</ol:singleTile></Extension></Layer><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://lioapp.lrc.gov.on.ca/cubeserv/cubeserv.pl"/></Server><Name>na_road:CCRS</Name><Title>Transportation Network</Title><sld:MinScaleDenominator xmlns:sld="http://www.opengis.net/sld">6200000.000</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld="http://www.opengis.net/sld">32000000.00</sld:MaxScaleDenominator><FormatList><Format current="1">image/png</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-166.5320000" miny="4.050460000" maxx="-0.2068180000" maxy="70.28700000"/><ol:tileSize xmlns:ol="http://openlayers.org/context" width="512" height="1024"/><ol:transparent xmlns:ol="http://openlayers.org/context">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">false</ol:isBaseLayer><ol:opacity xmlns:ol="http://openlayers.org/context">0.6</ol:opacity><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">false</ol:singleTile></Extension></Layer><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1"><OnlineResource xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://columbo.nrlssc.navy.mil/ogcwms/servlet/WMSServlet/AccuWeather_Maps.wms"/></Server><Name>3:1</Name><Title>Radar 3:1</Title><sld:MinScaleDenominator xmlns:sld="http://www.opengis.net/sld">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld="http://www.opengis.net/sld">31498228.80</sld:MaxScaleDenominator><FormatList><Format current="1">image/png</Format></FormatList><StyleList><Style current="1"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol="http://openlayers.org/context" minx="-131.0294952" miny="14.56289673" maxx="-61.02950287" maxy="54.56289673"/><ol:transparent xmlns:ol="http://openlayers.org/context">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol="http://openlayers.org/context">4</ol:numZoomLevels><ol:units xmlns:ol="http://openlayers.org/context">degrees</ol:units><ol:isBaseLayer xmlns:ol="http://openlayers.org/context">false</ol:isBaseLayer><ol:opacity xmlns:ol="http://openlayers.org/context">0.8</ol:opacity><ol:displayInLayerSwitcher xmlns:ol="http://openlayers.org/context">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol="http://openlayers.org/context">true</ol:singleTile></Extension></Layer></LayerList></ViewContext>';
+ var polar = '<ViewContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:default="http://www.opengis.net/context" xmlns:ol="http://openlayers.org/context" xmlns="http://www.opengis.net/context" xmlns:wms="http://www.opengis.net/wms" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1.0" id="OpenLayers_Context_466" xsi:schemaLocation="http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd"><General><BoundingBox minx="-3000000" miny="-3000000" maxx="7000000" maxy="7000000" SRS="EPSG:32661"/><Title>WMS viewer</Title><Extension><ol:maxExtent minx="-3000000" miny="-3000000" maxx="7000000" maxy="7000000"/><ol:units>m</ol:units></Extension></General><LayerList xmlns="http://www.opengis.net/context"><Layer queryable="0" hidden="0"><Server service="OGC:WMS" version="1.1.1" foo="bar"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://wms.met.no/maps/northpole.map"/></Server><Name>world</Name><Title>The World</Title><FormatList><Format>image/jpeg</Format><Format current="1">image/png</Format></FormatList></Layer></LayerList></ViewContext>';
+ var fulldoc = '<ViewContext xmlns="http://www.opengis.net/context" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sld="http://www.opengis.net/sld" version="1.1.0" id="eos_data_gateways" xsi:schemaLocation="http://www.opengis.net/context context.xsd"><General><Window width="500" height="300"/><BoundingBox SRS="EPSG:4326" minx="-180.000000" miny="-90.000000" maxx="180.000000" maxy="90.000000"/><Title>EOS Data Gateways</Title><KeywordList><Keyword>EOS</Keyword><Keyword>EOSDIS</Keyword><Keyword>NASA</Keyword><Keyword>CCRS</Keyword><Keyword>CEOS</Keyword><Keyword>OGC</Keyword></KeywordList><Abstract>Map View of EOSDIS partners locations</Abstract><LogoURL width="130" height="74" format="image/gif"><OnlineResource xlink:type="simple" xlink:href="http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif"/></LogoURL><DescriptionURL format="text/html"><OnlineResource xlink:type="simple" xlink:href="http://eos.nasa.gov/imswelcome"/></DescriptionURL><ContactInformation><ContactPersonPrimary><ContactPerson>Tom Kralidis</ContactPerson><ContactOrganization>Environment Canada</ContactOrganization></ContactPersonPrimary><ContactPosition>Systems Scientist</ContactPosition><ContactAddress><AddressType>postal</AddressType><Address>867 Lakeshore Road</Address><City>Burlington</City><StateOrProvince>Ontario</StateOrProvince><PostCode>L7R 4A6</PostCode><Country>Canada</Country></ContactAddress><ContactVoiceTelephone>+01-905-336-4409</ContactVoiceTelephone><ContactFacsimileTelephone>+01-905-336-4499</ContactFacsimileTelephone><ContactElectronicMailAddress>tom.kralidis@ec.gc.ca</ContactElectronicMailAddress></ContactInformation></General><LayerList><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1" title="ESA CubeSERV"><OnlineResource xlink:type="simple" xlink:href="http://mapserv2.esrin.esa.it/cubestor/cubeserv/cubeserv.cgi"/></Server><Name>WORLD_MODIS_1KM:MapAdmin</Name><Title>WORLD_MODIS_1KM</Title><Abstract>Global maps derived from various Earth Observation sensors / WORLD_MODIS_1KM:MapAdmin</Abstract><SRS>EPSG:4326</SRS><FormatList><Format current="1">image/png</Format><Format>image/gif</Format><Format>image/jpeg</Format></FormatList><StyleList><Style current="1"><Name>default</Name><Title>default</Title><LegendURL width="16" height="16" format="image/gif"><OnlineResource xlink:type="simple" xlink:href="http://mapserv2.esrin.esa.it/cubestor/cubeserv/cubeserv.cgi?version=1.1.1&amp;request=GetLegendGraphic&amp;layer=WORLD_MODIS_1KM:MapAdmin&amp;style=default&amp;format=image/gif"/></LegendURL></Style></StyleList></Layer><Layer queryable="0" hidden="0"><Server service="OGC:WMS" version="1.1.1" title="The GLOBE Program Visualization Server"><OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/viz-bin/wmt.cgi"/></Server><Name>COASTLINES</Name><Title>Coastlines</Title><Abstract>Context layer: Coastlines</Abstract><SRS>EPSG:4326</SRS><SRS>EPSG:900913</SRS><FormatList><Format current="1">image/gif</Format><Format>image/png</Format></FormatList><StyleList><Style current="1"><Name>default</Name><Title>Default</Title><LegendURL width="180" format="image/gif" height="50"><OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/COASTLINES.gif"/></LegendURL></Style></StyleList><DimensionList><Dimension name="time" units="ISO8601" nearestValue="1">2011-03-31,2011-04-01</Dimension></DimensionList></Layer><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1" title="The GLOBE Program Visualization Server"><OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/viz-bin/wmt.cgi"/></Server><Name>NATIONAL</Name><Title>National Boundaries</Title><Abstract>Context layer: National Boundaries</Abstract><DataURL><OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/data/national.gml"/></DataURL><MetadataURL><OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/metadata/national.txt"/></MetadataURL><SRS>EPSG:4326</SRS><FormatList><Format current="1">image/gif</Format><Format>image/png</Format></FormatList><StyleList><Style current="1"><Name>default</Name><Title>Default</Title><LegendURL width="180" format="image/gif" height="50"><OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/></LegendURL></Style></StyleList></Layer><Layer queryable="1" hidden="0"><Server service="OGC:WMS" version="1.1.1" title="Canada Centre for Remote Sensing Web Map Service"><OnlineResource xlink:type="simple" xlink:href="http://ceoware2.ccrs.nrcan.gc.ca/cubewerx/cubeserv/cubeserv.cgi"/></Server><Name>EOS_DATA_GATEWAYS:CEOWARE2</Name><Title>EOS Data Gateways</Title><Abstract>Locations of EOS Data Gateway Locations. The same services and data are available through each gateway location.</Abstract><sld:MinScaleDenominator>1000</sld:MinScaleDenominator><sld:MaxScaleDenominator>500000</sld:MaxScaleDenominator><SRS>EPSG:4326</SRS><FormatList><Format current="1">image/gif</Format><Format>image/png</Format><Format>image/jpeg</Format></FormatList><StyleList><Style current="1"><Name>default</Name><Title>default</Title><LegendURL width="16" height="16" format="image/gif"><OnlineResource xlink:type="simple" xlink:href="http://ceoware2.ccrs.nrcan.gc.ca/cubewerx/cubeserv/cubeserv.cgi?version=1.1.1&amp;request=GetLegendGraphic&amp;layer=EOS_DATA_GATEWAYS:CEOWARE2&amp;style=default&amp;format=image/gif"/></LegendURL></Style><Style><SLD><Title>Default</Title><sld:StyledLayerDescriptor xmlns:ogc="http://www.opengis.net/ogc" xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd"><sld:NamedLayer><sld:Name>AAA212</sld:Name><sld:UserStyle><sld:FeatureTypeStyle><sld:Rule><sld:TextSymbolizer><sld:Label><ogc:PropertyName>ZONENR</ogc:PropertyName></sld:Label><sld:Font><sld:CssParameter name="font-family">Arial</sld:CssParameter><sld:CssParameter name="font-size">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name="fill">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor></SLD></Style><Style><SLD><Title>Default</Title><sld:FeatureTypeStyle xmlns:ogc="http://www.opengis.net/ogc" xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd"><sld:Rule><sld:TextSymbolizer><sld:Label><PropertyName>ZONENR</PropertyName></sld:Label><sld:Font><sld:CssParameter name="font-family">Arial</sld:CssParameter><sld:CssParameter name="font-size">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name="fill">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle></SLD></Style></StyleList></Layer></LayerList></ViewContext>';
+
+ function test_Format_WMC_read(t) {
+ t.plan(64);
+
+ var format = new OpenLayers.Format.WMC();
+ var map, layer;
+
+ // test v1.0.0
+ map = format.read(v1_0_0, {map: "map"});
+ t.eq(map.center.lon.toPrecision(6), (-95).toPrecision(6), "(v1.0.0) map center correctly set");
+ t.eq(map.center.lat.toPrecision(6), (34.5).toPrecision(6), "(v1.0.0) map center correctly set");
+ t.eq(map.maxExtent.left.toPrecision(6), (-130).toPrecision(6), "(v1.0.0) map maxExtent correctly set");
+ t.eq(map.layers.length, 4, "(v1.0.0) correct number of layers");
+ t.eq(map.projection, "EPSG:4326", "(v1.0.0) map projection set correctly");
+ // check out first base layer
+ layer = map.layers[0];
+ t.eq(layer.queryable, true, "(1.0.0) Layer is queryable");
+ t.ok(layer instanceof OpenLayers.Layer.WMS,
+ "(v1.0.0) wms layer correctly instantiated");
+ t.eq(layer.url, "http://t1.hypercube.telascience.org/cgi-bin/landsat7",
+ "(v1.0.0) layer url correctly set");
+ t.eq(layer.maxExtent.right.toPrecision(6), (-60).toPrecision(6),
+ "(v1.0.0) layer maxExtent correctly set");
+ t.eq(layer.numZoomLevels, 4,
+ "(v1.0.0) layer numZoomLevels correctly set");
+ t.eq(layer.isBaseLayer, true,
+ "(v1.0.0) layer isBaseLayer correctly set for base layer");
+ t.eq(layer.tileSize.w, 512,
+ "(v1.0.0) layer tileSize width correctly set");
+ t.eq(layer.tileSize.h, 1024,
+ "(v1.0.0) layer tileSize height correctly set");
+ // check out layer not in switcher
+ layer = map.layers[2];
+ t.eq(layer.displayInLayerSwitcher, false,
+ "(v1.0.0) layer displayInLayerSwitcher correctly set");
+ t.eq(layer.params["TRANSPARENT"], "TRUE",
+ "(v1.0.0) layer param.transparent correctly set");
+ t.eq(layer.isBaseLayer, false,
+ "(v1.0.0) layer isBaseLayer correctly set for overlay");
+ // check out single tile overlay
+ layer = map.layers[3];
+ t.eq(layer.singleTile, true,
+ "(v1.0.0) layer singleTile correctly set");
+ t.eq(layer.opacity, 0.8,
+ "(v1.0.0) layer opacity correctly set");
+ map.destroy();
+
+ // test v1.1.0
+ map = format.read(v1_1_0, {map: "map"});
+ t.eq(map.center.lon.toPrecision(6), (-95).toPrecision(6), "(v1.1.0) map center correctly set");
+ t.eq(map.center.lat.toPrecision(6), (34.5).toPrecision(6), "(v1.1.0) map center correctly set");
+ t.eq(map.maxExtent.left.toPrecision(6), (-130).toPrecision(6), "(v1.1.0) map maxExtent correctly set");
+ t.eq(map.layers.length, 4, "(v1.1.0) correct number of layers");
+ t.eq(map.projection, "EPSG:4326", "(v1.1.0) map projection set correctly");
+ // check out first baseLayer
+ layer = map.layers[0];
+ t.ok(layer instanceof OpenLayers.Layer.WMS,
+ "(v1.1.0) wms layer correctly instantiated");
+ t.eq(layer.url, "http://t1.hypercube.telascience.org/cgi-bin/landsat7",
+ "(v1.1.0) layer url correctly set");
+ t.eq(layer.maxExtent.right.toPrecision(6), (-60).toPrecision(6),
+ "(v1.1.0) layer maxExtent correctly set");
+ t.eq(layer.numZoomLevels, 4,
+ "(v1.1.0) layer numZoomLevels correctly set");
+ t.eq(layer.isBaseLayer, true,
+ "(v1.1.0) layer isBaseLayer correctly set for overlay");
+ // check out layer not in switcher
+ layer = map.layers[2];
+ t.eq(layer.displayInLayerSwitcher, false,
+ "(v1.1.0) layer displayInLayerSwitcher correctly set");
+ t.eq(layer.params["TRANSPARENT"], "TRUE",
+ "(v1.1.0) layer param.transparent correctly set");
+ t.eq(layer.isBaseLayer, false,
+ "(v1.1.0) layer isBaseLayer correctly set for overlay");
+ t.eq(layer.minScale.toPrecision(6), (32000000).toPrecision(6),
+ "(v1.1.0) layer minScale correctly set");
+ t.eq(layer.maxScale.toPrecision(6), (6200000).toPrecision(6),
+ "(v1.1.0) layer maxScale correctly set");
+ // check out single tile overlay
+ layer = map.layers[3];
+ t.eq(layer.singleTile, true,
+ "(v1.1.0) layer singleTile correctly set");
+ t.eq(layer.opacity, 0.8,
+ "(v1.1.0) layer opacity correctly set");
+ map.destroy();
+
+ // Check if maxResolution is set correctly
+ map = format.read(polar, {map: "map"});
+ t.eq(map.maxResolution, 39062.5,
+ "maxResolution correctly set");
+ map.destroy();
+
+ // test mapOptions
+ map = format.read(v1_1_0, {map: {foo: 'bar', div: 'map'}});
+ t.eq(map.foo, "bar",
+ "mapOptions correctly passed to the created map object");
+ map.destroy();
+
+ map = format.read(fulldoc, {map: "map"});
+
+ var meta = map.metadata;
+
+ // Check if ContextInformation is set properly
+ var cinfo = meta.contactInformation;
+
+ t.eq(cinfo.personPrimary.person, "Tom Kralidis", "got correct person");
+ t.eq(cinfo.personPrimary.organization, "Environment Canada", "got correct organization");
+
+ t.eq(cinfo.contactAddress.address, "867 Lakeshore Road", "got correct address");
+ t.eq(cinfo.contactAddress.city, "Burlington", "got correct city");
+ t.eq(cinfo.contactAddress.country, "Canada", "got correct country");
+ t.eq(cinfo.contactAddress.postcode, "L7R 4A6", "got correct postcode");
+ t.eq(cinfo.contactAddress.stateOrProvince, "Ontario", "got correct stateOrProvince");
+ t.eq(cinfo.contactAddress.type, "postal", "got correct address type");
+
+ t.eq(cinfo.email, "tom.kralidis@ec.gc.ca", "got correct email");
+ t.eq(cinfo.fax, "+01-905-336-4499", "got correct fax number");
+ t.eq(cinfo.phone, "+01-905-336-4409", "got correct phone number");
+ t.eq(cinfo.position, "Systems Scientist", "got correct position");
+
+ // Check if LogoURL is read properly
+ var logo = meta.logo;
+ t.eq(logo, {
+ href: "http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif",
+ width: "130",
+ height: "74",
+ format: "image/gif"},
+ "got currect logo");
+
+ t.eq(meta.descriptionURL, "http://eos.nasa.gov/imswelcome", "got correct descriptionURL");
+
+ t.eq(meta.keywords,
+ ["EOS", "EOSDIS", "NASA", "CCRS", "CEOS", "OGC"],
+ "got correct keywords");
+
+ layer = map.layers[1];
+
+ t.eq(layer.metadata.servertitle,
+ "The GLOBE Program Visualization Server",
+ "got correct title for server");
+
+ t.eq(layer.srs,
+ {"EPSG:4326": true, "EPSG:900913": true},
+ "SRS read correctly");
+
+ t.eq(layer.metadata.formats,
+ [{value: "image/gif", current: true},
+ {value: "image/png"}],
+ "formats read correctly");
+
+ var style = layer.metadata.styles[0];
+ t.eq(style.legend, {
+ href: "http://globe.digitalearth.gov/globe/en/icons/colorbars/COASTLINES.gif",
+ width: "180",
+ height: "50",
+ format: "image/gif"},
+ "got currect legend");
+
+
+ var dim = layer.dimensions["time"];
+ t.eq(dim.name, "time", "got correct name of dimension");
+ t.eq(dim.units, "ISO8601", "got correct units for dimension");
+ t.eq(dim.nearestValue, true, "got correct value for nearestValue");
+ t.eq(dim.values, ["2011-03-31", "2011-04-01"], "got correct values for dimension");
+
+ layer = map.layers[2];
+ t.eq(layer.metadata.dataURL,
+ "http://globe.digitalearth.gov/data/national.gml",
+ "got correct dataURL");
+ t.eq(layer.metadataURL,
+ "http://globe.digitalearth.gov/metadata/national.txt",
+ "got correct metadataURL");
+
+ layer = map.layers[3];
+ var sld_body = '<sld:StyledLayerDescriptor xmlns:ogc="http://www.opengis.net/ogc" xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd"><sld:NamedLayer><sld:Name>AAA212</sld:Name><sld:UserStyle><sld:FeatureTypeStyle><sld:Rule><sld:TextSymbolizer><sld:Label><ogc:PropertyName>ZONENR</ogc:PropertyName></sld:Label><sld:Font><sld:CssParameter name="font-family">Arial</sld:CssParameter><sld:CssParameter name="font-size">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name="fill">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';
+ var styles = layer.metadata.styles;
+ t.xml_eq(styles[1].body, sld_body, "StyledLayerDescriptor body read correctly");
+
+ sld_body = '<sld:FeatureTypeStyle xmlns:ogc="http://www.opengis.net/ogc" xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd"><sld:Rule><sld:TextSymbolizer><sld:Label><PropertyName xmlns="http://www.opengis.net/context">ZONENR</PropertyName></sld:Label><sld:Font><sld:CssParameter name="font-family">Arial</sld:CssParameter><sld:CssParameter name="font-size">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name="fill">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle>';
+ t.xml_eq(styles[2].body, sld_body, "FeatureTypeStyle body read correctly");
+
+ }
+
+ function test_Format_WMC_write(t) {
+
+ var format = new OpenLayers.Format.WMC();
+ var map = format.read(v1_1_0, {map: "map"});
+ var wmc;
+
+ function sanitize(str) {
+ // id is unique so we don't expect it to be the same
+ str = str.replace(/OpenLayers_Context_\d+/, "foo");
+ // FF and IE differ on ordering of attribute nodes
+ // a better way to compare xml would be nice
+ str = str.replace(/\s*xsi:schemaLocation=".*?"/, "");
+ str = str.replace(/\s*xmlns:xlink=".*?"/g, "");
+ // and of course floating point precision is an issue
+ str = str.replace(/(-?\d+\.\d+)/g, function(m) {return parseFloat(m).toPrecision(6)});
+ return str;
+ }
+
+ /**
+ * Version 1.0.0 doesn't make the round trip because min/max resolutions
+ * are not stored. Version 1.1.0 introduced minScaleDenominator and
+ * maxScaleDenominator. The parser still writes valid WMC v1.0.0, you
+ * just need a validator to prove it.
+ *
+ * The wmc.html example can be used to produce WMC docs for validation.
+ * Prior to validation, the Extension tags need to be removed unless someone
+ * cares to write and maintain some XSD. Both version 1.0.0 and 1.1.0
+ * validate on http://www.validome.org/xml/.
+ */
+
+ // test v1.1.0
+ if(OpenLayers.BROWSER_NAME== "opera") {
+ t.plan(0);
+ t.debug_print("WMC writing works but is not tested in Opera");
+ } else {
+ t.plan(11);
+
+ map = format.read(v1_1_0, {map: "map"});
+ wmc = format.write(map);
+ t.eq(sanitize(wmc), sanitize(v1_1_0),
+ "(v1.1.0) write gives what read got");
+ map.destroy();
+
+ var parser = format.getParser("1.1.0");
+ map = format.read(fulldoc, {map: "map"});
+ var context = format.toContext(map);
+
+ // KeywordList
+ var expected = '<KeywordList xmlns="http://www.opengis.net/context"><Keyword>EOS</Keyword><Keyword>EOSDIS</Keyword><Keyword>NASA</Keyword><Keyword>CCRS</Keyword><Keyword>CEOS</Keyword><Keyword>OGC</Keyword></KeywordList>';
+ t.xml_eq(parser.write_wmc_KeywordList(context.keywords),
+ expected,
+ "keywordlist written correctly");
+
+ // ContactInformation
+ expected = '<ContactInformation xmlns="http://www.opengis.net/context"><ContactPersonPrimary><ContactPerson>Tom Kralidis</ContactPerson><ContactOrganization>Environment Canada</ContactOrganization></ContactPersonPrimary><ContactPosition>Systems Scientist</ContactPosition><ContactAddress><AddressType>postal</AddressType><Address>867 Lakeshore Road</Address><City>Burlington</City><StateOrProvince>Ontario</StateOrProvince><PostCode>L7R 4A6</PostCode><Country>Canada</Country></ContactAddress><ContactVoiceTelephone>+01-905-336-4409</ContactVoiceTelephone><ContactFacsimileTelephone>+01-905-336-4499</ContactFacsimileTelephone><ContactElectronicMailAddress>tom.kralidis@ec.gc.ca</ContactElectronicMailAddress></ContactInformation>';
+ t.xml_eq(parser.write_wmc_ContactInformation(context.contactInformation),
+ expected,
+ "contactInformation written correctly");
+
+ // LogoURL
+ expected = '<LogoURL xmlns="http://www.opengis.net/context" width="130" height="74" format="image/gif"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif"/></LogoURL>';
+ t.xml_eq(parser.write_wmc_URLType("LogoURL", context.logo.href, context.logo),
+ expected,
+ "LogoURL written correctly");
+
+ // DescriptionURL
+ expected = '<DescriptionURL xmlns="http://www.opengis.net/context"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://eos.nasa.gov/imswelcome"/></DescriptionURL>';
+ t.xml_eq(parser.write_wmc_URLType("DescriptionURL", context.descriptionURL),
+ expected,
+ "DescriptionURL written correctly");
+
+
+ var layerContext = context.layersContext[1];
+
+ // Server
+ expected = '<Server xmlns="http://www.opengis.net/context" service="OGC:WMS" version="1.1.1" title="The GLOBE Program Visualization Server"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://globe.digitalearth.gov/viz-bin/wmt.cgi"/></Server>';
+ t.xml_eq(parser.write_wmc_Server(layerContext),
+ expected,
+ "Server written correctly");
+
+ // FormatList
+ expected = '<FormatList xmlns="http://www.opengis.net/context"><Format current="1">image/gif</Format><Format>image/png</Format></FormatList>';
+ t.xml_eq(parser.write_wmc_FormatList(layerContext),
+ expected,
+ "FormatList written correctly");
+
+ // DimensionList
+ expected = '<DimensionList xmlns="http://www.opengis.net/context"><Dimension name="time" units="ISO8601" nearestValue="1" unitSymbol="" userValue="" multipleValues="0" current="0" default="">2011-03-31,2011-04-01</Dimension></DimensionList>';
+ t.xml_eq(parser.write_wmc_DimensionList(layerContext),
+ expected,
+ "DimensionList written correctly");
+
+ // LegendURL
+ var legend = layerContext.styles[0].legend;
+ expected = '<LegendURL xmlns="http://www.opengis.net/context" width="180" format="image/gif" height="50"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/COASTLINES.gif"/></LegendURL>';
+ t.xml_eq(parser.write_wmc_URLType("LegendURL", legend.href, legend),
+ expected,
+ "LegendURL written correctly");
+
+ layerContext = context.layersContext[2];
+
+ // DataURL
+ expected = '<DataURL xmlns="http://www.opengis.net/context"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://globe.digitalearth.gov/data/national.gml" /></DataURL>';
+ t.xml_eq(parser.write_wmc_URLType("DataURL", layerContext.dataURL),
+ expected,
+ "DataURL written correctly");
+
+ // MetadataURL
+ expected = '<MetadataURL xmlns="http://www.opengis.net/context"><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://globe.digitalearth.gov/metadata/national.txt" /></MetadataURL>';
+ t.xml_eq(parser.write_wmc_URLType("MetadataURL", layerContext.metadataURL),
+ expected,
+ "MetadataURL written correctly");
+
+ }
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 512px; height: 256px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMC/v1.html b/misc/openlayers/tests/Format/WMC/v1.html
new file mode 100644
index 0000000..05e6078
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMC/v1.html
@@ -0,0 +1,266 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_write_wmc_StyleList(t) {
+ t.plan(4);
+
+ var layer, layerContext, got, expected;
+
+ var format = new OpenLayers.Format.WMC();
+ var parser = format.getParser("1");
+ var name = "test";
+ var url = "http://foo";
+
+ // test named style
+ layer = new OpenLayers.Layer.WMS(name, url, {
+ styles: "mystyle"
+ });
+ layerContext = format.layerToContext(layer);
+ got = parser.write_wmc_StyleList(layerContext);
+ expected =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<Name>mystyle</Name><Title>Default</Title>" +
+ "</Style>" +
+ "</StyleList>";
+
+ t.xml_eq(got, expected, "named style correctly written");
+ layer.destroy();
+
+ // test linked style
+ layer = new OpenLayers.Layer.WMS(name, url, {
+ sld: "http://linked.sld"
+ });
+ layerContext = format.layerToContext(layer);
+ got = parser.write_wmc_StyleList(layerContext);
+ expected =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<SLD>" +
+ "<Title>Default</Title>" +
+ "<OnlineResource xmlns:xlink='http://www.w3.org/1999/xlink' "+
+ "xlink:type='simple' " +
+ "xlink:href='http://linked.sld' />" +
+ "</SLD>" +
+ "</Style>" +
+ "</StyleList>";
+
+ t.xml_eq(got, expected, "linked style correctly written");
+ layer.destroy();
+
+ // test inline style
+ layer = new OpenLayers.Layer.WMS(name, url, {
+ sld_body:
+ "<sld:StyledLayerDescriptor version='1.0.0' " +
+ "xmlns:ogc='http://www.opengis.net/ogc' " +
+ "xmlns:sld='http://www.opengis.net/sld' " +
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>" +
+ "<sld:NamedLayer>" +
+ "<sld:Name>AAA212</sld:Name>" +
+ "<sld:UserStyle>" +
+ "<sld:FeatureTypeStyle>" +
+ "<sld:Rule>" +
+ "<sld:TextSymbolizer>" +
+ "<sld:Label>" +
+ "<ogc:PropertyName>ZONENR</ogc:PropertyName>" +
+ "</sld:Label>" +
+ "<sld:Font>" +
+ "<sld:CssParameter name='font-family'>Arial</sld:CssParameter>" +
+ "<sld:CssParameter name='font-size'>10</sld:CssParameter>" +
+ "</sld:Font>" +
+ "<sld:Fill>" +
+ "<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>" +
+ "</sld:Fill>" +
+ "</sld:TextSymbolizer>" +
+ "</sld:Rule>" +
+ "</sld:FeatureTypeStyle>" +
+ "</sld:UserStyle>" +
+ "</sld:NamedLayer>" +
+ "</sld:StyledLayerDescriptor>"
+ });
+
+ layerContext = format.layerToContext(layer);
+ got = parser.write_wmc_StyleList(layerContext);
+ expected =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<SLD>" +
+ "<Title>Default</Title>" +
+ "<sld:StyledLayerDescriptor version='1.0.0' " +
+ "xmlns:sld='http://www.opengis.net/sld' " +
+ "xmlns:ogc='http://www.opengis.net/ogc' " +
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>" +
+ "<sld:NamedLayer>" +
+ "<sld:Name>AAA212</sld:Name>" +
+ "<sld:UserStyle>" +
+ "<sld:FeatureTypeStyle>" +
+ "<sld:Rule>" +
+ "<sld:TextSymbolizer>" +
+ "<sld:Label>" +
+ "<ogc:PropertyName>ZONENR</ogc:PropertyName>" +
+ "</sld:Label>" +
+ "<sld:Font>" +
+ "<sld:CssParameter name='font-family'>Arial</sld:CssParameter>" +
+ "<sld:CssParameter name='font-size'>10</sld:CssParameter>" +
+ "</sld:Font>" +
+ "<sld:Fill>" +
+ "<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>" +
+ "</sld:Fill>" +
+ "</sld:TextSymbolizer>" +
+ "</sld:Rule>" +
+ "</sld:FeatureTypeStyle>" +
+ "</sld:UserStyle>" +
+ "</sld:NamedLayer>" +
+ "</sld:StyledLayerDescriptor>" +
+ "</SLD>" +
+ "</Style>" +
+ "</StyleList>";
+
+ t.xml_eq(got, expected, "inline style correctly written");
+ layer.destroy();
+
+ // test inline FeatureTypeStyle
+ layer = new OpenLayers.Layer.WMS(name, url, {
+ sld_body:
+ "<sld:FeatureTypeStyle version='1.0.0' " +
+ "xmlns:sld='http://www.opengis.net/sld' " +
+ "xmlns:ogc='http://www.opengis.net/ogc' " +
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>" +
+ "<sld:Rule>" +
+ "<sld:TextSymbolizer>" +
+ "<sld:Label>" +
+ "<ogc:PropertyName>ZONENR</ogc:PropertyName>" +
+ "</sld:Label>" +
+ "<sld:Font>" +
+ "<sld:CssParameter name='font-family'>Arial</sld:CssParameter>" +
+ "<sld:CssParameter name='font-size'>10</sld:CssParameter>" +
+ "</sld:Font>" +
+ "<sld:Fill>" +
+ "<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>" +
+ "</sld:Fill>" +
+ "</sld:TextSymbolizer>" +
+ "</sld:Rule>" +
+ "</sld:FeatureTypeStyle>"
+ });
+
+ layerContext = format.layerToContext(layer);
+ got = parser.write_wmc_StyleList(layerContext);
+ expected =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<SLD>" +
+ "<Title>Default</Title>" +
+ "<sld:FeatureTypeStyle version='1.0.0' " +
+ "xmlns:sld='http://www.opengis.net/sld' " +
+ "xmlns:ogc='http://www.opengis.net/ogc' " +
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>" +
+ "<sld:Rule>" +
+ "<sld:TextSymbolizer>" +
+ "<sld:Label>" +
+ "<ogc:PropertyName>ZONENR</ogc:PropertyName>" +
+ "</sld:Label>" +
+ "<sld:Font>" +
+ "<sld:CssParameter name='font-family'>Arial</sld:CssParameter>" +
+ "<sld:CssParameter name='font-size'>10</sld:CssParameter>" +
+ "</sld:Font>" +
+ "<sld:Fill>" +
+ "<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>" +
+ "</sld:Fill>" +
+ "</sld:TextSymbolizer>" +
+ "</sld:Rule>" +
+ "</sld:FeatureTypeStyle>" +
+ "</SLD>" +
+ "</Style>" +
+ "</StyleList>";
+
+ t.xml_eq(got, expected, "inline FeatureTypeStyle correctly written");
+ layer.destroy();
+ }
+
+ function test_read_wmc_StyleList(t) {
+ t.plan(3);
+
+ var xml = new OpenLayers.Format.XML();
+ var format = new OpenLayers.Format.WMC();
+ var parser = format.getParser("1");
+ var node, text, layerContext, layer;
+
+ // test named style
+ text =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<Name>mystyle</Name><Title>Default</Title>" +
+ "</Style>" +
+ "</StyleList>";
+ node = xml.read(text).documentElement;
+ layerContext = {
+ styles: []
+ };
+ parser.read_wmc_StyleList(layerContext, node);
+ layer = format.getLayerFromContext(layerContext);
+ t.eq(layer.params.STYLES, "mystyle", "named style correctly read");
+
+ // test linked style
+ text =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<SLD>" +
+ "<OnlineResource xmlns:xlink='http://www.w3.org/1999/xlink' "+
+ "xlink:type='simple' " +
+ "xlink:href='http://linked.sld' />" +
+ "</SLD>" +
+ "</Style>" +
+ "</StyleList>";
+ node = xml.read(text).documentElement;
+ layerContext = {
+ styles: []
+ };
+ parser.read_wmc_StyleList(layerContext, node);
+ layer = format.getLayerFromContext(layerContext);
+ t.eq(layer.params.SLD, "http://linked.sld", "linked style correctly read");
+
+ // test inline style
+ // any valid xml under the StyledLayerDescriptor node should make the
+ // round trip from string to node and back
+ text =
+ "<StyleList xmlns='http://www.opengis.net/context'>" +
+ "<Style current='1'>" +
+ "<SLD>" +
+ "<sld:StyledLayerDescriptor version='1.0.0' " +
+ "xmlns:sld='http://www.opengis.net/sld' " +
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>" +
+ "<foo>bar<more/></foo>" +
+ "</sld:StyledLayerDescriptor>" +
+ "</SLD>" +
+ "</Style>" +
+ "</StyleList>";
+ node = xml.read(text).documentElement;
+ layerContext = {
+ styles: []
+ };
+ parser.read_wmc_StyleList(layerContext, node);
+ layer = format.getLayerFromContext(layerContext);
+ var expected =
+ "<sld:StyledLayerDescriptor version='1.0.0' " +
+ "xmlns:sld='http://www.opengis.net/sld' " +
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>" +
+ "<foo xmlns='http://www.opengis.net/context'>bar<more/></foo>" +
+ "</sld:StyledLayerDescriptor>";
+ t.xml_eq(layer.params.SLD_BODY, expected, "inline style correctly read");
+
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMC/v1_1_0.html b/misc/openlayers/tests/Format/WMC/v1_1_0.html
new file mode 100644
index 0000000..815d3bf
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMC/v1_1_0.html
@@ -0,0 +1,86 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_write_wmc_Layer(t) {
+ if (OpenLayers.BROWSER_NAME == "safari") {
+ t.plan(0);
+ t.debug_print("Safari has wierd behavior with getElementsByTagNameNS: the result is that we can't run these tests there. Patches welcome.");
+ return;
+ }
+ t.plan(12);
+
+ // direct construction of a parser for a unit test
+ var format = new OpenLayers.Format.WMC();
+ var parser = format.getParser("1_1_0");
+ var sldNS = parser.namespaces["sld"];
+
+ // test that Min/MaxScaleDenominator is not written out when no
+ // resolution related options are set
+ var layer = new OpenLayers.Layer.WMS(
+ "test", "http://foo", {},
+ {maxExtent: new OpenLayers.Bounds(1, 2, 3, 4)}
+ );
+ var layerContext = format.layerToContext(layer);
+ var node = parser.write_wmc_Layer(layerContext);
+ var minList = parser.getElementsByTagNameNS(node, sldNS, "MinScaleDenominator");
+ t.eq(minList.length, 0, "(none) node not written with MinScaleDenominator");
+ var maxList = parser.getElementsByTagNameNS(node, sldNS, "MaxScaleDenominator");
+ t.eq(maxList.length, 0, "(none) node not written with MaxScaleDenominator");
+
+ // test that Min/MaxScaleDenominator is written out for explicit
+ // resolutions array
+ layer = new OpenLayers.Layer.WMS(
+ "test", "http://foo", {},
+ {resolutions: [4, 2, 1], maxExtent: new OpenLayers.Bounds(1, 2, 3, 4)}
+ );
+ layer.minScale = Math.random();
+ layer.maxScale = Math.random();
+ sldNS = parser.namespaces["sld"];
+ layerContext = format.layerToContext(layer);
+ node = parser.write_wmc_Layer(layerContext);
+ minList = parser.getElementsByTagNameNS(node, sldNS, "MinScaleDenominator");
+ t.eq(minList.length, 1, "(resolutions) node written with MinScaleDenominator");
+ t.eq(layer.maxScale.toPrecision(16), parser.getChildValue(minList[0]),
+ "(resolutions) node written with correct MinScaleDenominator value");
+ maxList = parser.getElementsByTagNameNS(node, sldNS, "MaxScaleDenominator");
+ t.eq(maxList.length, 1, "(resolutions) node written with MaxScaleDenominator");
+ t.eq(layer.minScale.toPrecision(16), parser.getChildValue(maxList[0]),
+ "(resolutions) node written with correct MaxScaleDenominator value");
+
+ layer = new OpenLayers.Layer.WMS(
+ "test", "http://foo", {},
+ {scales: [4, 2, 1], maxExtent: new OpenLayers.Bounds(1, 2, 3, 4)}
+ );
+ layer.minScale = Math.random();
+ layer.maxScale = Math.random();
+ layerContext = format.layerToContext(layer);
+ node = parser.write_wmc_Layer(layerContext);
+ minList = parser.getElementsByTagNameNS(node, sldNS, "MinScaleDenominator");
+ var f = new OpenLayers.Format.XML();
+ t.eq(minList.length, 1, "(scales) node written with MinScaleDenominator");
+ t.eq(layer.maxScale.toPrecision(16), parser.getChildValue(minList[0]),
+ "(scales) node written with correct MinScaleDenominator value");
+ maxList = parser.getElementsByTagNameNS(node, sldNS, "MaxScaleDenominator");
+ t.eq(maxList.length, 1, "(scales) node written with MaxScaleDenominator");
+ t.eq(layer.minScale.toPrecision(16), parser.getChildValue(maxList[0]),
+ "(scales) node written with correct MaxScaleDenominator value");
+
+ layer.metadataURL = 'http://foo';
+ layerContext = format.layerToContext(layer);
+ node = parser.write_wmc_Layer(layerContext);
+ t.eq(node.childNodes[3].localName || node.childNodes[3].nodeName.split(":").pop(),
+ 'MetadataURL', "MinScaleDenominator is written after MetadataURL, so third node should be MetadataURL");
+ t.eq(node.childNodes[4].localName || node.childNodes[4].nodeName.split(":").pop(),
+ 'MinScaleDenominator', "MinScaleDenominator is written after MetadataURL, so fourth node should be MinScaleDenominator");
+
+ }
+
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 512px; height: 256px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMSCapabilities.html b/misc/openlayers/tests/Format/WMSCapabilities.html
new file mode 100644
index 0000000..a447bdd
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMSCapabilities.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+
+ t.plan(1);
+ var format = new OpenLayers.Format.WMSCapabilities({
+ version: "foo"
+ });
+ t.eq(format.version, "foo", "version set on format");
+
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1.html b/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1.html
new file mode 100644
index 0000000..e3b0863
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1.html
@@ -0,0 +1,5209 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+ t.plan(1);
+ var xml = document.getElementById("exceptionsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var format = new OpenLayers.Format.WMSCapabilities();
+ var obj = format.read(doc);
+ t.ok(!!obj.error, "Error reported correctly");
+ }
+
+ function test_read(t) {
+
+ t.plan(24);
+
+ var xml = document.getElementById("gssample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var format = new OpenLayers.Format.WMSCapabilities();
+ var obj = format.read(doc);
+
+ var capability = obj.capability;
+ t.ok(capability, "object contains capability property");
+
+ var getmap = capability.request.getmap;
+ t.eq(getmap.formats.length, 28, "getmap formats parsed");
+ t.eq(
+ getmap.href,
+ "http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&",
+ "getmap href parsed"
+ );
+ t.eq(
+ getmap.get.href,
+ getmap.href,
+ "getmap.get.href parsed"
+ );
+ t.eq(
+ getmap.post,
+ undefined,
+ "getmap.post not available"
+ );
+
+ var describelayer = capability.request.describelayer;
+ t.eq(
+ describelayer.href,
+ "http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&",
+ "describelayer href parsed"
+ );
+ t.eq(
+ describelayer.get.href,
+ describelayer.href,
+ "describelayer.get.href parsed"
+ );
+ t.eq(
+ describelayer.post,
+ undefined,
+ "describelayer.post not available"
+ );
+
+ var getfeatureinfo = capability.request.getfeatureinfo;
+ t.eq(
+ getfeatureinfo.href,
+ "http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&",
+ "getfeatureinfo href parsed"
+ );
+ t.eq(
+ getfeatureinfo.get.href,
+ getfeatureinfo.href,
+ "getmap.get.href parsed"
+ );
+ t.eq(
+ getfeatureinfo.post.href,
+ "http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&",
+ "getfeatureinfo.post set correctly"
+ );
+
+ t.ok(capability.layers, "layers parsed");
+ t.eq(capability.layers.length, 22, "correct number of layers parsed");
+
+ var layer = capability.layers[2];
+ t.eq(layer.infoFormats, ["text/plain", "text/html", "application/vnd.ogc.gml"], "infoFormats set on layer");
+ t.eq(layer.name, "tiger:tiger_roads", "[2] correct layer name");
+ t.eq(layer.prefix, "tiger", "[2] correct layer prefix");
+ t.eq(layer.title, "Manhattan (NY) roads", "[2] correct layer title");
+ t.eq(
+ layer["abstract"],
+ "Highly simplified road layout of Manhattan in New York..",
+ "[2] correct layer abstract"
+ );
+ t.eq(
+ layer.llbbox,
+ [-74.08769307536667, 40.660618924633326, -73.84653192463333, 40.90178007536667],
+ "[2] correct layer bbox"
+ );
+ t.eq(layer.styles.length, 1, "[2] correct styles length");
+ t.eq(layer.styles[0].name, "tiger_roads", "[2] correct style name");
+ t.eq(
+ layer.styles[0].legend.href,
+ "http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&FORMAT=image/png&WIDTH=20&HEIGHT=20&LAYER=tiger:tiger_roads",
+ "[2] correct legend url"
+ );
+ t.eq(
+ layer.styles[0].legend.format, "image/png",
+ "[2] correct legend format"
+ );
+ t.eq(layer.queryable, true, "[2] correct queryable attribute");
+
+
+ }
+
+ function test_layers(t) {
+
+ t.plan(24);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var capability = obj.capability;
+
+ var layers = {};
+ for (var i=0, len=capability.layers.length; i<len; i++) {
+ if ("name" in capability.layers[i]) {
+ layers[ capability.layers[i].name ] = capability.layers[i];
+ }
+ }
+
+ var rootlayer = capability.layers[ capability.layers.length - 1];
+
+ t.eq(rootlayer.srs,
+ {"EPSG:4326": true},
+ "SRS parsed correctly for root layer");
+ t.eq(layers["ROADS_RIVERS"].srs,
+ {"EPSG:4326": true, "EPSG:26986": true},
+ "Inheritance of SRS handled correctly when adding SRSes");
+ t.eq(layers["Temperature"].srs,
+ {"EPSG:4326": true},
+ "Inheritance of SRS handled correctly when redeclaring an inherited SRS");
+
+ var bbox = layers["ROADS_RIVERS"].bbox["EPSG:26986"];
+ t.eq(bbox.bbox,
+ [189000, 834000, 285000, 962000],
+ "Correct bbox from BoundingBox");
+ t.eq(bbox.res, {x: 1, y: 1}, "Correct resolution");
+ bbox = layers["ROADS_RIVERS"].bbox["EPSG:4326"];
+ t.eq(bbox.bbox,
+ [-71.63, 41.75, -70.78, 42.90],
+ "Correct bbox from BoundingBox (override)");
+ t.eq(bbox.res, {x: 0.01, y: 0.01}, "Correct resolution (override)");
+ bbox = layers["ROADS_1M"].bbox["EPSG:26986"];
+ t.eq(bbox.bbox,
+ [189000, 834000, 285000, 962000],
+ "Correctly inherited bbox");
+ t.eq(bbox.res, {x: 1, y: 1}, "Correctly inherited resolution");
+
+
+ var identifiers = layers["ROADS_RIVERS"].identifiers;
+ var authorities = layers["ROADS_RIVERS"].authorityURLs;
+
+ t.ok(identifiers, "got identifiers from layer ROADS_RIVERS");
+ t.ok("DIF_ID" in identifiers,
+ "authority attribute from Identifiers parsed correctly");
+ t.eq(identifiers["DIF_ID"],
+ "123456",
+ "Identifier value parsed correctly");
+ t.ok("DIF_ID" in authorities,
+ "AuthorityURLs parsed and inherited correctly");
+ t.eq(authorities["DIF_ID"],
+ "http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html",
+ "OnlineResource in AuthorityURLs parsed correctly");
+
+ var featurelist = layers["ROADS_RIVERS"].featureListURL;
+ t.ok(featurelist, "layer has FeatureListURL");
+ t.eq(featurelist.format,
+ "application/vnd.ogc.se_xml",
+ "FeatureListURL format parsed correctly");
+ t.eq(featurelist.href,
+ "http://www.university.edu/data/roads_rivers.gml",
+ "FeatureListURL OnlineResource parsed correctly");
+
+ t.eq(layers["Pressure"].queryable,
+ true,
+ "queryable property inherited correctly");
+ t.eq(layers["ozone_image"].queryable,
+ false,
+ "queryable property has correct default value");
+ t.eq(layers["population"].cascaded,
+ 1,
+ "cascaded property parsed correctly");
+ t.eq(layers["ozone_image"].fixedWidth,
+ 512,
+ "fixedWidth property correctly parsed");
+ t.eq(layers["ozone_image"].fixedHeight,
+ 256,
+ "fixedHeight property correctly parsed");
+ t.eq(layers["ozone_image"].opaque,
+ true,
+ "opaque property parsed correctly");
+ t.eq(layers["ozone_image"].noSubsets,
+ true,
+ "noSubsets property parsed correctly");
+
+
+ }
+
+ function test_dimensions(t) {
+
+ t.plan(8);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var capability = obj.capability;
+
+ var layers = {};
+ for (var i=0, len=capability.layers.length; i<len; i++) {
+ if ("name" in capability.layers[i]) {
+ layers[ capability.layers[i].name ] = capability.layers[i];
+ }
+ }
+
+ var time = layers["Clouds"].dimensions.time;
+ t.eq(time["default"], "2000-08-22", "Default time value parsed correctly");
+ t.eq(time.values.length, 1, "Currect number of time extent values/periods");
+ t.eq(time.values[0], "1999-01-01/2000-08-22/P1D", "Time extent values parsed correctly");
+
+ var elevation = layers["Pressure"].dimensions.elevation;
+ t.eq(elevation.units, "EPSG:5030", "Dimension units parsed correctly");
+ t.eq(elevation["default"], "0", "Default elevation value parsed correctly");
+ t.eq(elevation.nearestVal, true, "NearestValue parsed correctly");
+ t.eq(elevation.multipleVal, false, "Absense of MultipleValues handled correctly");
+ t.eq(elevation.values,
+ ["0","1000","3000","5000","10000"],
+ "Parsing of comma-separated values done correctly");
+
+
+ }
+
+ function test_contactinfo(t) {
+ t.plan(15);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var service = obj.service;
+
+ var contactinfo = service.contactInformation;
+ t.ok(contactinfo, "object contains contactInformation property");
+
+ var personPrimary = contactinfo.personPrimary;
+ t.ok(personPrimary, "object contains personPrimary property");
+
+ t.eq(personPrimary.person, "Jeff deLaBeaujardiere", "ContactPerson parsed correctly");
+ t.eq(personPrimary.organization, "NASA", "ContactOrganization parsed correctly");
+
+ t.eq(contactinfo.position,
+ "Computer Scientist",
+ "ContactPosition parsed correctly");
+
+
+ var addr = contactinfo.contactAddress;
+ t.ok(addr, "object contains contactAddress property");
+
+ t.eq(addr.type, "postal", "AddressType parsed correctly");
+ t.eq(addr.address,
+ "NASA Goddard Space Flight Center, Code 933",
+ "Address parsed correctly");
+ t.eq(addr.city, "Greenbelt", "City parsed correctly");
+ t.eq(addr.stateOrProvince, "MD", "StateOrProvince parsed correctly");
+ t.eq(addr.postcode, "20771", "PostCode parsed correctly");
+ t.eq(addr.country, "USA", "Country parsed correctly");
+
+ t.eq(contactinfo.phone,
+ "+1 301 286-1569",
+ "ContactVoiceTelephone parsed correctly");
+ t.eq(contactinfo.fax,
+ "+1 301 286-1777",
+ "ContactFacsimileTelephone parsed correctly");
+ t.eq(contactinfo.email,
+ "delabeau@iniki.gsfc.nasa.gov",
+ "ContactElectronicMailAddress parsed correctly");
+ }
+
+ function test_feesAndConstraints(t) {
+ t.plan(2);
+
+ var xml = document.getElementById("gssample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var service = obj.service;
+
+ t.ok(! ("fees" in service), "Fees=none handled correctly");
+ t.ok(! ("accessConstraints" in service), "AccessConstraints=none handled correctly");
+ }
+
+ function test_requests(t) {
+ t.plan(13);
+
+ var xml = document.getElementById("gssample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var request = obj.capability.request;
+
+ t.ok(request, "request property exists");
+ t.ok("getmap" in request, "got GetMap request");
+
+ t.ok("getfeatureinfo" in request, "got GetFeatureInfo request");
+ t.eq(request.getfeatureinfo.formats,
+ ["text/plain", "text/html", "application/vnd.ogc.gml"],
+ "GetFeatureInfo formats correctly parsed");
+
+ t.ok("describelayer" in request, "got DescribeLayer request");
+
+ t.ok("getlegendgraphic" in request, "got GetLegendGraphic request");
+
+ var exception = obj.capability.exception;
+ t.ok(exception, "exception property exists");
+ t.eq(exception.formats,
+ ["application/vnd.ogc.se_xml"],
+ "Exception Format parsed");
+
+ var userSymbols = obj.capability.userSymbols;
+ t.ok(userSymbols, "userSymbols property exists");
+ t.eq(userSymbols.supportSLD, true, "supportSLD parsed");
+ t.eq(userSymbols.userLayer, true, "userLayer parsed");
+ t.eq(userSymbols.userStyle, true, "userStyle parsed");
+ t.eq(userSymbols.remoteWFS, true, "remoteWFS parsed");
+
+ }
+ function test_ogc(t) {
+ t.plan(16)
+
+ /*
+ * Set up
+ */
+
+ // needed for the minScale/maxScale test, see below
+ var dpi = OpenLayers.DOTS_PER_INCH;
+ OpenLayers.DOTS_PER_INCH = 90.710230403857;
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var capability = obj.capability;
+
+ /*
+ * Test
+ */
+
+ var attribution = capability.layers[2].attribution;
+ t.eq(attribution.title, "State College University", "attribution title parsed correctly.");
+ t.eq(attribution.href, "http://www.university.edu/", "attribution href parsed correctly.")
+ t.eq(attribution.logo.href, "http://www.university.edu/icons/logo.gif", "attribution logo url parsed correctly.");
+ t.eq(attribution.logo.format, "image/gif", "attribution logo format parsed correctly.");
+ t.eq(attribution.logo.width, "100", "attribution logo width parsed correctly.");
+ t.eq(attribution.logo.height, "100", "attribution logo height parsed correctly.");
+
+ var keywords = capability.layers[0].keywords;
+ t.eq(keywords.length, 3, "layer has 3 keywords.");
+ t.eq(keywords[0], "road", "1st keyword parsed correctly.");
+
+ var metadataURLs = capability.layers[0].metadataURLs;
+ t.eq(metadataURLs.length, 2, "layer has 2 metadata urls.");
+ t.eq(metadataURLs[0].type, "FGDC", "type parsed correctly.");
+ t.eq(metadataURLs[0].format, "text/plain", "format parsed correctly.");
+ t.eq(metadataURLs[0].href, "http://www.university.edu/metadata/roads.txt", "href parsed correctly.");
+
+ /*
+ Test minScale and maxScale
+
+ For Mapserver
+
+ <ScaleHint min="0.395998292216226" max="98.9995730540565" />
+
+ corresponds to (RESOLUTION keyword in MAP file has value of 90.710230403857):
+
+ MAXSCALE 250000
+ MINSCALE 1000
+
+ */
+ t.eq(capability.layers[0].minScale, 250000, "layer.minScale is correct");
+ t.eq(capability.layers[0].maxScale, 1000, "layer.maxScale is correct");
+
+ t.eq(capability.layers[1].minScale, undefined, "layer.minScale for max='Infinity' is correct");
+ t.eq(capability.layers[1].maxScale, undefined, "layer.maxScale for min='0' is correct");
+ /*
+ * Tear down
+ */
+
+ OpenLayers.DOTS_PER_INCH = dpi;
+ }
+
+ </script>
+</head>
+<body>
+
+<!--
+OGC example below taken from
+http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.xml
+Copyright © 1994-2008 Open Geospatial Consortium, Inc. All Rights Reserved.
+http://www.opengeospatial.org/ogc/document
+Changes:
+* fixed DTD URL
+* removed comments
+-->
+<div id="ogcsample"><!--
+<?xml version='1.0' encoding="UTF-8" standalone="no" ?>
+<!DOCTYPE WMT_MS_Capabilities SYSTEM
+ "http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.dtd"
+ [
+ <!ELEMENT VendorSpecificCapabilities EMPTY>
+ ]>
+
+<WMT_MS_Capabilities version="1.1.1" updateSequence="0">
+<Service>
+
+ <Name>OGC:WMS</Name>
+ <Title>Acme Corp. Map Server</Title>
+ <Abstract>WMT Map Server maintained by Acme Corporation. Contact: webmaster@wmt.acme.com. High-quality maps showing roadrunner nests and possible ambush locations.</Abstract>
+ <KeywordList>
+
+ <Keyword>bird</Keyword>
+ <Keyword>roadrunner</Keyword>
+ <Keyword>ambush</Keyword>
+ </KeywordList>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://hostname/" />
+
+ <ContactInformation>
+ <ContactPersonPrimary>
+ <ContactPerson>Jeff deLaBeaujardiere</ContactPerson>
+ <ContactOrganization>NASA</ContactOrganization>
+ </ContactPersonPrimary>
+ <ContactPosition>Computer Scientist</ContactPosition>
+ <ContactAddress>
+
+ <AddressType>postal</AddressType>
+ <Address>NASA Goddard Space Flight Center, Code 933</Address>
+ <City>Greenbelt</City>
+ <StateOrProvince>MD</StateOrProvince>
+ <PostCode>20771</PostCode>
+ <Country>USA</Country>
+
+ </ContactAddress>
+ <ContactVoiceTelephone>+1 301 286-1569</ContactVoiceTelephone>
+ <ContactFacsimileTelephone>+1 301 286-1777</ContactFacsimileTelephone>
+ <ContactElectronicMailAddress>delabeau@iniki.gsfc.nasa.gov</ContactElectronicMailAddress>
+ </ContactInformation>
+ <Fees>none</Fees>
+
+ <AccessConstraints>none</AccessConstraints>
+</Service>
+<Capability>
+ <Request>
+ <GetCapabilities>
+ <Format>application/vnd.ogc.wms_xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname:port/path" />
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname:port/path" />
+ </Post>
+ </HTTP>
+ </DCPType>
+
+ </GetCapabilities>
+ <GetMap>
+ <Format>image/gif</Format>
+ <Format>image/png</Format>
+ <Format>image/jpeg</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname:port/path/get" />
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname:port/path/post" />
+ </Post>
+ </HTTP>
+ </DCPType>
+ </GetMap>
+ <GetFeatureInfo>
+ <Format>application/vnd.ogc.gml</Format>
+
+ <Format>text/plain</Format>
+ <Format>text/html</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname:port/path" />
+ </Get>
+ </HTTP>
+
+ </DCPType>
+ </GetFeatureInfo>
+ <DescribeLayer>
+ <Format>application/vnd.ogc.gml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname:port/path" />
+
+ </Get>
+ </HTTP>
+ </DCPType>
+ </DescribeLayer>
+ </Request>
+ <Exception>
+ <Format>application/vnd.ogc.se_xml</Format>
+ <Format>application/vnd.ogc.se_inimage</Format>
+
+ <Format>application/vnd.ogc.se_blank</Format>
+ </Exception>
+ <VendorSpecificCapabilities />
+ <UserDefinedSymbolization SupportSLD="1" UserLayer="1" UserStyle="1"
+ RemoteWFS="1" />
+
+ <Layer>
+ <Title>Acme Corp. Map Server</Title>
+ <SRS>EPSG:4326</SRS>
+ <BoundingBox SRS="EPSG:4326"
+ minx="-1" miny="-1" maxx="1" maxy="1" resx="0.0" resy="0.0"/>
+ <AuthorityURL name="DIF_ID">
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html" />
+ </AuthorityURL>
+ <Layer>
+ <Name>ROADS_RIVERS</Name>
+ <Title>Roads and Rivers</Title>
+ <SRS>EPSG:26986</SRS>
+ <LatLonBoundingBox minx="-71.63" miny="41.75" maxx="-70.78" maxy="42.90"/>
+ <BoundingBox SRS="EPSG:4326"
+ minx="-71.63" miny="41.75" maxx="-70.78" maxy="42.90" resx="0.01" resy="0.01"/>
+
+ <BoundingBox SRS="EPSG:26986"
+ minx="189000" miny="834000" maxx="285000" maxy="962000" resx="1" resy="1" />
+ <Attribution>
+ <Title>State College University</Title>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://www.university.edu/" />
+ <LogoURL width="100" height="100">
+ <Format>image/gif</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/icons/logo.gif" />
+
+ </LogoURL>
+ </Attribution>
+ <Identifier authority="DIF_ID">123456</Identifier>
+ <FeatureListURL>
+ <Format>application/vnd.ogc.se_xml</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://www.university.edu/data/roads_rivers.gml" />
+ </FeatureListURL>
+
+ <Style>
+ <Name>USGS</Name>
+ <Title>USGS Topo Map Style</Title>
+ <Abstract>Features are shown in a style like that used in USGS topographic maps.</Abstract>
+ <LegendURL width="72" height="72">
+ <Format>image/gif</Format>
+
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/legends/usgs.gif" />
+ </LegendURL>
+ <StyleSheetURL>
+ <Format>text/xsl</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/stylesheets/usgs.xsl" />
+ </StyleSheetURL>
+ </Style>
+
+
+ <Layer queryable="1">
+ <Name>ROADS_1M</Name>
+ <Title>Roads at 1:1M scale</Title>
+ <Abstract>Roads at a scale of 1 to 1 million.</Abstract>
+ <KeywordList>
+ <Keyword>road</Keyword>
+
+ <Keyword>transportation</Keyword>
+ <Keyword>atlas</Keyword>
+ </KeywordList>
+ <Identifier authority="DIF_ID">123456</Identifier>
+ <MetadataURL type="FGDC">
+ <Format>text/plain</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/metadata/roads.txt" />
+ </MetadataURL>
+ <MetadataURL type="FGDC">
+ <Format>text/xml</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/metadata/roads.xml" />
+ </MetadataURL>
+ <Style>
+
+ <Name>ATLAS</Name>
+ <Title>Road atlas style</Title>
+ <Abstract>Roads are shown in a style like that used in a commercial road atlas.</Abstract>
+ <LegendURL width="72" height="72">
+ <Format>image/gif</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/legends/atlas.gif" />
+ </LegendURL>
+
+ </Style>
+ <ScaleHint min="0.395998292216226" max="98.9995730540565" />
+ </Layer>
+ <Layer queryable="1">
+ <Name>RIVERS_1M</Name>
+ <Title>Rivers at 1:1M scale</Title>
+ <Abstract>Rivers at a scale of 1 to 1 million.</Abstract>
+ <KeywordList>
+
+ <Keyword>river</Keyword>
+ <Keyword>canal</Keyword>
+ <Keyword>waterway</Keyword>
+ </KeywordList>
+ <ScaleHint min="0" max="Infinity" />
+ </Layer>
+ </Layer>
+ <Layer queryable="1">
+
+ <Title>Weather Forecast Data</Title>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
+ <Dimension name="time" units="ISO8601" />
+ <Extent name="time" default="2000-08-22">1999-01-01/2000-08-22/P1D</Extent>
+
+ <Layer>
+ <Name>Clouds</Name>
+ <Title>Forecast cloud cover</Title>
+ </Layer>
+
+ <Layer>
+ <Name>Temperature</Name>
+ <Title>Forecast temperature</Title>
+ </Layer>
+
+ <Layer>
+ <Name>Pressure</Name>
+ <Title>Forecast barometric pressure</Title>
+ <Dimension name="time" units="ISO8601" />
+ <Dimension name="elevation" units="EPSG:5030" />
+ <Extent name="time" default="2000-08-22">1999-01-01/2000-08-22/P1D</Extent>
+ <Extent name="elevation" default="0" nearestValue="1">0,1000,3000,5000,10000</Extent>
+ </Layer>
+
+ </Layer>
+
+ <Layer opaque="1" noSubsets="1" fixedWidth="512" fixedHeight="256">
+ <Name>ozone_image</Name>
+ <Title>Global ozone distribution (1992)</Title>
+ <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
+ <Extent name="time" default="1992">1992</Extent>
+ </Layer>
+
+ <Layer cascaded="1">
+ <Name>population</Name>
+ <Title>World population, annual</Title>
+ <LatLonBoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
+ <Extent name="time" default="2000">1990/2000/P1Y</Extent>
+ </Layer>
+
+ </Layer>
+
+
+</Capability>
+</WMT_MS_Capabilities>
+--></div>
+<div id="exceptionsample"><!--
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd">
+<ServiceExceptionReport version="1.1.1"><ServiceException> Plain text message about an error. </ServiceException>
+</ServiceExceptionReport>
+--></div>
+<!--
+GeoServer example below taken from
+http://publicus.opengeo.org/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities
+Changes:
+* fixed DTD URL (publicus is no longer available)
+* removed comments
+-->
+<div id="gssample"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE WMT_MS_Capabilities SYSTEM "http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.dtd">
+<WMT_MS_Capabilities version="1.1.1" updateSequence="57">
+ <Service>
+ <Name>OGC:WMS</Name>
+ <Title>GeoServer Web Map Service</Title>
+ <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>
+ <KeywordList>
+ <Keyword>WFS</Keyword>
+ <Keyword>WMS</Keyword>
+ <Keyword>GEOSERVER</Keyword>
+ </KeywordList>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms"/>
+ <ContactInformation>
+ <ContactPersonPrimary>
+ <ContactPerson>Claudius Ptolomaeus</ContactPerson>
+ <ContactOrganization>The ancient geographes INC</ContactOrganization>
+ </ContactPersonPrimary>
+ <ContactPosition>Chief geographer</ContactPosition>
+ <ContactAddress>
+ <AddressType>Work</AddressType>
+ <Address/>
+ <City>Alexandria</City>
+ <StateOrProvince/>
+ <PostCode/>
+ <Country>Egypt</Country>
+ </ContactAddress>
+ <ContactVoiceTelephone/>
+ <ContactFacsimileTelephone/>
+ <ContactElectronicMailAddress>claudius.ptolomaeus@gmail.com</ContactElectronicMailAddress>
+ </ContactInformation>
+ <Fees>NONE</Fees>
+ <AccessConstraints>NONE</AccessConstraints>
+ </Service>
+ <Capability>
+ <Request>
+ <GetCapabilities>
+ <Format>application/vnd.ogc.wms_xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Post>
+ </HTTP>
+ </DCPType>
+ </GetCapabilities>
+ <GetMap>
+ <Format>image/png</Format>
+ <Format>application/atom xml</Format>
+ <Format>application/atom+xml</Format>
+ <Format>application/openlayers</Format>
+ <Format>application/pdf</Format>
+ <Format>application/rss xml</Format>
+ <Format>application/rss+xml</Format>
+ <Format>application/vnd.google-earth.kml</Format>
+ <Format>application/vnd.google-earth.kml xml</Format>
+ <Format>application/vnd.google-earth.kml+xml</Format>
+ <Format>application/vnd.google-earth.kmz</Format>
+ <Format>application/vnd.google-earth.kmz xml</Format>
+ <Format>application/vnd.google-earth.kmz+xml</Format>
+ <Format>atom</Format>
+ <Format>image/geotiff</Format>
+ <Format>image/geotiff8</Format>
+ <Format>image/gif</Format>
+ <Format>image/jpeg</Format>
+ <Format>image/png8</Format>
+ <Format>image/svg</Format>
+ <Format>image/svg xml</Format>
+ <Format>image/svg+xml</Format>
+ <Format>image/tiff</Format>
+ <Format>image/tiff8</Format>
+ <Format>kml</Format>
+ <Format>kmz</Format>
+ <Format>openlayers</Format>
+ <Format>rss</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetMap>
+ <GetFeatureInfo>
+ <Format>text/plain</Format>
+ <Format>text/html</Format>
+ <Format>application/vnd.ogc.gml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Post>
+ </HTTP>
+ </DCPType>
+ </GetFeatureInfo>
+ <DescribeLayer>
+ <Format>application/vnd.ogc.wms_xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </DescribeLayer>
+ <GetLegendGraphic>
+ <Format>image/png</Format>
+ <Format>image/jpeg</Format>
+ <Format>image/gif</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetLegendGraphic>
+ </Request>
+ <Exception>
+ <Format>application/vnd.ogc.se_xml</Format>
+ </Exception>
+ <UserDefinedSymbolization SupportSLD="1" UserLayer="1" UserStyle="1" RemoteWFS="1"/>
+ <Layer>
+ <Title>GeoServer Web Map Service</Title>
+ <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>
+ <SRS>EPSG:WGS84(DD)</SRS>
+ <SRS>EPSG:2000</SRS>
+ <SRS>EPSG:2001</SRS>
+ <SRS>EPSG:2002</SRS>
+ <SRS>EPSG:2003</SRS>
+ <SRS>EPSG:2004</SRS>
+ <SRS>EPSG:2005</SRS>
+ <SRS>EPSG:2006</SRS>
+ <SRS>EPSG:2007</SRS>
+ <SRS>EPSG:2008</SRS>
+ <SRS>EPSG:2009</SRS>
+ <SRS>EPSG:2010</SRS>
+ <SRS>EPSG:2011</SRS>
+ <SRS>EPSG:2012</SRS>
+ <SRS>EPSG:2013</SRS>
+ <SRS>EPSG:2014</SRS>
+ <SRS>EPSG:2015</SRS>
+ <SRS>EPSG:2016</SRS>
+ <SRS>EPSG:2017</SRS>
+ <SRS>EPSG:2018</SRS>
+ <SRS>EPSG:2019</SRS>
+ <SRS>EPSG:2020</SRS>
+ <SRS>EPSG:2021</SRS>
+ <SRS>EPSG:2022</SRS>
+ <SRS>EPSG:2023</SRS>
+ <SRS>EPSG:2024</SRS>
+ <SRS>EPSG:2025</SRS>
+ <SRS>EPSG:2026</SRS>
+ <SRS>EPSG:2027</SRS>
+ <SRS>EPSG:2028</SRS>
+ <SRS>EPSG:2029</SRS>
+ <SRS>EPSG:2030</SRS>
+ <SRS>EPSG:2031</SRS>
+ <SRS>EPSG:2032</SRS>
+ <SRS>EPSG:2033</SRS>
+ <SRS>EPSG:2034</SRS>
+ <SRS>EPSG:2035</SRS>
+ <SRS>EPSG:2036</SRS>
+ <SRS>EPSG:2037</SRS>
+ <SRS>EPSG:2038</SRS>
+ <SRS>EPSG:2039</SRS>
+ <SRS>EPSG:2040</SRS>
+ <SRS>EPSG:2041</SRS>
+ <SRS>EPSG:2042</SRS>
+ <SRS>EPSG:2043</SRS>
+ <SRS>EPSG:2044</SRS>
+ <SRS>EPSG:2045</SRS>
+ <SRS>EPSG:2046</SRS>
+ <SRS>EPSG:2047</SRS>
+ <SRS>EPSG:2048</SRS>
+ <SRS>EPSG:2049</SRS>
+ <SRS>EPSG:2050</SRS>
+ <SRS>EPSG:2051</SRS>
+ <SRS>EPSG:2052</SRS>
+ <SRS>EPSG:2053</SRS>
+ <SRS>EPSG:2054</SRS>
+ <SRS>EPSG:2055</SRS>
+ <SRS>EPSG:2056</SRS>
+ <SRS>EPSG:2057</SRS>
+ <SRS>EPSG:2058</SRS>
+ <SRS>EPSG:2059</SRS>
+ <SRS>EPSG:2060</SRS>
+ <SRS>EPSG:2061</SRS>
+ <SRS>EPSG:2062</SRS>
+ <SRS>EPSG:2063</SRS>
+ <SRS>EPSG:2064</SRS>
+ <SRS>EPSG:2065</SRS>
+ <SRS>EPSG:2066</SRS>
+ <SRS>EPSG:2067</SRS>
+ <SRS>EPSG:2068</SRS>
+ <SRS>EPSG:2069</SRS>
+ <SRS>EPSG:2070</SRS>
+ <SRS>EPSG:2071</SRS>
+ <SRS>EPSG:2072</SRS>
+ <SRS>EPSG:2073</SRS>
+ <SRS>EPSG:2074</SRS>
+ <SRS>EPSG:2075</SRS>
+ <SRS>EPSG:2076</SRS>
+ <SRS>EPSG:2077</SRS>
+ <SRS>EPSG:2078</SRS>
+ <SRS>EPSG:2079</SRS>
+ <SRS>EPSG:2080</SRS>
+ <SRS>EPSG:2081</SRS>
+ <SRS>EPSG:2082</SRS>
+ <SRS>EPSG:2083</SRS>
+ <SRS>EPSG:2084</SRS>
+ <SRS>EPSG:2085</SRS>
+ <SRS>EPSG:2086</SRS>
+ <SRS>EPSG:2087</SRS>
+ <SRS>EPSG:2088</SRS>
+ <SRS>EPSG:2089</SRS>
+ <SRS>EPSG:2090</SRS>
+ <SRS>EPSG:2091</SRS>
+ <SRS>EPSG:2092</SRS>
+ <SRS>EPSG:2093</SRS>
+ <SRS>EPSG:2094</SRS>
+ <SRS>EPSG:2095</SRS>
+ <SRS>EPSG:2096</SRS>
+ <SRS>EPSG:2097</SRS>
+ <SRS>EPSG:2098</SRS>
+ <SRS>EPSG:2099</SRS>
+ <SRS>EPSG:2100</SRS>
+ <SRS>EPSG:2101</SRS>
+ <SRS>EPSG:2102</SRS>
+ <SRS>EPSG:2103</SRS>
+ <SRS>EPSG:2104</SRS>
+ <SRS>EPSG:2105</SRS>
+ <SRS>EPSG:2106</SRS>
+ <SRS>EPSG:2107</SRS>
+ <SRS>EPSG:2108</SRS>
+ <SRS>EPSG:2109</SRS>
+ <SRS>EPSG:2110</SRS>
+ <SRS>EPSG:2111</SRS>
+ <SRS>EPSG:2112</SRS>
+ <SRS>EPSG:2113</SRS>
+ <SRS>EPSG:2114</SRS>
+ <SRS>EPSG:2115</SRS>
+ <SRS>EPSG:2116</SRS>
+ <SRS>EPSG:2117</SRS>
+ <SRS>EPSG:2118</SRS>
+ <SRS>EPSG:2119</SRS>
+ <SRS>EPSG:2120</SRS>
+ <SRS>EPSG:2121</SRS>
+ <SRS>EPSG:2122</SRS>
+ <SRS>EPSG:2123</SRS>
+ <SRS>EPSG:2124</SRS>
+ <SRS>EPSG:2125</SRS>
+ <SRS>EPSG:2126</SRS>
+ <SRS>EPSG:2127</SRS>
+ <SRS>EPSG:2128</SRS>
+ <SRS>EPSG:2129</SRS>
+ <SRS>EPSG:2130</SRS>
+ <SRS>EPSG:2131</SRS>
+ <SRS>EPSG:2132</SRS>
+ <SRS>EPSG:2133</SRS>
+ <SRS>EPSG:2134</SRS>
+ <SRS>EPSG:2135</SRS>
+ <SRS>EPSG:2136</SRS>
+ <SRS>EPSG:2137</SRS>
+ <SRS>EPSG:2138</SRS>
+ <SRS>EPSG:2139</SRS>
+ <SRS>EPSG:2140</SRS>
+ <SRS>EPSG:2141</SRS>
+ <SRS>EPSG:2142</SRS>
+ <SRS>EPSG:2143</SRS>
+ <SRS>EPSG:2144</SRS>
+ <SRS>EPSG:2145</SRS>
+ <SRS>EPSG:2146</SRS>
+ <SRS>EPSG:2147</SRS>
+ <SRS>EPSG:2148</SRS>
+ <SRS>EPSG:2149</SRS>
+ <SRS>EPSG:2150</SRS>
+ <SRS>EPSG:2151</SRS>
+ <SRS>EPSG:2152</SRS>
+ <SRS>EPSG:2153</SRS>
+ <SRS>EPSG:2154</SRS>
+ <SRS>EPSG:2155</SRS>
+ <SRS>EPSG:2156</SRS>
+ <SRS>EPSG:2157</SRS>
+ <SRS>EPSG:2158</SRS>
+ <SRS>EPSG:2159</SRS>
+ <SRS>EPSG:2160</SRS>
+ <SRS>EPSG:2161</SRS>
+ <SRS>EPSG:2162</SRS>
+ <SRS>EPSG:2163</SRS>
+ <SRS>EPSG:2164</SRS>
+ <SRS>EPSG:2165</SRS>
+ <SRS>EPSG:2166</SRS>
+ <SRS>EPSG:2167</SRS>
+ <SRS>EPSG:2168</SRS>
+ <SRS>EPSG:2169</SRS>
+ <SRS>EPSG:2170</SRS>
+ <SRS>EPSG:2171</SRS>
+ <SRS>EPSG:2172</SRS>
+ <SRS>EPSG:2173</SRS>
+ <SRS>EPSG:2174</SRS>
+ <SRS>EPSG:2175</SRS>
+ <SRS>EPSG:2176</SRS>
+ <SRS>EPSG:2177</SRS>
+ <SRS>EPSG:2178</SRS>
+ <SRS>EPSG:2179</SRS>
+ <SRS>EPSG:2180</SRS>
+ <SRS>EPSG:2188</SRS>
+ <SRS>EPSG:2189</SRS>
+ <SRS>EPSG:2190</SRS>
+ <SRS>EPSG:2191</SRS>
+ <SRS>EPSG:2192</SRS>
+ <SRS>EPSG:2193</SRS>
+ <SRS>EPSG:2194</SRS>
+ <SRS>EPSG:2195</SRS>
+ <SRS>EPSG:2196</SRS>
+ <SRS>EPSG:2197</SRS>
+ <SRS>EPSG:2198</SRS>
+ <SRS>EPSG:2199</SRS>
+ <SRS>EPSG:2200</SRS>
+ <SRS>EPSG:2201</SRS>
+ <SRS>EPSG:2202</SRS>
+ <SRS>EPSG:2203</SRS>
+ <SRS>EPSG:2204</SRS>
+ <SRS>EPSG:2205</SRS>
+ <SRS>EPSG:2206</SRS>
+ <SRS>EPSG:2207</SRS>
+ <SRS>EPSG:2208</SRS>
+ <SRS>EPSG:2209</SRS>
+ <SRS>EPSG:2210</SRS>
+ <SRS>EPSG:2211</SRS>
+ <SRS>EPSG:2212</SRS>
+ <SRS>EPSG:2213</SRS>
+ <SRS>EPSG:2214</SRS>
+ <SRS>EPSG:2215</SRS>
+ <SRS>EPSG:2216</SRS>
+ <SRS>EPSG:2217</SRS>
+ <SRS>EPSG:2218</SRS>
+ <SRS>EPSG:2219</SRS>
+ <SRS>EPSG:2220</SRS>
+ <SRS>EPSG:2221</SRS>
+ <SRS>EPSG:2222</SRS>
+ <SRS>EPSG:2223</SRS>
+ <SRS>EPSG:2224</SRS>
+ <SRS>EPSG:2225</SRS>
+ <SRS>EPSG:2226</SRS>
+ <SRS>EPSG:2227</SRS>
+ <SRS>EPSG:2228</SRS>
+ <SRS>EPSG:2229</SRS>
+ <SRS>EPSG:2230</SRS>
+ <SRS>EPSG:2231</SRS>
+ <SRS>EPSG:2232</SRS>
+ <SRS>EPSG:2233</SRS>
+ <SRS>EPSG:2234</SRS>
+ <SRS>EPSG:2235</SRS>
+ <SRS>EPSG:2236</SRS>
+ <SRS>EPSG:2237</SRS>
+ <SRS>EPSG:2238</SRS>
+ <SRS>EPSG:2239</SRS>
+ <SRS>EPSG:2240</SRS>
+ <SRS>EPSG:2241</SRS>
+ <SRS>EPSG:2242</SRS>
+ <SRS>EPSG:2243</SRS>
+ <SRS>EPSG:2244</SRS>
+ <SRS>EPSG:2245</SRS>
+ <SRS>EPSG:2246</SRS>
+ <SRS>EPSG:2247</SRS>
+ <SRS>EPSG:2248</SRS>
+ <SRS>EPSG:2249</SRS>
+ <SRS>EPSG:2250</SRS>
+ <SRS>EPSG:2251</SRS>
+ <SRS>EPSG:2252</SRS>
+ <SRS>EPSG:2253</SRS>
+ <SRS>EPSG:2254</SRS>
+ <SRS>EPSG:2255</SRS>
+ <SRS>EPSG:2256</SRS>
+ <SRS>EPSG:2257</SRS>
+ <SRS>EPSG:2258</SRS>
+ <SRS>EPSG:2259</SRS>
+ <SRS>EPSG:2260</SRS>
+ <SRS>EPSG:2261</SRS>
+ <SRS>EPSG:2262</SRS>
+ <SRS>EPSG:2263</SRS>
+ <SRS>EPSG:2264</SRS>
+ <SRS>EPSG:2265</SRS>
+ <SRS>EPSG:2266</SRS>
+ <SRS>EPSG:2267</SRS>
+ <SRS>EPSG:2268</SRS>
+ <SRS>EPSG:2269</SRS>
+ <SRS>EPSG:2270</SRS>
+ <SRS>EPSG:2271</SRS>
+ <SRS>EPSG:2272</SRS>
+ <SRS>EPSG:2273</SRS>
+ <SRS>EPSG:2274</SRS>
+ <SRS>EPSG:2275</SRS>
+ <SRS>EPSG:2276</SRS>
+ <SRS>EPSG:2277</SRS>
+ <SRS>EPSG:2278</SRS>
+ <SRS>EPSG:2279</SRS>
+ <SRS>EPSG:2280</SRS>
+ <SRS>EPSG:2281</SRS>
+ <SRS>EPSG:2282</SRS>
+ <SRS>EPSG:2283</SRS>
+ <SRS>EPSG:2284</SRS>
+ <SRS>EPSG:2285</SRS>
+ <SRS>EPSG:2286</SRS>
+ <SRS>EPSG:2287</SRS>
+ <SRS>EPSG:2288</SRS>
+ <SRS>EPSG:2289</SRS>
+ <SRS>EPSG:2290</SRS>
+ <SRS>EPSG:2291</SRS>
+ <SRS>EPSG:2292</SRS>
+ <SRS>EPSG:2294</SRS>
+ <SRS>EPSG:2295</SRS>
+ <SRS>EPSG:2296</SRS>
+ <SRS>EPSG:2297</SRS>
+ <SRS>EPSG:2298</SRS>
+ <SRS>EPSG:2299</SRS>
+ <SRS>EPSG:2300</SRS>
+ <SRS>EPSG:2301</SRS>
+ <SRS>EPSG:2302</SRS>
+ <SRS>EPSG:2303</SRS>
+ <SRS>EPSG:2304</SRS>
+ <SRS>EPSG:2305</SRS>
+ <SRS>EPSG:2306</SRS>
+ <SRS>EPSG:2307</SRS>
+ <SRS>EPSG:2308</SRS>
+ <SRS>EPSG:2309</SRS>
+ <SRS>EPSG:2310</SRS>
+ <SRS>EPSG:2311</SRS>
+ <SRS>EPSG:2312</SRS>
+ <SRS>EPSG:2313</SRS>
+ <SRS>EPSG:2314</SRS>
+ <SRS>EPSG:2315</SRS>
+ <SRS>EPSG:2316</SRS>
+ <SRS>EPSG:2317</SRS>
+ <SRS>EPSG:2318</SRS>
+ <SRS>EPSG:2319</SRS>
+ <SRS>EPSG:2320</SRS>
+ <SRS>EPSG:2321</SRS>
+ <SRS>EPSG:2322</SRS>
+ <SRS>EPSG:2323</SRS>
+ <SRS>EPSG:2324</SRS>
+ <SRS>EPSG:2325</SRS>
+ <SRS>EPSG:2326</SRS>
+ <SRS>EPSG:2327</SRS>
+ <SRS>EPSG:2328</SRS>
+ <SRS>EPSG:2329</SRS>
+ <SRS>EPSG:2330</SRS>
+ <SRS>EPSG:2331</SRS>
+ <SRS>EPSG:2332</SRS>
+ <SRS>EPSG:2333</SRS>
+ <SRS>EPSG:2334</SRS>
+ <SRS>EPSG:2335</SRS>
+ <SRS>EPSG:2336</SRS>
+ <SRS>EPSG:2337</SRS>
+ <SRS>EPSG:2338</SRS>
+ <SRS>EPSG:2339</SRS>
+ <SRS>EPSG:2340</SRS>
+ <SRS>EPSG:2341</SRS>
+ <SRS>EPSG:2342</SRS>
+ <SRS>EPSG:2343</SRS>
+ <SRS>EPSG:2344</SRS>
+ <SRS>EPSG:2345</SRS>
+ <SRS>EPSG:2346</SRS>
+ <SRS>EPSG:2347</SRS>
+ <SRS>EPSG:2348</SRS>
+ <SRS>EPSG:2349</SRS>
+ <SRS>EPSG:2350</SRS>
+ <SRS>EPSG:2351</SRS>
+ <SRS>EPSG:2352</SRS>
+ <SRS>EPSG:2353</SRS>
+ <SRS>EPSG:2354</SRS>
+ <SRS>EPSG:2355</SRS>
+ <SRS>EPSG:2356</SRS>
+ <SRS>EPSG:2357</SRS>
+ <SRS>EPSG:2358</SRS>
+ <SRS>EPSG:2359</SRS>
+ <SRS>EPSG:2360</SRS>
+ <SRS>EPSG:2361</SRS>
+ <SRS>EPSG:2362</SRS>
+ <SRS>EPSG:2363</SRS>
+ <SRS>EPSG:2364</SRS>
+ <SRS>EPSG:2365</SRS>
+ <SRS>EPSG:2366</SRS>
+ <SRS>EPSG:2367</SRS>
+ <SRS>EPSG:2368</SRS>
+ <SRS>EPSG:2369</SRS>
+ <SRS>EPSG:2370</SRS>
+ <SRS>EPSG:2371</SRS>
+ <SRS>EPSG:2372</SRS>
+ <SRS>EPSG:2373</SRS>
+ <SRS>EPSG:2374</SRS>
+ <SRS>EPSG:2375</SRS>
+ <SRS>EPSG:2376</SRS>
+ <SRS>EPSG:2377</SRS>
+ <SRS>EPSG:2378</SRS>
+ <SRS>EPSG:2379</SRS>
+ <SRS>EPSG:2380</SRS>
+ <SRS>EPSG:2381</SRS>
+ <SRS>EPSG:2382</SRS>
+ <SRS>EPSG:2383</SRS>
+ <SRS>EPSG:2384</SRS>
+ <SRS>EPSG:2385</SRS>
+ <SRS>EPSG:2386</SRS>
+ <SRS>EPSG:2387</SRS>
+ <SRS>EPSG:2388</SRS>
+ <SRS>EPSG:2389</SRS>
+ <SRS>EPSG:2390</SRS>
+ <SRS>EPSG:2391</SRS>
+ <SRS>EPSG:2392</SRS>
+ <SRS>EPSG:2393</SRS>
+ <SRS>EPSG:2394</SRS>
+ <SRS>EPSG:2395</SRS>
+ <SRS>EPSG:2396</SRS>
+ <SRS>EPSG:2397</SRS>
+ <SRS>EPSG:2398</SRS>
+ <SRS>EPSG:2399</SRS>
+ <SRS>EPSG:2400</SRS>
+ <SRS>EPSG:2401</SRS>
+ <SRS>EPSG:2402</SRS>
+ <SRS>EPSG:2403</SRS>
+ <SRS>EPSG:2404</SRS>
+ <SRS>EPSG:2405</SRS>
+ <SRS>EPSG:2406</SRS>
+ <SRS>EPSG:2407</SRS>
+ <SRS>EPSG:2408</SRS>
+ <SRS>EPSG:2409</SRS>
+ <SRS>EPSG:2410</SRS>
+ <SRS>EPSG:2411</SRS>
+ <SRS>EPSG:2412</SRS>
+ <SRS>EPSG:2413</SRS>
+ <SRS>EPSG:2414</SRS>
+ <SRS>EPSG:2415</SRS>
+ <SRS>EPSG:2416</SRS>
+ <SRS>EPSG:2417</SRS>
+ <SRS>EPSG:2418</SRS>
+ <SRS>EPSG:2419</SRS>
+ <SRS>EPSG:2420</SRS>
+ <SRS>EPSG:2421</SRS>
+ <SRS>EPSG:2422</SRS>
+ <SRS>EPSG:2423</SRS>
+ <SRS>EPSG:2424</SRS>
+ <SRS>EPSG:2425</SRS>
+ <SRS>EPSG:2426</SRS>
+ <SRS>EPSG:2427</SRS>
+ <SRS>EPSG:2428</SRS>
+ <SRS>EPSG:2429</SRS>
+ <SRS>EPSG:2430</SRS>
+ <SRS>EPSG:2431</SRS>
+ <SRS>EPSG:2432</SRS>
+ <SRS>EPSG:2433</SRS>
+ <SRS>EPSG:2434</SRS>
+ <SRS>EPSG:2435</SRS>
+ <SRS>EPSG:2436</SRS>
+ <SRS>EPSG:2437</SRS>
+ <SRS>EPSG:2438</SRS>
+ <SRS>EPSG:2439</SRS>
+ <SRS>EPSG:2440</SRS>
+ <SRS>EPSG:2441</SRS>
+ <SRS>EPSG:2442</SRS>
+ <SRS>EPSG:2443</SRS>
+ <SRS>EPSG:2444</SRS>
+ <SRS>EPSG:2445</SRS>
+ <SRS>EPSG:2446</SRS>
+ <SRS>EPSG:2447</SRS>
+ <SRS>EPSG:2448</SRS>
+ <SRS>EPSG:2449</SRS>
+ <SRS>EPSG:2450</SRS>
+ <SRS>EPSG:2451</SRS>
+ <SRS>EPSG:2452</SRS>
+ <SRS>EPSG:2453</SRS>
+ <SRS>EPSG:2454</SRS>
+ <SRS>EPSG:2455</SRS>
+ <SRS>EPSG:2456</SRS>
+ <SRS>EPSG:2457</SRS>
+ <SRS>EPSG:2458</SRS>
+ <SRS>EPSG:2459</SRS>
+ <SRS>EPSG:2460</SRS>
+ <SRS>EPSG:2461</SRS>
+ <SRS>EPSG:2462</SRS>
+ <SRS>EPSG:2463</SRS>
+ <SRS>EPSG:2464</SRS>
+ <SRS>EPSG:2465</SRS>
+ <SRS>EPSG:2466</SRS>
+ <SRS>EPSG:2467</SRS>
+ <SRS>EPSG:2468</SRS>
+ <SRS>EPSG:2469</SRS>
+ <SRS>EPSG:2470</SRS>
+ <SRS>EPSG:2471</SRS>
+ <SRS>EPSG:2472</SRS>
+ <SRS>EPSG:2473</SRS>
+ <SRS>EPSG:2474</SRS>
+ <SRS>EPSG:2475</SRS>
+ <SRS>EPSG:2476</SRS>
+ <SRS>EPSG:2477</SRS>
+ <SRS>EPSG:2478</SRS>
+ <SRS>EPSG:2479</SRS>
+ <SRS>EPSG:2480</SRS>
+ <SRS>EPSG:2481</SRS>
+ <SRS>EPSG:2482</SRS>
+ <SRS>EPSG:2483</SRS>
+ <SRS>EPSG:2484</SRS>
+ <SRS>EPSG:2485</SRS>
+ <SRS>EPSG:2486</SRS>
+ <SRS>EPSG:2487</SRS>
+ <SRS>EPSG:2488</SRS>
+ <SRS>EPSG:2489</SRS>
+ <SRS>EPSG:2490</SRS>
+ <SRS>EPSG:2491</SRS>
+ <SRS>EPSG:2492</SRS>
+ <SRS>EPSG:2493</SRS>
+ <SRS>EPSG:2494</SRS>
+ <SRS>EPSG:2495</SRS>
+ <SRS>EPSG:2496</SRS>
+ <SRS>EPSG:2497</SRS>
+ <SRS>EPSG:2498</SRS>
+ <SRS>EPSG:2499</SRS>
+ <SRS>EPSG:2500</SRS>
+ <SRS>EPSG:2501</SRS>
+ <SRS>EPSG:2502</SRS>
+ <SRS>EPSG:2503</SRS>
+ <SRS>EPSG:2504</SRS>
+ <SRS>EPSG:2505</SRS>
+ <SRS>EPSG:2506</SRS>
+ <SRS>EPSG:2507</SRS>
+ <SRS>EPSG:2508</SRS>
+ <SRS>EPSG:2509</SRS>
+ <SRS>EPSG:2510</SRS>
+ <SRS>EPSG:2511</SRS>
+ <SRS>EPSG:2512</SRS>
+ <SRS>EPSG:2513</SRS>
+ <SRS>EPSG:2514</SRS>
+ <SRS>EPSG:2515</SRS>
+ <SRS>EPSG:2516</SRS>
+ <SRS>EPSG:2517</SRS>
+ <SRS>EPSG:2518</SRS>
+ <SRS>EPSG:2519</SRS>
+ <SRS>EPSG:2520</SRS>
+ <SRS>EPSG:2521</SRS>
+ <SRS>EPSG:2522</SRS>
+ <SRS>EPSG:2523</SRS>
+ <SRS>EPSG:2524</SRS>
+ <SRS>EPSG:2525</SRS>
+ <SRS>EPSG:2526</SRS>
+ <SRS>EPSG:2527</SRS>
+ <SRS>EPSG:2528</SRS>
+ <SRS>EPSG:2529</SRS>
+ <SRS>EPSG:2530</SRS>
+ <SRS>EPSG:2531</SRS>
+ <SRS>EPSG:2532</SRS>
+ <SRS>EPSG:2533</SRS>
+ <SRS>EPSG:2534</SRS>
+ <SRS>EPSG:2535</SRS>
+ <SRS>EPSG:2536</SRS>
+ <SRS>EPSG:2537</SRS>
+ <SRS>EPSG:2538</SRS>
+ <SRS>EPSG:2539</SRS>
+ <SRS>EPSG:2540</SRS>
+ <SRS>EPSG:2541</SRS>
+ <SRS>EPSG:2542</SRS>
+ <SRS>EPSG:2543</SRS>
+ <SRS>EPSG:2544</SRS>
+ <SRS>EPSG:2545</SRS>
+ <SRS>EPSG:2546</SRS>
+ <SRS>EPSG:2547</SRS>
+ <SRS>EPSG:2548</SRS>
+ <SRS>EPSG:2549</SRS>
+ <SRS>EPSG:2550</SRS>
+ <SRS>EPSG:2551</SRS>
+ <SRS>EPSG:2552</SRS>
+ <SRS>EPSG:2553</SRS>
+ <SRS>EPSG:2554</SRS>
+ <SRS>EPSG:2555</SRS>
+ <SRS>EPSG:2556</SRS>
+ <SRS>EPSG:2557</SRS>
+ <SRS>EPSG:2558</SRS>
+ <SRS>EPSG:2559</SRS>
+ <SRS>EPSG:2560</SRS>
+ <SRS>EPSG:2561</SRS>
+ <SRS>EPSG:2562</SRS>
+ <SRS>EPSG:2563</SRS>
+ <SRS>EPSG:2564</SRS>
+ <SRS>EPSG:2565</SRS>
+ <SRS>EPSG:2566</SRS>
+ <SRS>EPSG:2567</SRS>
+ <SRS>EPSG:2568</SRS>
+ <SRS>EPSG:2569</SRS>
+ <SRS>EPSG:2570</SRS>
+ <SRS>EPSG:2571</SRS>
+ <SRS>EPSG:2572</SRS>
+ <SRS>EPSG:2573</SRS>
+ <SRS>EPSG:2574</SRS>
+ <SRS>EPSG:2575</SRS>
+ <SRS>EPSG:2576</SRS>
+ <SRS>EPSG:2577</SRS>
+ <SRS>EPSG:2578</SRS>
+ <SRS>EPSG:2579</SRS>
+ <SRS>EPSG:2580</SRS>
+ <SRS>EPSG:2581</SRS>
+ <SRS>EPSG:2582</SRS>
+ <SRS>EPSG:2583</SRS>
+ <SRS>EPSG:2584</SRS>
+ <SRS>EPSG:2585</SRS>
+ <SRS>EPSG:2586</SRS>
+ <SRS>EPSG:2587</SRS>
+ <SRS>EPSG:2588</SRS>
+ <SRS>EPSG:2589</SRS>
+ <SRS>EPSG:2590</SRS>
+ <SRS>EPSG:2591</SRS>
+ <SRS>EPSG:2592</SRS>
+ <SRS>EPSG:2593</SRS>
+ <SRS>EPSG:2594</SRS>
+ <SRS>EPSG:2595</SRS>
+ <SRS>EPSG:2596</SRS>
+ <SRS>EPSG:2597</SRS>
+ <SRS>EPSG:2598</SRS>
+ <SRS>EPSG:2599</SRS>
+ <SRS>EPSG:2600</SRS>
+ <SRS>EPSG:2601</SRS>
+ <SRS>EPSG:2602</SRS>
+ <SRS>EPSG:2603</SRS>
+ <SRS>EPSG:2604</SRS>
+ <SRS>EPSG:2605</SRS>
+ <SRS>EPSG:2606</SRS>
+ <SRS>EPSG:2607</SRS>
+ <SRS>EPSG:2608</SRS>
+ <SRS>EPSG:2609</SRS>
+ <SRS>EPSG:2610</SRS>
+ <SRS>EPSG:2611</SRS>
+ <SRS>EPSG:2612</SRS>
+ <SRS>EPSG:2613</SRS>
+ <SRS>EPSG:2614</SRS>
+ <SRS>EPSG:2615</SRS>
+ <SRS>EPSG:2616</SRS>
+ <SRS>EPSG:2617</SRS>
+ <SRS>EPSG:2618</SRS>
+ <SRS>EPSG:2619</SRS>
+ <SRS>EPSG:2620</SRS>
+ <SRS>EPSG:2621</SRS>
+ <SRS>EPSG:2622</SRS>
+ <SRS>EPSG:2623</SRS>
+ <SRS>EPSG:2624</SRS>
+ <SRS>EPSG:2625</SRS>
+ <SRS>EPSG:2626</SRS>
+ <SRS>EPSG:2627</SRS>
+ <SRS>EPSG:2628</SRS>
+ <SRS>EPSG:2629</SRS>
+ <SRS>EPSG:2630</SRS>
+ <SRS>EPSG:2631</SRS>
+ <SRS>EPSG:2632</SRS>
+ <SRS>EPSG:2633</SRS>
+ <SRS>EPSG:2634</SRS>
+ <SRS>EPSG:2635</SRS>
+ <SRS>EPSG:2636</SRS>
+ <SRS>EPSG:2637</SRS>
+ <SRS>EPSG:2638</SRS>
+ <SRS>EPSG:2639</SRS>
+ <SRS>EPSG:2640</SRS>
+ <SRS>EPSG:2641</SRS>
+ <SRS>EPSG:2642</SRS>
+ <SRS>EPSG:2643</SRS>
+ <SRS>EPSG:2644</SRS>
+ <SRS>EPSG:2645</SRS>
+ <SRS>EPSG:2646</SRS>
+ <SRS>EPSG:2647</SRS>
+ <SRS>EPSG:2648</SRS>
+ <SRS>EPSG:2649</SRS>
+ <SRS>EPSG:2650</SRS>
+ <SRS>EPSG:2651</SRS>
+ <SRS>EPSG:2652</SRS>
+ <SRS>EPSG:2653</SRS>
+ <SRS>EPSG:2654</SRS>
+ <SRS>EPSG:2655</SRS>
+ <SRS>EPSG:2656</SRS>
+ <SRS>EPSG:2657</SRS>
+ <SRS>EPSG:2658</SRS>
+ <SRS>EPSG:2659</SRS>
+ <SRS>EPSG:2660</SRS>
+ <SRS>EPSG:2661</SRS>
+ <SRS>EPSG:2662</SRS>
+ <SRS>EPSG:2663</SRS>
+ <SRS>EPSG:2664</SRS>
+ <SRS>EPSG:2665</SRS>
+ <SRS>EPSG:2666</SRS>
+ <SRS>EPSG:2667</SRS>
+ <SRS>EPSG:2668</SRS>
+ <SRS>EPSG:2669</SRS>
+ <SRS>EPSG:2670</SRS>
+ <SRS>EPSG:2671</SRS>
+ <SRS>EPSG:2672</SRS>
+ <SRS>EPSG:2673</SRS>
+ <SRS>EPSG:2674</SRS>
+ <SRS>EPSG:2675</SRS>
+ <SRS>EPSG:2676</SRS>
+ <SRS>EPSG:2677</SRS>
+ <SRS>EPSG:2678</SRS>
+ <SRS>EPSG:2679</SRS>
+ <SRS>EPSG:2680</SRS>
+ <SRS>EPSG:2681</SRS>
+ <SRS>EPSG:2682</SRS>
+ <SRS>EPSG:2683</SRS>
+ <SRS>EPSG:2684</SRS>
+ <SRS>EPSG:2685</SRS>
+ <SRS>EPSG:2686</SRS>
+ <SRS>EPSG:2687</SRS>
+ <SRS>EPSG:2688</SRS>
+ <SRS>EPSG:2689</SRS>
+ <SRS>EPSG:2690</SRS>
+ <SRS>EPSG:2691</SRS>
+ <SRS>EPSG:2692</SRS>
+ <SRS>EPSG:2693</SRS>
+ <SRS>EPSG:2694</SRS>
+ <SRS>EPSG:2695</SRS>
+ <SRS>EPSG:2696</SRS>
+ <SRS>EPSG:2697</SRS>
+ <SRS>EPSG:2698</SRS>
+ <SRS>EPSG:2699</SRS>
+ <SRS>EPSG:2700</SRS>
+ <SRS>EPSG:2701</SRS>
+ <SRS>EPSG:2702</SRS>
+ <SRS>EPSG:2703</SRS>
+ <SRS>EPSG:2704</SRS>
+ <SRS>EPSG:2705</SRS>
+ <SRS>EPSG:2706</SRS>
+ <SRS>EPSG:2707</SRS>
+ <SRS>EPSG:2708</SRS>
+ <SRS>EPSG:2709</SRS>
+ <SRS>EPSG:2710</SRS>
+ <SRS>EPSG:2711</SRS>
+ <SRS>EPSG:2712</SRS>
+ <SRS>EPSG:2713</SRS>
+ <SRS>EPSG:2714</SRS>
+ <SRS>EPSG:2715</SRS>
+ <SRS>EPSG:2716</SRS>
+ <SRS>EPSG:2717</SRS>
+ <SRS>EPSG:2718</SRS>
+ <SRS>EPSG:2719</SRS>
+ <SRS>EPSG:2720</SRS>
+ <SRS>EPSG:2721</SRS>
+ <SRS>EPSG:2722</SRS>
+ <SRS>EPSG:2723</SRS>
+ <SRS>EPSG:2724</SRS>
+ <SRS>EPSG:2725</SRS>
+ <SRS>EPSG:2726</SRS>
+ <SRS>EPSG:2727</SRS>
+ <SRS>EPSG:2728</SRS>
+ <SRS>EPSG:2729</SRS>
+ <SRS>EPSG:2730</SRS>
+ <SRS>EPSG:2731</SRS>
+ <SRS>EPSG:2732</SRS>
+ <SRS>EPSG:2733</SRS>
+ <SRS>EPSG:2734</SRS>
+ <SRS>EPSG:2735</SRS>
+ <SRS>EPSG:2736</SRS>
+ <SRS>EPSG:2737</SRS>
+ <SRS>EPSG:2738</SRS>
+ <SRS>EPSG:2739</SRS>
+ <SRS>EPSG:2740</SRS>
+ <SRS>EPSG:2741</SRS>
+ <SRS>EPSG:2742</SRS>
+ <SRS>EPSG:2743</SRS>
+ <SRS>EPSG:2744</SRS>
+ <SRS>EPSG:2745</SRS>
+ <SRS>EPSG:2746</SRS>
+ <SRS>EPSG:2747</SRS>
+ <SRS>EPSG:2748</SRS>
+ <SRS>EPSG:2749</SRS>
+ <SRS>EPSG:2750</SRS>
+ <SRS>EPSG:2751</SRS>
+ <SRS>EPSG:2752</SRS>
+ <SRS>EPSG:2753</SRS>
+ <SRS>EPSG:2754</SRS>
+ <SRS>EPSG:2755</SRS>
+ <SRS>EPSG:2756</SRS>
+ <SRS>EPSG:2757</SRS>
+ <SRS>EPSG:2758</SRS>
+ <SRS>EPSG:2759</SRS>
+ <SRS>EPSG:2760</SRS>
+ <SRS>EPSG:2761</SRS>
+ <SRS>EPSG:2762</SRS>
+ <SRS>EPSG:2763</SRS>
+ <SRS>EPSG:2764</SRS>
+ <SRS>EPSG:2765</SRS>
+ <SRS>EPSG:2766</SRS>
+ <SRS>EPSG:2767</SRS>
+ <SRS>EPSG:2768</SRS>
+ <SRS>EPSG:2769</SRS>
+ <SRS>EPSG:2770</SRS>
+ <SRS>EPSG:2771</SRS>
+ <SRS>EPSG:2772</SRS>
+ <SRS>EPSG:2773</SRS>
+ <SRS>EPSG:2774</SRS>
+ <SRS>EPSG:2775</SRS>
+ <SRS>EPSG:2776</SRS>
+ <SRS>EPSG:2777</SRS>
+ <SRS>EPSG:2778</SRS>
+ <SRS>EPSG:2779</SRS>
+ <SRS>EPSG:2780</SRS>
+ <SRS>EPSG:2781</SRS>
+ <SRS>EPSG:2782</SRS>
+ <SRS>EPSG:2783</SRS>
+ <SRS>EPSG:2784</SRS>
+ <SRS>EPSG:2785</SRS>
+ <SRS>EPSG:2786</SRS>
+ <SRS>EPSG:2787</SRS>
+ <SRS>EPSG:2788</SRS>
+ <SRS>EPSG:2789</SRS>
+ <SRS>EPSG:2790</SRS>
+ <SRS>EPSG:2791</SRS>
+ <SRS>EPSG:2792</SRS>
+ <SRS>EPSG:2793</SRS>
+ <SRS>EPSG:2794</SRS>
+ <SRS>EPSG:2795</SRS>
+ <SRS>EPSG:2796</SRS>
+ <SRS>EPSG:2797</SRS>
+ <SRS>EPSG:2798</SRS>
+ <SRS>EPSG:2799</SRS>
+ <SRS>EPSG:2800</SRS>
+ <SRS>EPSG:2801</SRS>
+ <SRS>EPSG:2802</SRS>
+ <SRS>EPSG:2803</SRS>
+ <SRS>EPSG:2804</SRS>
+ <SRS>EPSG:2805</SRS>
+ <SRS>EPSG:2806</SRS>
+ <SRS>EPSG:2807</SRS>
+ <SRS>EPSG:2808</SRS>
+ <SRS>EPSG:2809</SRS>
+ <SRS>EPSG:2810</SRS>
+ <SRS>EPSG:2811</SRS>
+ <SRS>EPSG:2812</SRS>
+ <SRS>EPSG:2813</SRS>
+ <SRS>EPSG:2814</SRS>
+ <SRS>EPSG:2815</SRS>
+ <SRS>EPSG:2816</SRS>
+ <SRS>EPSG:2817</SRS>
+ <SRS>EPSG:2818</SRS>
+ <SRS>EPSG:2819</SRS>
+ <SRS>EPSG:2820</SRS>
+ <SRS>EPSG:2821</SRS>
+ <SRS>EPSG:2822</SRS>
+ <SRS>EPSG:2823</SRS>
+ <SRS>EPSG:2824</SRS>
+ <SRS>EPSG:2825</SRS>
+ <SRS>EPSG:2826</SRS>
+ <SRS>EPSG:2827</SRS>
+ <SRS>EPSG:2828</SRS>
+ <SRS>EPSG:2829</SRS>
+ <SRS>EPSG:2830</SRS>
+ <SRS>EPSG:2831</SRS>
+ <SRS>EPSG:2832</SRS>
+ <SRS>EPSG:2833</SRS>
+ <SRS>EPSG:2834</SRS>
+ <SRS>EPSG:2835</SRS>
+ <SRS>EPSG:2836</SRS>
+ <SRS>EPSG:2837</SRS>
+ <SRS>EPSG:2838</SRS>
+ <SRS>EPSG:2839</SRS>
+ <SRS>EPSG:2840</SRS>
+ <SRS>EPSG:2841</SRS>
+ <SRS>EPSG:2842</SRS>
+ <SRS>EPSG:2843</SRS>
+ <SRS>EPSG:2844</SRS>
+ <SRS>EPSG:2845</SRS>
+ <SRS>EPSG:2846</SRS>
+ <SRS>EPSG:2847</SRS>
+ <SRS>EPSG:2848</SRS>
+ <SRS>EPSG:2849</SRS>
+ <SRS>EPSG:2850</SRS>
+ <SRS>EPSG:2851</SRS>
+ <SRS>EPSG:2852</SRS>
+ <SRS>EPSG:2853</SRS>
+ <SRS>EPSG:2854</SRS>
+ <SRS>EPSG:2855</SRS>
+ <SRS>EPSG:2856</SRS>
+ <SRS>EPSG:2857</SRS>
+ <SRS>EPSG:2858</SRS>
+ <SRS>EPSG:2859</SRS>
+ <SRS>EPSG:2860</SRS>
+ <SRS>EPSG:2861</SRS>
+ <SRS>EPSG:2862</SRS>
+ <SRS>EPSG:2863</SRS>
+ <SRS>EPSG:2864</SRS>
+ <SRS>EPSG:2865</SRS>
+ <SRS>EPSG:2866</SRS>
+ <SRS>EPSG:2867</SRS>
+ <SRS>EPSG:2868</SRS>
+ <SRS>EPSG:2869</SRS>
+ <SRS>EPSG:2870</SRS>
+ <SRS>EPSG:2871</SRS>
+ <SRS>EPSG:2872</SRS>
+ <SRS>EPSG:2873</SRS>
+ <SRS>EPSG:2874</SRS>
+ <SRS>EPSG:2875</SRS>
+ <SRS>EPSG:2876</SRS>
+ <SRS>EPSG:2877</SRS>
+ <SRS>EPSG:2878</SRS>
+ <SRS>EPSG:2879</SRS>
+ <SRS>EPSG:2880</SRS>
+ <SRS>EPSG:2881</SRS>
+ <SRS>EPSG:2882</SRS>
+ <SRS>EPSG:2883</SRS>
+ <SRS>EPSG:2884</SRS>
+ <SRS>EPSG:2885</SRS>
+ <SRS>EPSG:2886</SRS>
+ <SRS>EPSG:2887</SRS>
+ <SRS>EPSG:2888</SRS>
+ <SRS>EPSG:2889</SRS>
+ <SRS>EPSG:2890</SRS>
+ <SRS>EPSG:2891</SRS>
+ <SRS>EPSG:2892</SRS>
+ <SRS>EPSG:2893</SRS>
+ <SRS>EPSG:2894</SRS>
+ <SRS>EPSG:2895</SRS>
+ <SRS>EPSG:2896</SRS>
+ <SRS>EPSG:2897</SRS>
+ <SRS>EPSG:2898</SRS>
+ <SRS>EPSG:2899</SRS>
+ <SRS>EPSG:2900</SRS>
+ <SRS>EPSG:2901</SRS>
+ <SRS>EPSG:2902</SRS>
+ <SRS>EPSG:2903</SRS>
+ <SRS>EPSG:2904</SRS>
+ <SRS>EPSG:2905</SRS>
+ <SRS>EPSG:2906</SRS>
+ <SRS>EPSG:2907</SRS>
+ <SRS>EPSG:2908</SRS>
+ <SRS>EPSG:2909</SRS>
+ <SRS>EPSG:2910</SRS>
+ <SRS>EPSG:2911</SRS>
+ <SRS>EPSG:2912</SRS>
+ <SRS>EPSG:2913</SRS>
+ <SRS>EPSG:2914</SRS>
+ <SRS>EPSG:2915</SRS>
+ <SRS>EPSG:2916</SRS>
+ <SRS>EPSG:2917</SRS>
+ <SRS>EPSG:2918</SRS>
+ <SRS>EPSG:2919</SRS>
+ <SRS>EPSG:2920</SRS>
+ <SRS>EPSG:2921</SRS>
+ <SRS>EPSG:2922</SRS>
+ <SRS>EPSG:2923</SRS>
+ <SRS>EPSG:2924</SRS>
+ <SRS>EPSG:2925</SRS>
+ <SRS>EPSG:2926</SRS>
+ <SRS>EPSG:2927</SRS>
+ <SRS>EPSG:2928</SRS>
+ <SRS>EPSG:2929</SRS>
+ <SRS>EPSG:2930</SRS>
+ <SRS>EPSG:2931</SRS>
+ <SRS>EPSG:2932</SRS>
+ <SRS>EPSG:2933</SRS>
+ <SRS>EPSG:2934</SRS>
+ <SRS>EPSG:2935</SRS>
+ <SRS>EPSG:2936</SRS>
+ <SRS>EPSG:2937</SRS>
+ <SRS>EPSG:2938</SRS>
+ <SRS>EPSG:2939</SRS>
+ <SRS>EPSG:2940</SRS>
+ <SRS>EPSG:2941</SRS>
+ <SRS>EPSG:2942</SRS>
+ <SRS>EPSG:2943</SRS>
+ <SRS>EPSG:2944</SRS>
+ <SRS>EPSG:2945</SRS>
+ <SRS>EPSG:2946</SRS>
+ <SRS>EPSG:2947</SRS>
+ <SRS>EPSG:2948</SRS>
+ <SRS>EPSG:2949</SRS>
+ <SRS>EPSG:2950</SRS>
+ <SRS>EPSG:2951</SRS>
+ <SRS>EPSG:2952</SRS>
+ <SRS>EPSG:2953</SRS>
+ <SRS>EPSG:2954</SRS>
+ <SRS>EPSG:2955</SRS>
+ <SRS>EPSG:2956</SRS>
+ <SRS>EPSG:2957</SRS>
+ <SRS>EPSG:2958</SRS>
+ <SRS>EPSG:2959</SRS>
+ <SRS>EPSG:2960</SRS>
+ <SRS>EPSG:2961</SRS>
+ <SRS>EPSG:2962</SRS>
+ <SRS>EPSG:2963</SRS>
+ <SRS>EPSG:2964</SRS>
+ <SRS>EPSG:2965</SRS>
+ <SRS>EPSG:2966</SRS>
+ <SRS>EPSG:2967</SRS>
+ <SRS>EPSG:2968</SRS>
+ <SRS>EPSG:2969</SRS>
+ <SRS>EPSG:2970</SRS>
+ <SRS>EPSG:2971</SRS>
+ <SRS>EPSG:2972</SRS>
+ <SRS>EPSG:2973</SRS>
+ <SRS>EPSG:2975</SRS>
+ <SRS>EPSG:2976</SRS>
+ <SRS>EPSG:2977</SRS>
+ <SRS>EPSG:2978</SRS>
+ <SRS>EPSG:2979</SRS>
+ <SRS>EPSG:2980</SRS>
+ <SRS>EPSG:2981</SRS>
+ <SRS>EPSG:2982</SRS>
+ <SRS>EPSG:2983</SRS>
+ <SRS>EPSG:2984</SRS>
+ <SRS>EPSG:2985</SRS>
+ <SRS>EPSG:2986</SRS>
+ <SRS>EPSG:2987</SRS>
+ <SRS>EPSG:2988</SRS>
+ <SRS>EPSG:2989</SRS>
+ <SRS>EPSG:2990</SRS>
+ <SRS>EPSG:2991</SRS>
+ <SRS>EPSG:2992</SRS>
+ <SRS>EPSG:2993</SRS>
+ <SRS>EPSG:2994</SRS>
+ <SRS>EPSG:2995</SRS>
+ <SRS>EPSG:2996</SRS>
+ <SRS>EPSG:2997</SRS>
+ <SRS>EPSG:2998</SRS>
+ <SRS>EPSG:2999</SRS>
+ <SRS>EPSG:3000</SRS>
+ <SRS>EPSG:3001</SRS>
+ <SRS>EPSG:3002</SRS>
+ <SRS>EPSG:3003</SRS>
+ <SRS>EPSG:3004</SRS>
+ <SRS>EPSG:3005</SRS>
+ <SRS>EPSG:3006</SRS>
+ <SRS>EPSG:3007</SRS>
+ <SRS>EPSG:3008</SRS>
+ <SRS>EPSG:3009</SRS>
+ <SRS>EPSG:3010</SRS>
+ <SRS>EPSG:3011</SRS>
+ <SRS>EPSG:3012</SRS>
+ <SRS>EPSG:3013</SRS>
+ <SRS>EPSG:3014</SRS>
+ <SRS>EPSG:3015</SRS>
+ <SRS>EPSG:3016</SRS>
+ <SRS>EPSG:3017</SRS>
+ <SRS>EPSG:3018</SRS>
+ <SRS>EPSG:3019</SRS>
+ <SRS>EPSG:3020</SRS>
+ <SRS>EPSG:3021</SRS>
+ <SRS>EPSG:3022</SRS>
+ <SRS>EPSG:3023</SRS>
+ <SRS>EPSG:3024</SRS>
+ <SRS>EPSG:3025</SRS>
+ <SRS>EPSG:3026</SRS>
+ <SRS>EPSG:3027</SRS>
+ <SRS>EPSG:3028</SRS>
+ <SRS>EPSG:3029</SRS>
+ <SRS>EPSG:3030</SRS>
+ <SRS>EPSG:3031</SRS>
+ <SRS>EPSG:3032</SRS>
+ <SRS>EPSG:3033</SRS>
+ <SRS>EPSG:3034</SRS>
+ <SRS>EPSG:3035</SRS>
+ <SRS>EPSG:3036</SRS>
+ <SRS>EPSG:3037</SRS>
+ <SRS>EPSG:3038</SRS>
+ <SRS>EPSG:3039</SRS>
+ <SRS>EPSG:3040</SRS>
+ <SRS>EPSG:3041</SRS>
+ <SRS>EPSG:3042</SRS>
+ <SRS>EPSG:3043</SRS>
+ <SRS>EPSG:3044</SRS>
+ <SRS>EPSG:3045</SRS>
+ <SRS>EPSG:3046</SRS>
+ <SRS>EPSG:3047</SRS>
+ <SRS>EPSG:3048</SRS>
+ <SRS>EPSG:3049</SRS>
+ <SRS>EPSG:3050</SRS>
+ <SRS>EPSG:3051</SRS>
+ <SRS>EPSG:3052</SRS>
+ <SRS>EPSG:3053</SRS>
+ <SRS>EPSG:3054</SRS>
+ <SRS>EPSG:3055</SRS>
+ <SRS>EPSG:3056</SRS>
+ <SRS>EPSG:3057</SRS>
+ <SRS>EPSG:3058</SRS>
+ <SRS>EPSG:3059</SRS>
+ <SRS>EPSG:3060</SRS>
+ <SRS>EPSG:3061</SRS>
+ <SRS>EPSG:3062</SRS>
+ <SRS>EPSG:3063</SRS>
+ <SRS>EPSG:3064</SRS>
+ <SRS>EPSG:3065</SRS>
+ <SRS>EPSG:3066</SRS>
+ <SRS>EPSG:3067</SRS>
+ <SRS>EPSG:3068</SRS>
+ <SRS>EPSG:3069</SRS>
+ <SRS>EPSG:3070</SRS>
+ <SRS>EPSG:3071</SRS>
+ <SRS>EPSG:3072</SRS>
+ <SRS>EPSG:3073</SRS>
+ <SRS>EPSG:3074</SRS>
+ <SRS>EPSG:3075</SRS>
+ <SRS>EPSG:3076</SRS>
+ <SRS>EPSG:3077</SRS>
+ <SRS>EPSG:3078</SRS>
+ <SRS>EPSG:3079</SRS>
+ <SRS>EPSG:3080</SRS>
+ <SRS>EPSG:3081</SRS>
+ <SRS>EPSG:3082</SRS>
+ <SRS>EPSG:3083</SRS>
+ <SRS>EPSG:3084</SRS>
+ <SRS>EPSG:3085</SRS>
+ <SRS>EPSG:3086</SRS>
+ <SRS>EPSG:3087</SRS>
+ <SRS>EPSG:3088</SRS>
+ <SRS>EPSG:3089</SRS>
+ <SRS>EPSG:3090</SRS>
+ <SRS>EPSG:3091</SRS>
+ <SRS>EPSG:3092</SRS>
+ <SRS>EPSG:3093</SRS>
+ <SRS>EPSG:3094</SRS>
+ <SRS>EPSG:3095</SRS>
+ <SRS>EPSG:3096</SRS>
+ <SRS>EPSG:3097</SRS>
+ <SRS>EPSG:3098</SRS>
+ <SRS>EPSG:3099</SRS>
+ <SRS>EPSG:3100</SRS>
+ <SRS>EPSG:3101</SRS>
+ <SRS>EPSG:3102</SRS>
+ <SRS>EPSG:3103</SRS>
+ <SRS>EPSG:3104</SRS>
+ <SRS>EPSG:3105</SRS>
+ <SRS>EPSG:3106</SRS>
+ <SRS>EPSG:3107</SRS>
+ <SRS>EPSG:3108</SRS>
+ <SRS>EPSG:3109</SRS>
+ <SRS>EPSG:3110</SRS>
+ <SRS>EPSG:3111</SRS>
+ <SRS>EPSG:3112</SRS>
+ <SRS>EPSG:3113</SRS>
+ <SRS>EPSG:3114</SRS>
+ <SRS>EPSG:3115</SRS>
+ <SRS>EPSG:3116</SRS>
+ <SRS>EPSG:3117</SRS>
+ <SRS>EPSG:3118</SRS>
+ <SRS>EPSG:3119</SRS>
+ <SRS>EPSG:3120</SRS>
+ <SRS>EPSG:3121</SRS>
+ <SRS>EPSG:3122</SRS>
+ <SRS>EPSG:3123</SRS>
+ <SRS>EPSG:3124</SRS>
+ <SRS>EPSG:3125</SRS>
+ <SRS>EPSG:3126</SRS>
+ <SRS>EPSG:3127</SRS>
+ <SRS>EPSG:3128</SRS>
+ <SRS>EPSG:3129</SRS>
+ <SRS>EPSG:3130</SRS>
+ <SRS>EPSG:3131</SRS>
+ <SRS>EPSG:3132</SRS>
+ <SRS>EPSG:3133</SRS>
+ <SRS>EPSG:3134</SRS>
+ <SRS>EPSG:3135</SRS>
+ <SRS>EPSG:3136</SRS>
+ <SRS>EPSG:3137</SRS>
+ <SRS>EPSG:3138</SRS>
+ <SRS>EPSG:3139</SRS>
+ <SRS>EPSG:3140</SRS>
+ <SRS>EPSG:3141</SRS>
+ <SRS>EPSG:3142</SRS>
+ <SRS>EPSG:3143</SRS>
+ <SRS>EPSG:3144</SRS>
+ <SRS>EPSG:3145</SRS>
+ <SRS>EPSG:3146</SRS>
+ <SRS>EPSG:3147</SRS>
+ <SRS>EPSG:3148</SRS>
+ <SRS>EPSG:3149</SRS>
+ <SRS>EPSG:3150</SRS>
+ <SRS>EPSG:3151</SRS>
+ <SRS>EPSG:3152</SRS>
+ <SRS>EPSG:3153</SRS>
+ <SRS>EPSG:3154</SRS>
+ <SRS>EPSG:3155</SRS>
+ <SRS>EPSG:3156</SRS>
+ <SRS>EPSG:3157</SRS>
+ <SRS>EPSG:3158</SRS>
+ <SRS>EPSG:3159</SRS>
+ <SRS>EPSG:3160</SRS>
+ <SRS>EPSG:3161</SRS>
+ <SRS>EPSG:3162</SRS>
+ <SRS>EPSG:3163</SRS>
+ <SRS>EPSG:3164</SRS>
+ <SRS>EPSG:3165</SRS>
+ <SRS>EPSG:3166</SRS>
+ <SRS>EPSG:3167</SRS>
+ <SRS>EPSG:3168</SRS>
+ <SRS>EPSG:3169</SRS>
+ <SRS>EPSG:3170</SRS>
+ <SRS>EPSG:3171</SRS>
+ <SRS>EPSG:3172</SRS>
+ <SRS>EPSG:3173</SRS>
+ <SRS>EPSG:3174</SRS>
+ <SRS>EPSG:3175</SRS>
+ <SRS>EPSG:3176</SRS>
+ <SRS>EPSG:3177</SRS>
+ <SRS>EPSG:3178</SRS>
+ <SRS>EPSG:3179</SRS>
+ <SRS>EPSG:3180</SRS>
+ <SRS>EPSG:3181</SRS>
+ <SRS>EPSG:3182</SRS>
+ <SRS>EPSG:3183</SRS>
+ <SRS>EPSG:3184</SRS>
+ <SRS>EPSG:3185</SRS>
+ <SRS>EPSG:3186</SRS>
+ <SRS>EPSG:3187</SRS>
+ <SRS>EPSG:3188</SRS>
+ <SRS>EPSG:3189</SRS>
+ <SRS>EPSG:3190</SRS>
+ <SRS>EPSG:3191</SRS>
+ <SRS>EPSG:3192</SRS>
+ <SRS>EPSG:3193</SRS>
+ <SRS>EPSG:3194</SRS>
+ <SRS>EPSG:3195</SRS>
+ <SRS>EPSG:3196</SRS>
+ <SRS>EPSG:3197</SRS>
+ <SRS>EPSG:3198</SRS>
+ <SRS>EPSG:3199</SRS>
+ <SRS>EPSG:3200</SRS>
+ <SRS>EPSG:3201</SRS>
+ <SRS>EPSG:3202</SRS>
+ <SRS>EPSG:3203</SRS>
+ <SRS>EPSG:3204</SRS>
+ <SRS>EPSG:3205</SRS>
+ <SRS>EPSG:3206</SRS>
+ <SRS>EPSG:3207</SRS>
+ <SRS>EPSG:3208</SRS>
+ <SRS>EPSG:3209</SRS>
+ <SRS>EPSG:3210</SRS>
+ <SRS>EPSG:3211</SRS>
+ <SRS>EPSG:3212</SRS>
+ <SRS>EPSG:3213</SRS>
+ <SRS>EPSG:3214</SRS>
+ <SRS>EPSG:3215</SRS>
+ <SRS>EPSG:3216</SRS>
+ <SRS>EPSG:3217</SRS>
+ <SRS>EPSG:3218</SRS>
+ <SRS>EPSG:3219</SRS>
+ <SRS>EPSG:3220</SRS>
+ <SRS>EPSG:3221</SRS>
+ <SRS>EPSG:3222</SRS>
+ <SRS>EPSG:3223</SRS>
+ <SRS>EPSG:3224</SRS>
+ <SRS>EPSG:3225</SRS>
+ <SRS>EPSG:3226</SRS>
+ <SRS>EPSG:3227</SRS>
+ <SRS>EPSG:3228</SRS>
+ <SRS>EPSG:3229</SRS>
+ <SRS>EPSG:3230</SRS>
+ <SRS>EPSG:3231</SRS>
+ <SRS>EPSG:3232</SRS>
+ <SRS>EPSG:3233</SRS>
+ <SRS>EPSG:3234</SRS>
+ <SRS>EPSG:3235</SRS>
+ <SRS>EPSG:3236</SRS>
+ <SRS>EPSG:3237</SRS>
+ <SRS>EPSG:3238</SRS>
+ <SRS>EPSG:3239</SRS>
+ <SRS>EPSG:3240</SRS>
+ <SRS>EPSG:3241</SRS>
+ <SRS>EPSG:3242</SRS>
+ <SRS>EPSG:3243</SRS>
+ <SRS>EPSG:3244</SRS>
+ <SRS>EPSG:3245</SRS>
+ <SRS>EPSG:3246</SRS>
+ <SRS>EPSG:3247</SRS>
+ <SRS>EPSG:3248</SRS>
+ <SRS>EPSG:3249</SRS>
+ <SRS>EPSG:3250</SRS>
+ <SRS>EPSG:3251</SRS>
+ <SRS>EPSG:3252</SRS>
+ <SRS>EPSG:3253</SRS>
+ <SRS>EPSG:3254</SRS>
+ <SRS>EPSG:3255</SRS>
+ <SRS>EPSG:3256</SRS>
+ <SRS>EPSG:3257</SRS>
+ <SRS>EPSG:3258</SRS>
+ <SRS>EPSG:3259</SRS>
+ <SRS>EPSG:3260</SRS>
+ <SRS>EPSG:3261</SRS>
+ <SRS>EPSG:3262</SRS>
+ <SRS>EPSG:3263</SRS>
+ <SRS>EPSG:3264</SRS>
+ <SRS>EPSG:3265</SRS>
+ <SRS>EPSG:3266</SRS>
+ <SRS>EPSG:3267</SRS>
+ <SRS>EPSG:3268</SRS>
+ <SRS>EPSG:3269</SRS>
+ <SRS>EPSG:3270</SRS>
+ <SRS>EPSG:3271</SRS>
+ <SRS>EPSG:3272</SRS>
+ <SRS>EPSG:3273</SRS>
+ <SRS>EPSG:3274</SRS>
+ <SRS>EPSG:3275</SRS>
+ <SRS>EPSG:3276</SRS>
+ <SRS>EPSG:3277</SRS>
+ <SRS>EPSG:3278</SRS>
+ <SRS>EPSG:3279</SRS>
+ <SRS>EPSG:3280</SRS>
+ <SRS>EPSG:3281</SRS>
+ <SRS>EPSG:3282</SRS>
+ <SRS>EPSG:3283</SRS>
+ <SRS>EPSG:3284</SRS>
+ <SRS>EPSG:3285</SRS>
+ <SRS>EPSG:3286</SRS>
+ <SRS>EPSG:3287</SRS>
+ <SRS>EPSG:3288</SRS>
+ <SRS>EPSG:3289</SRS>
+ <SRS>EPSG:3290</SRS>
+ <SRS>EPSG:3291</SRS>
+ <SRS>EPSG:3292</SRS>
+ <SRS>EPSG:3293</SRS>
+ <SRS>EPSG:3294</SRS>
+ <SRS>EPSG:3295</SRS>
+ <SRS>EPSG:3296</SRS>
+ <SRS>EPSG:3297</SRS>
+ <SRS>EPSG:3298</SRS>
+ <SRS>EPSG:3299</SRS>
+ <SRS>EPSG:3300</SRS>
+ <SRS>EPSG:3301</SRS>
+ <SRS>EPSG:3302</SRS>
+ <SRS>EPSG:3303</SRS>
+ <SRS>EPSG:3304</SRS>
+ <SRS>EPSG:3305</SRS>
+ <SRS>EPSG:3306</SRS>
+ <SRS>EPSG:3307</SRS>
+ <SRS>EPSG:3308</SRS>
+ <SRS>EPSG:3309</SRS>
+ <SRS>EPSG:3310</SRS>
+ <SRS>EPSG:3311</SRS>
+ <SRS>EPSG:3312</SRS>
+ <SRS>EPSG:3313</SRS>
+ <SRS>EPSG:3314</SRS>
+ <SRS>EPSG:3315</SRS>
+ <SRS>EPSG:3316</SRS>
+ <SRS>EPSG:3317</SRS>
+ <SRS>EPSG:3318</SRS>
+ <SRS>EPSG:3319</SRS>
+ <SRS>EPSG:3320</SRS>
+ <SRS>EPSG:3321</SRS>
+ <SRS>EPSG:3322</SRS>
+ <SRS>EPSG:3323</SRS>
+ <SRS>EPSG:3324</SRS>
+ <SRS>EPSG:3325</SRS>
+ <SRS>EPSG:3326</SRS>
+ <SRS>EPSG:3327</SRS>
+ <SRS>EPSG:3328</SRS>
+ <SRS>EPSG:3329</SRS>
+ <SRS>EPSG:3330</SRS>
+ <SRS>EPSG:3331</SRS>
+ <SRS>EPSG:3332</SRS>
+ <SRS>EPSG:3333</SRS>
+ <SRS>EPSG:3334</SRS>
+ <SRS>EPSG:3335</SRS>
+ <SRS>EPSG:3336</SRS>
+ <SRS>EPSG:3337</SRS>
+ <SRS>EPSG:3338</SRS>
+ <SRS>EPSG:3339</SRS>
+ <SRS>EPSG:3340</SRS>
+ <SRS>EPSG:3341</SRS>
+ <SRS>EPSG:3342</SRS>
+ <SRS>EPSG:3343</SRS>
+ <SRS>EPSG:3344</SRS>
+ <SRS>EPSG:3345</SRS>
+ <SRS>EPSG:3346</SRS>
+ <SRS>EPSG:3347</SRS>
+ <SRS>EPSG:3348</SRS>
+ <SRS>EPSG:3349</SRS>
+ <SRS>EPSG:3350</SRS>
+ <SRS>EPSG:3351</SRS>
+ <SRS>EPSG:3352</SRS>
+ <SRS>EPSG:3353</SRS>
+ <SRS>EPSG:3354</SRS>
+ <SRS>EPSG:3355</SRS>
+ <SRS>EPSG:3356</SRS>
+ <SRS>EPSG:3357</SRS>
+ <SRS>EPSG:3358</SRS>
+ <SRS>EPSG:3359</SRS>
+ <SRS>EPSG:3360</SRS>
+ <SRS>EPSG:3361</SRS>
+ <SRS>EPSG:3362</SRS>
+ <SRS>EPSG:3363</SRS>
+ <SRS>EPSG:3364</SRS>
+ <SRS>EPSG:3365</SRS>
+ <SRS>EPSG:3366</SRS>
+ <SRS>EPSG:3367</SRS>
+ <SRS>EPSG:3368</SRS>
+ <SRS>EPSG:3369</SRS>
+ <SRS>EPSG:3370</SRS>
+ <SRS>EPSG:3371</SRS>
+ <SRS>EPSG:3372</SRS>
+ <SRS>EPSG:3373</SRS>
+ <SRS>EPSG:3374</SRS>
+ <SRS>EPSG:3375</SRS>
+ <SRS>EPSG:3376</SRS>
+ <SRS>EPSG:3377</SRS>
+ <SRS>EPSG:3378</SRS>
+ <SRS>EPSG:3379</SRS>
+ <SRS>EPSG:3380</SRS>
+ <SRS>EPSG:3381</SRS>
+ <SRS>EPSG:3382</SRS>
+ <SRS>EPSG:3383</SRS>
+ <SRS>EPSG:3384</SRS>
+ <SRS>EPSG:3385</SRS>
+ <SRS>EPSG:3386</SRS>
+ <SRS>EPSG:3387</SRS>
+ <SRS>EPSG:3388</SRS>
+ <SRS>EPSG:3389</SRS>
+ <SRS>EPSG:3390</SRS>
+ <SRS>EPSG:3391</SRS>
+ <SRS>EPSG:3392</SRS>
+ <SRS>EPSG:3393</SRS>
+ <SRS>EPSG:3394</SRS>
+ <SRS>EPSG:3395</SRS>
+ <SRS>EPSG:3396</SRS>
+ <SRS>EPSG:3397</SRS>
+ <SRS>EPSG:3398</SRS>
+ <SRS>EPSG:3399</SRS>
+ <SRS>EPSG:3400</SRS>
+ <SRS>EPSG:3401</SRS>
+ <SRS>EPSG:3402</SRS>
+ <SRS>EPSG:3403</SRS>
+ <SRS>EPSG:3404</SRS>
+ <SRS>EPSG:3405</SRS>
+ <SRS>EPSG:3406</SRS>
+ <SRS>EPSG:3407</SRS>
+ <SRS>EPSG:3408</SRS>
+ <SRS>EPSG:3409</SRS>
+ <SRS>EPSG:3410</SRS>
+ <SRS>EPSG:3411</SRS>
+ <SRS>EPSG:3412</SRS>
+ <SRS>EPSG:3413</SRS>
+ <SRS>EPSG:3414</SRS>
+ <SRS>EPSG:3415</SRS>
+ <SRS>EPSG:3416</SRS>
+ <SRS>EPSG:3417</SRS>
+ <SRS>EPSG:3418</SRS>
+ <SRS>EPSG:3419</SRS>
+ <SRS>EPSG:3420</SRS>
+ <SRS>EPSG:3421</SRS>
+ <SRS>EPSG:3422</SRS>
+ <SRS>EPSG:3423</SRS>
+ <SRS>EPSG:3424</SRS>
+ <SRS>EPSG:3425</SRS>
+ <SRS>EPSG:3426</SRS>
+ <SRS>EPSG:3427</SRS>
+ <SRS>EPSG:3428</SRS>
+ <SRS>EPSG:3429</SRS>
+ <SRS>EPSG:3430</SRS>
+ <SRS>EPSG:3431</SRS>
+ <SRS>EPSG:3432</SRS>
+ <SRS>EPSG:3433</SRS>
+ <SRS>EPSG:3434</SRS>
+ <SRS>EPSG:3435</SRS>
+ <SRS>EPSG:3436</SRS>
+ <SRS>EPSG:3437</SRS>
+ <SRS>EPSG:3438</SRS>
+ <SRS>EPSG:3439</SRS>
+ <SRS>EPSG:3440</SRS>
+ <SRS>EPSG:3441</SRS>
+ <SRS>EPSG:3442</SRS>
+ <SRS>EPSG:3443</SRS>
+ <SRS>EPSG:3444</SRS>
+ <SRS>EPSG:3445</SRS>
+ <SRS>EPSG:3446</SRS>
+ <SRS>EPSG:3447</SRS>
+ <SRS>EPSG:3448</SRS>
+ <SRS>EPSG:3449</SRS>
+ <SRS>EPSG:3450</SRS>
+ <SRS>EPSG:3451</SRS>
+ <SRS>EPSG:3452</SRS>
+ <SRS>EPSG:3453</SRS>
+ <SRS>EPSG:3454</SRS>
+ <SRS>EPSG:3455</SRS>
+ <SRS>EPSG:3456</SRS>
+ <SRS>EPSG:3457</SRS>
+ <SRS>EPSG:3458</SRS>
+ <SRS>EPSG:3459</SRS>
+ <SRS>EPSG:3460</SRS>
+ <SRS>EPSG:3461</SRS>
+ <SRS>EPSG:3462</SRS>
+ <SRS>EPSG:3463</SRS>
+ <SRS>EPSG:3464</SRS>
+ <SRS>EPSG:3560</SRS>
+ <SRS>EPSG:3561</SRS>
+ <SRS>EPSG:3562</SRS>
+ <SRS>EPSG:3563</SRS>
+ <SRS>EPSG:3564</SRS>
+ <SRS>EPSG:3565</SRS>
+ <SRS>EPSG:3566</SRS>
+ <SRS>EPSG:3567</SRS>
+ <SRS>EPSG:3568</SRS>
+ <SRS>EPSG:3569</SRS>
+ <SRS>EPSG:3570</SRS>
+ <SRS>EPSG:3571</SRS>
+ <SRS>EPSG:3572</SRS>
+ <SRS>EPSG:3573</SRS>
+ <SRS>EPSG:3574</SRS>
+ <SRS>EPSG:3575</SRS>
+ <SRS>EPSG:3576</SRS>
+ <SRS>EPSG:3577</SRS>
+ <SRS>EPSG:3920</SRS>
+ <SRS>EPSG:3991</SRS>
+ <SRS>EPSG:3992</SRS>
+ <SRS>EPSG:3993</SRS>
+ <SRS>EPSG:4001</SRS>
+ <SRS>EPSG:4002</SRS>
+ <SRS>EPSG:4003</SRS>
+ <SRS>EPSG:4004</SRS>
+ <SRS>EPSG:4005</SRS>
+ <SRS>EPSG:4006</SRS>
+ <SRS>EPSG:4007</SRS>
+ <SRS>EPSG:4008</SRS>
+ <SRS>EPSG:4009</SRS>
+ <SRS>EPSG:4010</SRS>
+ <SRS>EPSG:4011</SRS>
+ <SRS>EPSG:4012</SRS>
+ <SRS>EPSG:4013</SRS>
+ <SRS>EPSG:4014</SRS>
+ <SRS>EPSG:4015</SRS>
+ <SRS>EPSG:4016</SRS>
+ <SRS>EPSG:4018</SRS>
+ <SRS>EPSG:4019</SRS>
+ <SRS>EPSG:4020</SRS>
+ <SRS>EPSG:4021</SRS>
+ <SRS>EPSG:4022</SRS>
+ <SRS>EPSG:4024</SRS>
+ <SRS>EPSG:4025</SRS>
+ <SRS>EPSG:4027</SRS>
+ <SRS>EPSG:4028</SRS>
+ <SRS>EPSG:4029</SRS>
+ <SRS>EPSG:4030</SRS>
+ <SRS>EPSG:4031</SRS>
+ <SRS>EPSG:4032</SRS>
+ <SRS>EPSG:4033</SRS>
+ <SRS>EPSG:4034</SRS>
+ <SRS>EPSG:4035</SRS>
+ <SRS>EPSG:4036</SRS>
+ <SRS>EPSG:4041</SRS>
+ <SRS>EPSG:4042</SRS>
+ <SRS>EPSG:4043</SRS>
+ <SRS>EPSG:4044</SRS>
+ <SRS>EPSG:4045</SRS>
+ <SRS>EPSG:4047</SRS>
+ <SRS>EPSG:4052</SRS>
+ <SRS>EPSG:4053</SRS>
+ <SRS>EPSG:4054</SRS>
+ <SRS>EPSG:4120</SRS>
+ <SRS>EPSG:4121</SRS>
+ <SRS>EPSG:4122</SRS>
+ <SRS>EPSG:4123</SRS>
+ <SRS>EPSG:4124</SRS>
+ <SRS>EPSG:4125</SRS>
+ <SRS>EPSG:4126</SRS>
+ <SRS>EPSG:4127</SRS>
+ <SRS>EPSG:4128</SRS>
+ <SRS>EPSG:4129</SRS>
+ <SRS>EPSG:4130</SRS>
+ <SRS>EPSG:4131</SRS>
+ <SRS>EPSG:4132</SRS>
+ <SRS>EPSG:4133</SRS>
+ <SRS>EPSG:4134</SRS>
+ <SRS>EPSG:4135</SRS>
+ <SRS>EPSG:4136</SRS>
+ <SRS>EPSG:4137</SRS>
+ <SRS>EPSG:4138</SRS>
+ <SRS>EPSG:4139</SRS>
+ <SRS>EPSG:4140</SRS>
+ <SRS>EPSG:4141</SRS>
+ <SRS>EPSG:4142</SRS>
+ <SRS>EPSG:4143</SRS>
+ <SRS>EPSG:4144</SRS>
+ <SRS>EPSG:4145</SRS>
+ <SRS>EPSG:4146</SRS>
+ <SRS>EPSG:4147</SRS>
+ <SRS>EPSG:4148</SRS>
+ <SRS>EPSG:4149</SRS>
+ <SRS>EPSG:4150</SRS>
+ <SRS>EPSG:4151</SRS>
+ <SRS>EPSG:4152</SRS>
+ <SRS>EPSG:4153</SRS>
+ <SRS>EPSG:4154</SRS>
+ <SRS>EPSG:4155</SRS>
+ <SRS>EPSG:4156</SRS>
+ <SRS>EPSG:4157</SRS>
+ <SRS>EPSG:4158</SRS>
+ <SRS>EPSG:4159</SRS>
+ <SRS>EPSG:4160</SRS>
+ <SRS>EPSG:4161</SRS>
+ <SRS>EPSG:4162</SRS>
+ <SRS>EPSG:4163</SRS>
+ <SRS>EPSG:4164</SRS>
+ <SRS>EPSG:4165</SRS>
+ <SRS>EPSG:4166</SRS>
+ <SRS>EPSG:4167</SRS>
+ <SRS>EPSG:4168</SRS>
+ <SRS>EPSG:4169</SRS>
+ <SRS>EPSG:4170</SRS>
+ <SRS>EPSG:4171</SRS>
+ <SRS>EPSG:4172</SRS>
+ <SRS>EPSG:4173</SRS>
+ <SRS>EPSG:4174</SRS>
+ <SRS>EPSG:4175</SRS>
+ <SRS>EPSG:4176</SRS>
+ <SRS>EPSG:4178</SRS>
+ <SRS>EPSG:4179</SRS>
+ <SRS>EPSG:4180</SRS>
+ <SRS>EPSG:4181</SRS>
+ <SRS>EPSG:4182</SRS>
+ <SRS>EPSG:4183</SRS>
+ <SRS>EPSG:4184</SRS>
+ <SRS>EPSG:4185</SRS>
+ <SRS>EPSG:4188</SRS>
+ <SRS>EPSG:4189</SRS>
+ <SRS>EPSG:4190</SRS>
+ <SRS>EPSG:4191</SRS>
+ <SRS>EPSG:4192</SRS>
+ <SRS>EPSG:4193</SRS>
+ <SRS>EPSG:4194</SRS>
+ <SRS>EPSG:4195</SRS>
+ <SRS>EPSG:4196</SRS>
+ <SRS>EPSG:4197</SRS>
+ <SRS>EPSG:4198</SRS>
+ <SRS>EPSG:4199</SRS>
+ <SRS>EPSG:4200</SRS>
+ <SRS>EPSG:4201</SRS>
+ <SRS>EPSG:4202</SRS>
+ <SRS>EPSG:4203</SRS>
+ <SRS>EPSG:4204</SRS>
+ <SRS>EPSG:4205</SRS>
+ <SRS>EPSG:4206</SRS>
+ <SRS>EPSG:4207</SRS>
+ <SRS>EPSG:4208</SRS>
+ <SRS>EPSG:4209</SRS>
+ <SRS>EPSG:4210</SRS>
+ <SRS>EPSG:4211</SRS>
+ <SRS>EPSG:4212</SRS>
+ <SRS>EPSG:4213</SRS>
+ <SRS>EPSG:4214</SRS>
+ <SRS>EPSG:4215</SRS>
+ <SRS>EPSG:4216</SRS>
+ <SRS>EPSG:4218</SRS>
+ <SRS>EPSG:4219</SRS>
+ <SRS>EPSG:4220</SRS>
+ <SRS>EPSG:4221</SRS>
+ <SRS>EPSG:4222</SRS>
+ <SRS>EPSG:4223</SRS>
+ <SRS>EPSG:4224</SRS>
+ <SRS>EPSG:4225</SRS>
+ <SRS>EPSG:4226</SRS>
+ <SRS>EPSG:4227</SRS>
+ <SRS>EPSG:4228</SRS>
+ <SRS>EPSG:4229</SRS>
+ <SRS>EPSG:4230</SRS>
+ <SRS>EPSG:4231</SRS>
+ <SRS>EPSG:4232</SRS>
+ <SRS>EPSG:4233</SRS>
+ <SRS>EPSG:4234</SRS>
+ <SRS>EPSG:4235</SRS>
+ <SRS>EPSG:4236</SRS>
+ <SRS>EPSG:4237</SRS>
+ <SRS>EPSG:4238</SRS>
+ <SRS>EPSG:4239</SRS>
+ <SRS>EPSG:4240</SRS>
+ <SRS>EPSG:4241</SRS>
+ <SRS>EPSG:4242</SRS>
+ <SRS>EPSG:4243</SRS>
+ <SRS>EPSG:4244</SRS>
+ <SRS>EPSG:4245</SRS>
+ <SRS>EPSG:4246</SRS>
+ <SRS>EPSG:4247</SRS>
+ <SRS>EPSG:4248</SRS>
+ <SRS>EPSG:4249</SRS>
+ <SRS>EPSG:4250</SRS>
+ <SRS>EPSG:4251</SRS>
+ <SRS>EPSG:4252</SRS>
+ <SRS>EPSG:4253</SRS>
+ <SRS>EPSG:4254</SRS>
+ <SRS>EPSG:4255</SRS>
+ <SRS>EPSG:4256</SRS>
+ <SRS>EPSG:4257</SRS>
+ <SRS>EPSG:4258</SRS>
+ <SRS>EPSG:4259</SRS>
+ <SRS>EPSG:4260</SRS>
+ <SRS>EPSG:4261</SRS>
+ <SRS>EPSG:4262</SRS>
+ <SRS>EPSG:4263</SRS>
+ <SRS>EPSG:4264</SRS>
+ <SRS>EPSG:4265</SRS>
+ <SRS>EPSG:4266</SRS>
+ <SRS>EPSG:4267</SRS>
+ <SRS>EPSG:4268</SRS>
+ <SRS>EPSG:4269</SRS>
+ <SRS>EPSG:4270</SRS>
+ <SRS>EPSG:4271</SRS>
+ <SRS>EPSG:4272</SRS>
+ <SRS>EPSG:4273</SRS>
+ <SRS>EPSG:4274</SRS>
+ <SRS>EPSG:4275</SRS>
+ <SRS>EPSG:4276</SRS>
+ <SRS>EPSG:4277</SRS>
+ <SRS>EPSG:4278</SRS>
+ <SRS>EPSG:4279</SRS>
+ <SRS>EPSG:4280</SRS>
+ <SRS>EPSG:4281</SRS>
+ <SRS>EPSG:4282</SRS>
+ <SRS>EPSG:4283</SRS>
+ <SRS>EPSG:4284</SRS>
+ <SRS>EPSG:4285</SRS>
+ <SRS>EPSG:4286</SRS>
+ <SRS>EPSG:4287</SRS>
+ <SRS>EPSG:4288</SRS>
+ <SRS>EPSG:4289</SRS>
+ <SRS>EPSG:4291</SRS>
+ <SRS>EPSG:4292</SRS>
+ <SRS>EPSG:4293</SRS>
+ <SRS>EPSG:4294</SRS>
+ <SRS>EPSG:4295</SRS>
+ <SRS>EPSG:4296</SRS>
+ <SRS>EPSG:4297</SRS>
+ <SRS>EPSG:4298</SRS>
+ <SRS>EPSG:4299</SRS>
+ <SRS>EPSG:4300</SRS>
+ <SRS>EPSG:4301</SRS>
+ <SRS>EPSG:4302</SRS>
+ <SRS>EPSG:4303</SRS>
+ <SRS>EPSG:4304</SRS>
+ <SRS>EPSG:4306</SRS>
+ <SRS>EPSG:4307</SRS>
+ <SRS>EPSG:4308</SRS>
+ <SRS>EPSG:4309</SRS>
+ <SRS>EPSG:4310</SRS>
+ <SRS>EPSG:4311</SRS>
+ <SRS>EPSG:4312</SRS>
+ <SRS>EPSG:4313</SRS>
+ <SRS>EPSG:4314</SRS>
+ <SRS>EPSG:4315</SRS>
+ <SRS>EPSG:4316</SRS>
+ <SRS>EPSG:4317</SRS>
+ <SRS>EPSG:4318</SRS>
+ <SRS>EPSG:4319</SRS>
+ <SRS>EPSG:4322</SRS>
+ <SRS>EPSG:4324</SRS>
+ <SRS>EPSG:4326</SRS>
+ <SRS>EPSG:4327</SRS>
+ <SRS>EPSG:4328</SRS>
+ <SRS>EPSG:4329</SRS>
+ <SRS>EPSG:4330</SRS>
+ <SRS>EPSG:4331</SRS>
+ <SRS>EPSG:4332</SRS>
+ <SRS>EPSG:4333</SRS>
+ <SRS>EPSG:4334</SRS>
+ <SRS>EPSG:4335</SRS>
+ <SRS>EPSG:4336</SRS>
+ <SRS>EPSG:4337</SRS>
+ <SRS>EPSG:4338</SRS>
+ <SRS>EPSG:4339</SRS>
+ <SRS>EPSG:4340</SRS>
+ <SRS>EPSG:4341</SRS>
+ <SRS>EPSG:4342</SRS>
+ <SRS>EPSG:4343</SRS>
+ <SRS>EPSG:4344</SRS>
+ <SRS>EPSG:4345</SRS>
+ <SRS>EPSG:4346</SRS>
+ <SRS>EPSG:4347</SRS>
+ <SRS>EPSG:4348</SRS>
+ <SRS>EPSG:4349</SRS>
+ <SRS>EPSG:4350</SRS>
+ <SRS>EPSG:4351</SRS>
+ <SRS>EPSG:4352</SRS>
+ <SRS>EPSG:4353</SRS>
+ <SRS>EPSG:4354</SRS>
+ <SRS>EPSG:4355</SRS>
+ <SRS>EPSG:4356</SRS>
+ <SRS>EPSG:4357</SRS>
+ <SRS>EPSG:4358</SRS>
+ <SRS>EPSG:4359</SRS>
+ <SRS>EPSG:4360</SRS>
+ <SRS>EPSG:4361</SRS>
+ <SRS>EPSG:4362</SRS>
+ <SRS>EPSG:4363</SRS>
+ <SRS>EPSG:4364</SRS>
+ <SRS>EPSG:4365</SRS>
+ <SRS>EPSG:4366</SRS>
+ <SRS>EPSG:4367</SRS>
+ <SRS>EPSG:4368</SRS>
+ <SRS>EPSG:4369</SRS>
+ <SRS>EPSG:4370</SRS>
+ <SRS>EPSG:4371</SRS>
+ <SRS>EPSG:4372</SRS>
+ <SRS>EPSG:4373</SRS>
+ <SRS>EPSG:4374</SRS>
+ <SRS>EPSG:4375</SRS>
+ <SRS>EPSG:4376</SRS>
+ <SRS>EPSG:4377</SRS>
+ <SRS>EPSG:4378</SRS>
+ <SRS>EPSG:4379</SRS>
+ <SRS>EPSG:4380</SRS>
+ <SRS>EPSG:4381</SRS>
+ <SRS>EPSG:4382</SRS>
+ <SRS>EPSG:4383</SRS>
+ <SRS>EPSG:4384</SRS>
+ <SRS>EPSG:4385</SRS>
+ <SRS>EPSG:4386</SRS>
+ <SRS>EPSG:4387</SRS>
+ <SRS>EPSG:4388</SRS>
+ <SRS>EPSG:4389</SRS>
+ <SRS>EPSG:4600</SRS>
+ <SRS>EPSG:4601</SRS>
+ <SRS>EPSG:4602</SRS>
+ <SRS>EPSG:4603</SRS>
+ <SRS>EPSG:4604</SRS>
+ <SRS>EPSG:4605</SRS>
+ <SRS>EPSG:4606</SRS>
+ <SRS>EPSG:4607</SRS>
+ <SRS>EPSG:4608</SRS>
+ <SRS>EPSG:4609</SRS>
+ <SRS>EPSG:4610</SRS>
+ <SRS>EPSG:4611</SRS>
+ <SRS>EPSG:4612</SRS>
+ <SRS>EPSG:4613</SRS>
+ <SRS>EPSG:4614</SRS>
+ <SRS>EPSG:4615</SRS>
+ <SRS>EPSG:4616</SRS>
+ <SRS>EPSG:4617</SRS>
+ <SRS>EPSG:4618</SRS>
+ <SRS>EPSG:4619</SRS>
+ <SRS>EPSG:4620</SRS>
+ <SRS>EPSG:4621</SRS>
+ <SRS>EPSG:4622</SRS>
+ <SRS>EPSG:4623</SRS>
+ <SRS>EPSG:4624</SRS>
+ <SRS>EPSG:4625</SRS>
+ <SRS>EPSG:4626</SRS>
+ <SRS>EPSG:4627</SRS>
+ <SRS>EPSG:4628</SRS>
+ <SRS>EPSG:4629</SRS>
+ <SRS>EPSG:4630</SRS>
+ <SRS>EPSG:4631</SRS>
+ <SRS>EPSG:4632</SRS>
+ <SRS>EPSG:4633</SRS>
+ <SRS>EPSG:4634</SRS>
+ <SRS>EPSG:4635</SRS>
+ <SRS>EPSG:4636</SRS>
+ <SRS>EPSG:4637</SRS>
+ <SRS>EPSG:4638</SRS>
+ <SRS>EPSG:4639</SRS>
+ <SRS>EPSG:4640</SRS>
+ <SRS>EPSG:4641</SRS>
+ <SRS>EPSG:4642</SRS>
+ <SRS>EPSG:4643</SRS>
+ <SRS>EPSG:4644</SRS>
+ <SRS>EPSG:4645</SRS>
+ <SRS>EPSG:4646</SRS>
+ <SRS>EPSG:4657</SRS>
+ <SRS>EPSG:4658</SRS>
+ <SRS>EPSG:4659</SRS>
+ <SRS>EPSG:4660</SRS>
+ <SRS>EPSG:4661</SRS>
+ <SRS>EPSG:4662</SRS>
+ <SRS>EPSG:4663</SRS>
+ <SRS>EPSG:4664</SRS>
+ <SRS>EPSG:4665</SRS>
+ <SRS>EPSG:4666</SRS>
+ <SRS>EPSG:4667</SRS>
+ <SRS>EPSG:4668</SRS>
+ <SRS>EPSG:4669</SRS>
+ <SRS>EPSG:4670</SRS>
+ <SRS>EPSG:4671</SRS>
+ <SRS>EPSG:4672</SRS>
+ <SRS>EPSG:4673</SRS>
+ <SRS>EPSG:4674</SRS>
+ <SRS>EPSG:4675</SRS>
+ <SRS>EPSG:4676</SRS>
+ <SRS>EPSG:4677</SRS>
+ <SRS>EPSG:4678</SRS>
+ <SRS>EPSG:4679</SRS>
+ <SRS>EPSG:4680</SRS>
+ <SRS>EPSG:4681</SRS>
+ <SRS>EPSG:4682</SRS>
+ <SRS>EPSG:4683</SRS>
+ <SRS>EPSG:4684</SRS>
+ <SRS>EPSG:4685</SRS>
+ <SRS>EPSG:4686</SRS>
+ <SRS>EPSG:4687</SRS>
+ <SRS>EPSG:4688</SRS>
+ <SRS>EPSG:4689</SRS>
+ <SRS>EPSG:4690</SRS>
+ <SRS>EPSG:4691</SRS>
+ <SRS>EPSG:4692</SRS>
+ <SRS>EPSG:4693</SRS>
+ <SRS>EPSG:4694</SRS>
+ <SRS>EPSG:4695</SRS>
+ <SRS>EPSG:4696</SRS>
+ <SRS>EPSG:4697</SRS>
+ <SRS>EPSG:4698</SRS>
+ <SRS>EPSG:4699</SRS>
+ <SRS>EPSG:4700</SRS>
+ <SRS>EPSG:4701</SRS>
+ <SRS>EPSG:4702</SRS>
+ <SRS>EPSG:4703</SRS>
+ <SRS>EPSG:4704</SRS>
+ <SRS>EPSG:4705</SRS>
+ <SRS>EPSG:4706</SRS>
+ <SRS>EPSG:4707</SRS>
+ <SRS>EPSG:4708</SRS>
+ <SRS>EPSG:4709</SRS>
+ <SRS>EPSG:4710</SRS>
+ <SRS>EPSG:4711</SRS>
+ <SRS>EPSG:4712</SRS>
+ <SRS>EPSG:4713</SRS>
+ <SRS>EPSG:4714</SRS>
+ <SRS>EPSG:4715</SRS>
+ <SRS>EPSG:4716</SRS>
+ <SRS>EPSG:4717</SRS>
+ <SRS>EPSG:4718</SRS>
+ <SRS>EPSG:4719</SRS>
+ <SRS>EPSG:4720</SRS>
+ <SRS>EPSG:4721</SRS>
+ <SRS>EPSG:4722</SRS>
+ <SRS>EPSG:4723</SRS>
+ <SRS>EPSG:4724</SRS>
+ <SRS>EPSG:4725</SRS>
+ <SRS>EPSG:4726</SRS>
+ <SRS>EPSG:4727</SRS>
+ <SRS>EPSG:4728</SRS>
+ <SRS>EPSG:4729</SRS>
+ <SRS>EPSG:4730</SRS>
+ <SRS>EPSG:4731</SRS>
+ <SRS>EPSG:4732</SRS>
+ <SRS>EPSG:4733</SRS>
+ <SRS>EPSG:4734</SRS>
+ <SRS>EPSG:4735</SRS>
+ <SRS>EPSG:4736</SRS>
+ <SRS>EPSG:4737</SRS>
+ <SRS>EPSG:4738</SRS>
+ <SRS>EPSG:4739</SRS>
+ <SRS>EPSG:4740</SRS>
+ <SRS>EPSG:4741</SRS>
+ <SRS>EPSG:4742</SRS>
+ <SRS>EPSG:4743</SRS>
+ <SRS>EPSG:4744</SRS>
+ <SRS>EPSG:4745</SRS>
+ <SRS>EPSG:4746</SRS>
+ <SRS>EPSG:4747</SRS>
+ <SRS>EPSG:4748</SRS>
+ <SRS>EPSG:4749</SRS>
+ <SRS>EPSG:4750</SRS>
+ <SRS>EPSG:4751</SRS>
+ <SRS>EPSG:4752</SRS>
+ <SRS>EPSG:4753</SRS>
+ <SRS>EPSG:4754</SRS>
+ <SRS>EPSG:4755</SRS>
+ <SRS>EPSG:4756</SRS>
+ <SRS>EPSG:4757</SRS>
+ <SRS>EPSG:4758</SRS>
+ <SRS>EPSG:4801</SRS>
+ <SRS>EPSG:4802</SRS>
+ <SRS>EPSG:4803</SRS>
+ <SRS>EPSG:4804</SRS>
+ <SRS>EPSG:4805</SRS>
+ <SRS>EPSG:4806</SRS>
+ <SRS>EPSG:4807</SRS>
+ <SRS>EPSG:4808</SRS>
+ <SRS>EPSG:4809</SRS>
+ <SRS>EPSG:4810</SRS>
+ <SRS>EPSG:4811</SRS>
+ <SRS>EPSG:4813</SRS>
+ <SRS>EPSG:4814</SRS>
+ <SRS>EPSG:4815</SRS>
+ <SRS>EPSG:4816</SRS>
+ <SRS>EPSG:4817</SRS>
+ <SRS>EPSG:4818</SRS>
+ <SRS>EPSG:4819</SRS>
+ <SRS>EPSG:4820</SRS>
+ <SRS>EPSG:4821</SRS>
+ <SRS>EPSG:4894</SRS>
+ <SRS>EPSG:4895</SRS>
+ <SRS>EPSG:4896</SRS>
+ <SRS>EPSG:4897</SRS>
+ <SRS>EPSG:4898</SRS>
+ <SRS>EPSG:4899</SRS>
+ <SRS>EPSG:4900</SRS>
+ <SRS>EPSG:4901</SRS>
+ <SRS>EPSG:4902</SRS>
+ <SRS>EPSG:4903</SRS>
+ <SRS>EPSG:4904</SRS>
+ <SRS>EPSG:4906</SRS>
+ <SRS>EPSG:4907</SRS>
+ <SRS>EPSG:4908</SRS>
+ <SRS>EPSG:4909</SRS>
+ <SRS>EPSG:4910</SRS>
+ <SRS>EPSG:4911</SRS>
+ <SRS>EPSG:4912</SRS>
+ <SRS>EPSG:4913</SRS>
+ <SRS>EPSG:4914</SRS>
+ <SRS>EPSG:4915</SRS>
+ <SRS>EPSG:4916</SRS>
+ <SRS>EPSG:4917</SRS>
+ <SRS>EPSG:4918</SRS>
+ <SRS>EPSG:4919</SRS>
+ <SRS>EPSG:4920</SRS>
+ <SRS>EPSG:4921</SRS>
+ <SRS>EPSG:4922</SRS>
+ <SRS>EPSG:4923</SRS>
+ <SRS>EPSG:4924</SRS>
+ <SRS>EPSG:4925</SRS>
+ <SRS>EPSG:4926</SRS>
+ <SRS>EPSG:4927</SRS>
+ <SRS>EPSG:4928</SRS>
+ <SRS>EPSG:4929</SRS>
+ <SRS>EPSG:4930</SRS>
+ <SRS>EPSG:4931</SRS>
+ <SRS>EPSG:4932</SRS>
+ <SRS>EPSG:4933</SRS>
+ <SRS>EPSG:4934</SRS>
+ <SRS>EPSG:4935</SRS>
+ <SRS>EPSG:4936</SRS>
+ <SRS>EPSG:4937</SRS>
+ <SRS>EPSG:4938</SRS>
+ <SRS>EPSG:4939</SRS>
+ <SRS>EPSG:4940</SRS>
+ <SRS>EPSG:4941</SRS>
+ <SRS>EPSG:4942</SRS>
+ <SRS>EPSG:4943</SRS>
+ <SRS>EPSG:4944</SRS>
+ <SRS>EPSG:4945</SRS>
+ <SRS>EPSG:4946</SRS>
+ <SRS>EPSG:4947</SRS>
+ <SRS>EPSG:4948</SRS>
+ <SRS>EPSG:4949</SRS>
+ <SRS>EPSG:4950</SRS>
+ <SRS>EPSG:4951</SRS>
+ <SRS>EPSG:4952</SRS>
+ <SRS>EPSG:4953</SRS>
+ <SRS>EPSG:4954</SRS>
+ <SRS>EPSG:4955</SRS>
+ <SRS>EPSG:4956</SRS>
+ <SRS>EPSG:4957</SRS>
+ <SRS>EPSG:4958</SRS>
+ <SRS>EPSG:4959</SRS>
+ <SRS>EPSG:4960</SRS>
+ <SRS>EPSG:4961</SRS>
+ <SRS>EPSG:4962</SRS>
+ <SRS>EPSG:4963</SRS>
+ <SRS>EPSG:4964</SRS>
+ <SRS>EPSG:4965</SRS>
+ <SRS>EPSG:4966</SRS>
+ <SRS>EPSG:4967</SRS>
+ <SRS>EPSG:4968</SRS>
+ <SRS>EPSG:4969</SRS>
+ <SRS>EPSG:4970</SRS>
+ <SRS>EPSG:4971</SRS>
+ <SRS>EPSG:4972</SRS>
+ <SRS>EPSG:4973</SRS>
+ <SRS>EPSG:4974</SRS>
+ <SRS>EPSG:4975</SRS>
+ <SRS>EPSG:4976</SRS>
+ <SRS>EPSG:4977</SRS>
+ <SRS>EPSG:4978</SRS>
+ <SRS>EPSG:4979</SRS>
+ <SRS>EPSG:4980</SRS>
+ <SRS>EPSG:4981</SRS>
+ <SRS>EPSG:4982</SRS>
+ <SRS>EPSG:4983</SRS>
+ <SRS>EPSG:4984</SRS>
+ <SRS>EPSG:4985</SRS>
+ <SRS>EPSG:4986</SRS>
+ <SRS>EPSG:4987</SRS>
+ <SRS>EPSG:4988</SRS>
+ <SRS>EPSG:4989</SRS>
+ <SRS>EPSG:4990</SRS>
+ <SRS>EPSG:4991</SRS>
+ <SRS>EPSG:4992</SRS>
+ <SRS>EPSG:4993</SRS>
+ <SRS>EPSG:4994</SRS>
+ <SRS>EPSG:4995</SRS>
+ <SRS>EPSG:4996</SRS>
+ <SRS>EPSG:4997</SRS>
+ <SRS>EPSG:4998</SRS>
+ <SRS>EPSG:4999</SRS>
+ <SRS>EPSG:5600</SRS>
+ <SRS>EPSG:5601</SRS>
+ <SRS>EPSG:5602</SRS>
+ <SRS>EPSG:5603</SRS>
+ <SRS>EPSG:5604</SRS>
+ <SRS>EPSG:5605</SRS>
+ <SRS>EPSG:5606</SRS>
+ <SRS>EPSG:5607</SRS>
+ <SRS>EPSG:5608</SRS>
+ <SRS>EPSG:5609</SRS>
+ <SRS>EPSG:5701</SRS>
+ <SRS>EPSG:5702</SRS>
+ <SRS>EPSG:5703</SRS>
+ <SRS>EPSG:5704</SRS>
+ <SRS>EPSG:5705</SRS>
+ <SRS>EPSG:5706</SRS>
+ <SRS>EPSG:5709</SRS>
+ <SRS>EPSG:5710</SRS>
+ <SRS>EPSG:5711</SRS>
+ <SRS>EPSG:5712</SRS>
+ <SRS>EPSG:5713</SRS>
+ <SRS>EPSG:5714</SRS>
+ <SRS>EPSG:5715</SRS>
+ <SRS>EPSG:5716</SRS>
+ <SRS>EPSG:5717</SRS>
+ <SRS>EPSG:5718</SRS>
+ <SRS>EPSG:5719</SRS>
+ <SRS>EPSG:5720</SRS>
+ <SRS>EPSG:5721</SRS>
+ <SRS>EPSG:5722</SRS>
+ <SRS>EPSG:5723</SRS>
+ <SRS>EPSG:5724</SRS>
+ <SRS>EPSG:5725</SRS>
+ <SRS>EPSG:5726</SRS>
+ <SRS>EPSG:5727</SRS>
+ <SRS>EPSG:5728</SRS>
+ <SRS>EPSG:5729</SRS>
+ <SRS>EPSG:5730</SRS>
+ <SRS>EPSG:5731</SRS>
+ <SRS>EPSG:5732</SRS>
+ <SRS>EPSG:5733</SRS>
+ <SRS>EPSG:5734</SRS>
+ <SRS>EPSG:5735</SRS>
+ <SRS>EPSG:5736</SRS>
+ <SRS>EPSG:5737</SRS>
+ <SRS>EPSG:5738</SRS>
+ <SRS>EPSG:5739</SRS>
+ <SRS>EPSG:5740</SRS>
+ <SRS>EPSG:5741</SRS>
+ <SRS>EPSG:5742</SRS>
+ <SRS>EPSG:5743</SRS>
+ <SRS>EPSG:5744</SRS>
+ <SRS>EPSG:5745</SRS>
+ <SRS>EPSG:5746</SRS>
+ <SRS>EPSG:5747</SRS>
+ <SRS>EPSG:5748</SRS>
+ <SRS>EPSG:5749</SRS>
+ <SRS>EPSG:5750</SRS>
+ <SRS>EPSG:5751</SRS>
+ <SRS>EPSG:5752</SRS>
+ <SRS>EPSG:5753</SRS>
+ <SRS>EPSG:5754</SRS>
+ <SRS>EPSG:5755</SRS>
+ <SRS>EPSG:5756</SRS>
+ <SRS>EPSG:5757</SRS>
+ <SRS>EPSG:5758</SRS>
+ <SRS>EPSG:5759</SRS>
+ <SRS>EPSG:5760</SRS>
+ <SRS>EPSG:5761</SRS>
+ <SRS>EPSG:5762</SRS>
+ <SRS>EPSG:5763</SRS>
+ <SRS>EPSG:5764</SRS>
+ <SRS>EPSG:5765</SRS>
+ <SRS>EPSG:5766</SRS>
+ <SRS>EPSG:5767</SRS>
+ <SRS>EPSG:5768</SRS>
+ <SRS>EPSG:5769</SRS>
+ <SRS>EPSG:5770</SRS>
+ <SRS>EPSG:5771</SRS>
+ <SRS>EPSG:5772</SRS>
+ <SRS>EPSG:5773</SRS>
+ <SRS>EPSG:5774</SRS>
+ <SRS>EPSG:5775</SRS>
+ <SRS>EPSG:5776</SRS>
+ <SRS>EPSG:5777</SRS>
+ <SRS>EPSG:5778</SRS>
+ <SRS>EPSG:5779</SRS>
+ <SRS>EPSG:5780</SRS>
+ <SRS>EPSG:5781</SRS>
+ <SRS>EPSG:5782</SRS>
+ <SRS>EPSG:5783</SRS>
+ <SRS>EPSG:5784</SRS>
+ <SRS>EPSG:5785</SRS>
+ <SRS>EPSG:5786</SRS>
+ <SRS>EPSG:5787</SRS>
+ <SRS>EPSG:5788</SRS>
+ <SRS>EPSG:5789</SRS>
+ <SRS>EPSG:5790</SRS>
+ <SRS>EPSG:5791</SRS>
+ <SRS>EPSG:5792</SRS>
+ <SRS>EPSG:5793</SRS>
+ <SRS>EPSG:5794</SRS>
+ <SRS>EPSG:5795</SRS>
+ <SRS>EPSG:5796</SRS>
+ <SRS>EPSG:5797</SRS>
+ <SRS>EPSG:5798</SRS>
+ <SRS>EPSG:5799</SRS>
+ <SRS>EPSG:5800</SRS>
+ <SRS>EPSG:5801</SRS>
+ <SRS>EPSG:5802</SRS>
+ <SRS>EPSG:5803</SRS>
+ <SRS>EPSG:5804</SRS>
+ <SRS>EPSG:5805</SRS>
+ <SRS>EPSG:5806</SRS>
+ <SRS>EPSG:5807</SRS>
+ <SRS>EPSG:5808</SRS>
+ <SRS>EPSG:5809</SRS>
+ <SRS>EPSG:5810</SRS>
+ <SRS>EPSG:5811</SRS>
+ <SRS>EPSG:5812</SRS>
+ <SRS>EPSG:5813</SRS>
+ <SRS>EPSG:5814</SRS>
+ <SRS>EPSG:5815</SRS>
+ <SRS>EPSG:5816</SRS>
+ <SRS>EPSG:5817</SRS>
+ <SRS>EPSG:5818</SRS>
+ <SRS>EPSG:7400</SRS>
+ <SRS>EPSG:7401</SRS>
+ <SRS>EPSG:7402</SRS>
+ <SRS>EPSG:7403</SRS>
+ <SRS>EPSG:7404</SRS>
+ <SRS>EPSG:7405</SRS>
+ <SRS>EPSG:7406</SRS>
+ <SRS>EPSG:7407</SRS>
+ <SRS>EPSG:7408</SRS>
+ <SRS>EPSG:7409</SRS>
+ <SRS>EPSG:7410</SRS>
+ <SRS>EPSG:7411</SRS>
+ <SRS>EPSG:7412</SRS>
+ <SRS>EPSG:7413</SRS>
+ <SRS>EPSG:7414</SRS>
+ <SRS>EPSG:7415</SRS>
+ <SRS>EPSG:7416</SRS>
+ <SRS>EPSG:7417</SRS>
+ <SRS>EPSG:7418</SRS>
+ <SRS>EPSG:7419</SRS>
+ <SRS>EPSG:7420</SRS>
+ <SRS>EPSG:20004</SRS>
+ <SRS>EPSG:20005</SRS>
+ <SRS>EPSG:20006</SRS>
+ <SRS>EPSG:20007</SRS>
+ <SRS>EPSG:20008</SRS>
+ <SRS>EPSG:20009</SRS>
+ <SRS>EPSG:20010</SRS>
+ <SRS>EPSG:20011</SRS>
+ <SRS>EPSG:20012</SRS>
+ <SRS>EPSG:20013</SRS>
+ <SRS>EPSG:20014</SRS>
+ <SRS>EPSG:20015</SRS>
+ <SRS>EPSG:20016</SRS>
+ <SRS>EPSG:20017</SRS>
+ <SRS>EPSG:20018</SRS>
+ <SRS>EPSG:20019</SRS>
+ <SRS>EPSG:20020</SRS>
+ <SRS>EPSG:20021</SRS>
+ <SRS>EPSG:20022</SRS>
+ <SRS>EPSG:20023</SRS>
+ <SRS>EPSG:20024</SRS>
+ <SRS>EPSG:20025</SRS>
+ <SRS>EPSG:20026</SRS>
+ <SRS>EPSG:20027</SRS>
+ <SRS>EPSG:20028</SRS>
+ <SRS>EPSG:20029</SRS>
+ <SRS>EPSG:20030</SRS>
+ <SRS>EPSG:20031</SRS>
+ <SRS>EPSG:20032</SRS>
+ <SRS>EPSG:20064</SRS>
+ <SRS>EPSG:20065</SRS>
+ <SRS>EPSG:20066</SRS>
+ <SRS>EPSG:20067</SRS>
+ <SRS>EPSG:20068</SRS>
+ <SRS>EPSG:20069</SRS>
+ <SRS>EPSG:20070</SRS>
+ <SRS>EPSG:20071</SRS>
+ <SRS>EPSG:20072</SRS>
+ <SRS>EPSG:20073</SRS>
+ <SRS>EPSG:20074</SRS>
+ <SRS>EPSG:20075</SRS>
+ <SRS>EPSG:20076</SRS>
+ <SRS>EPSG:20077</SRS>
+ <SRS>EPSG:20078</SRS>
+ <SRS>EPSG:20079</SRS>
+ <SRS>EPSG:20080</SRS>
+ <SRS>EPSG:20081</SRS>
+ <SRS>EPSG:20082</SRS>
+ <SRS>EPSG:20083</SRS>
+ <SRS>EPSG:20084</SRS>
+ <SRS>EPSG:20085</SRS>
+ <SRS>EPSG:20086</SRS>
+ <SRS>EPSG:20087</SRS>
+ <SRS>EPSG:20088</SRS>
+ <SRS>EPSG:20089</SRS>
+ <SRS>EPSG:20090</SRS>
+ <SRS>EPSG:20091</SRS>
+ <SRS>EPSG:20092</SRS>
+ <SRS>EPSG:20135</SRS>
+ <SRS>EPSG:20136</SRS>
+ <SRS>EPSG:20137</SRS>
+ <SRS>EPSG:20138</SRS>
+ <SRS>EPSG:20248</SRS>
+ <SRS>EPSG:20249</SRS>
+ <SRS>EPSG:20250</SRS>
+ <SRS>EPSG:20251</SRS>
+ <SRS>EPSG:20252</SRS>
+ <SRS>EPSG:20253</SRS>
+ <SRS>EPSG:20254</SRS>
+ <SRS>EPSG:20255</SRS>
+ <SRS>EPSG:20256</SRS>
+ <SRS>EPSG:20257</SRS>
+ <SRS>EPSG:20258</SRS>
+ <SRS>EPSG:20348</SRS>
+ <SRS>EPSG:20349</SRS>
+ <SRS>EPSG:20350</SRS>
+ <SRS>EPSG:20351</SRS>
+ <SRS>EPSG:20352</SRS>
+ <SRS>EPSG:20353</SRS>
+ <SRS>EPSG:20354</SRS>
+ <SRS>EPSG:20355</SRS>
+ <SRS>EPSG:20356</SRS>
+ <SRS>EPSG:20357</SRS>
+ <SRS>EPSG:20358</SRS>
+ <SRS>EPSG:20436</SRS>
+ <SRS>EPSG:20437</SRS>
+ <SRS>EPSG:20438</SRS>
+ <SRS>EPSG:20439</SRS>
+ <SRS>EPSG:20440</SRS>
+ <SRS>EPSG:20499</SRS>
+ <SRS>EPSG:20538</SRS>
+ <SRS>EPSG:20539</SRS>
+ <SRS>EPSG:20790</SRS>
+ <SRS>EPSG:20791</SRS>
+ <SRS>EPSG:20822</SRS>
+ <SRS>EPSG:20823</SRS>
+ <SRS>EPSG:20824</SRS>
+ <SRS>EPSG:20934</SRS>
+ <SRS>EPSG:20935</SRS>
+ <SRS>EPSG:20936</SRS>
+ <SRS>EPSG:21035</SRS>
+ <SRS>EPSG:21036</SRS>
+ <SRS>EPSG:21037</SRS>
+ <SRS>EPSG:21095</SRS>
+ <SRS>EPSG:21096</SRS>
+ <SRS>EPSG:21097</SRS>
+ <SRS>EPSG:21100</SRS>
+ <SRS>EPSG:21148</SRS>
+ <SRS>EPSG:21149</SRS>
+ <SRS>EPSG:21150</SRS>
+ <SRS>EPSG:21291</SRS>
+ <SRS>EPSG:21292</SRS>
+ <SRS>EPSG:21413</SRS>
+ <SRS>EPSG:21414</SRS>
+ <SRS>EPSG:21415</SRS>
+ <SRS>EPSG:21416</SRS>
+ <SRS>EPSG:21417</SRS>
+ <SRS>EPSG:21418</SRS>
+ <SRS>EPSG:21419</SRS>
+ <SRS>EPSG:21420</SRS>
+ <SRS>EPSG:21421</SRS>
+ <SRS>EPSG:21422</SRS>
+ <SRS>EPSG:21423</SRS>
+ <SRS>EPSG:21453</SRS>
+ <SRS>EPSG:21454</SRS>
+ <SRS>EPSG:21455</SRS>
+ <SRS>EPSG:21456</SRS>
+ <SRS>EPSG:21457</SRS>
+ <SRS>EPSG:21458</SRS>
+ <SRS>EPSG:21459</SRS>
+ <SRS>EPSG:21460</SRS>
+ <SRS>EPSG:21461</SRS>
+ <SRS>EPSG:21462</SRS>
+ <SRS>EPSG:21463</SRS>
+ <SRS>EPSG:21473</SRS>
+ <SRS>EPSG:21474</SRS>
+ <SRS>EPSG:21475</SRS>
+ <SRS>EPSG:21476</SRS>
+ <SRS>EPSG:21477</SRS>
+ <SRS>EPSG:21478</SRS>
+ <SRS>EPSG:21479</SRS>
+ <SRS>EPSG:21480</SRS>
+ <SRS>EPSG:21481</SRS>
+ <SRS>EPSG:21482</SRS>
+ <SRS>EPSG:21483</SRS>
+ <SRS>EPSG:21500</SRS>
+ <SRS>EPSG:21780</SRS>
+ <SRS>EPSG:21781</SRS>
+ <SRS>EPSG:21817</SRS>
+ <SRS>EPSG:21818</SRS>
+ <SRS>EPSG:21891</SRS>
+ <SRS>EPSG:21892</SRS>
+ <SRS>EPSG:21893</SRS>
+ <SRS>EPSG:21894</SRS>
+ <SRS>EPSG:21896</SRS>
+ <SRS>EPSG:21897</SRS>
+ <SRS>EPSG:21898</SRS>
+ <SRS>EPSG:21899</SRS>
+ <SRS>EPSG:22032</SRS>
+ <SRS>EPSG:22033</SRS>
+ <SRS>EPSG:22091</SRS>
+ <SRS>EPSG:22092</SRS>
+ <SRS>EPSG:22171</SRS>
+ <SRS>EPSG:22172</SRS>
+ <SRS>EPSG:22173</SRS>
+ <SRS>EPSG:22174</SRS>
+ <SRS>EPSG:22175</SRS>
+ <SRS>EPSG:22176</SRS>
+ <SRS>EPSG:22177</SRS>
+ <SRS>EPSG:22181</SRS>
+ <SRS>EPSG:22182</SRS>
+ <SRS>EPSG:22183</SRS>
+ <SRS>EPSG:22184</SRS>
+ <SRS>EPSG:22185</SRS>
+ <SRS>EPSG:22186</SRS>
+ <SRS>EPSG:22187</SRS>
+ <SRS>EPSG:22191</SRS>
+ <SRS>EPSG:22192</SRS>
+ <SRS>EPSG:22193</SRS>
+ <SRS>EPSG:22194</SRS>
+ <SRS>EPSG:22195</SRS>
+ <SRS>EPSG:22196</SRS>
+ <SRS>EPSG:22197</SRS>
+ <SRS>EPSG:22234</SRS>
+ <SRS>EPSG:22235</SRS>
+ <SRS>EPSG:22236</SRS>
+ <SRS>EPSG:22275</SRS>
+ <SRS>EPSG:22277</SRS>
+ <SRS>EPSG:22279</SRS>
+ <SRS>EPSG:22281</SRS>
+ <SRS>EPSG:22283</SRS>
+ <SRS>EPSG:22285</SRS>
+ <SRS>EPSG:22287</SRS>
+ <SRS>EPSG:22289</SRS>
+ <SRS>EPSG:22291</SRS>
+ <SRS>EPSG:22293</SRS>
+ <SRS>EPSG:22300</SRS>
+ <SRS>EPSG:22332</SRS>
+ <SRS>EPSG:22391</SRS>
+ <SRS>EPSG:22392</SRS>
+ <SRS>EPSG:22521</SRS>
+ <SRS>EPSG:22522</SRS>
+ <SRS>EPSG:22523</SRS>
+ <SRS>EPSG:22524</SRS>
+ <SRS>EPSG:22525</SRS>
+ <SRS>EPSG:22700</SRS>
+ <SRS>EPSG:22770</SRS>
+ <SRS>EPSG:22780</SRS>
+ <SRS>EPSG:22832</SRS>
+ <SRS>EPSG:22991</SRS>
+ <SRS>EPSG:22992</SRS>
+ <SRS>EPSG:22993</SRS>
+ <SRS>EPSG:22994</SRS>
+ <SRS>EPSG:23028</SRS>
+ <SRS>EPSG:23029</SRS>
+ <SRS>EPSG:23030</SRS>
+ <SRS>EPSG:23031</SRS>
+ <SRS>EPSG:23032</SRS>
+ <SRS>EPSG:23033</SRS>
+ <SRS>EPSG:23034</SRS>
+ <SRS>EPSG:23035</SRS>
+ <SRS>EPSG:23036</SRS>
+ <SRS>EPSG:23037</SRS>
+ <SRS>EPSG:23038</SRS>
+ <SRS>EPSG:23090</SRS>
+ <SRS>EPSG:23095</SRS>
+ <SRS>EPSG:23239</SRS>
+ <SRS>EPSG:23240</SRS>
+ <SRS>EPSG:23433</SRS>
+ <SRS>EPSG:23700</SRS>
+ <SRS>EPSG:23846</SRS>
+ <SRS>EPSG:23847</SRS>
+ <SRS>EPSG:23848</SRS>
+ <SRS>EPSG:23849</SRS>
+ <SRS>EPSG:23850</SRS>
+ <SRS>EPSG:23851</SRS>
+ <SRS>EPSG:23852</SRS>
+ <SRS>EPSG:23853</SRS>
+ <SRS>EPSG:23866</SRS>
+ <SRS>EPSG:23867</SRS>
+ <SRS>EPSG:23868</SRS>
+ <SRS>EPSG:23869</SRS>
+ <SRS>EPSG:23870</SRS>
+ <SRS>EPSG:23871</SRS>
+ <SRS>EPSG:23872</SRS>
+ <SRS>EPSG:23877</SRS>
+ <SRS>EPSG:23878</SRS>
+ <SRS>EPSG:23879</SRS>
+ <SRS>EPSG:23880</SRS>
+ <SRS>EPSG:23881</SRS>
+ <SRS>EPSG:23882</SRS>
+ <SRS>EPSG:23883</SRS>
+ <SRS>EPSG:23884</SRS>
+ <SRS>EPSG:23886</SRS>
+ <SRS>EPSG:23887</SRS>
+ <SRS>EPSG:23888</SRS>
+ <SRS>EPSG:23889</SRS>
+ <SRS>EPSG:23890</SRS>
+ <SRS>EPSG:23891</SRS>
+ <SRS>EPSG:23892</SRS>
+ <SRS>EPSG:23893</SRS>
+ <SRS>EPSG:23894</SRS>
+ <SRS>EPSG:23946</SRS>
+ <SRS>EPSG:23947</SRS>
+ <SRS>EPSG:23948</SRS>
+ <SRS>EPSG:24047</SRS>
+ <SRS>EPSG:24048</SRS>
+ <SRS>EPSG:24100</SRS>
+ <SRS>EPSG:24200</SRS>
+ <SRS>EPSG:24305</SRS>
+ <SRS>EPSG:24306</SRS>
+ <SRS>EPSG:24311</SRS>
+ <SRS>EPSG:24312</SRS>
+ <SRS>EPSG:24313</SRS>
+ <SRS>EPSG:24342</SRS>
+ <SRS>EPSG:24343</SRS>
+ <SRS>EPSG:24344</SRS>
+ <SRS>EPSG:24345</SRS>
+ <SRS>EPSG:24346</SRS>
+ <SRS>EPSG:24347</SRS>
+ <SRS>EPSG:24370</SRS>
+ <SRS>EPSG:24371</SRS>
+ <SRS>EPSG:24372</SRS>
+ <SRS>EPSG:24373</SRS>
+ <SRS>EPSG:24374</SRS>
+ <SRS>EPSG:24375</SRS>
+ <SRS>EPSG:24376</SRS>
+ <SRS>EPSG:24377</SRS>
+ <SRS>EPSG:24378</SRS>
+ <SRS>EPSG:24379</SRS>
+ <SRS>EPSG:24380</SRS>
+ <SRS>EPSG:24381</SRS>
+ <SRS>EPSG:24382</SRS>
+ <SRS>EPSG:24383</SRS>
+ <SRS>EPSG:24500</SRS>
+ <SRS>EPSG:24547</SRS>
+ <SRS>EPSG:24548</SRS>
+ <SRS>EPSG:24571</SRS>
+ <SRS>EPSG:24600</SRS>
+ <SRS>EPSG:24718</SRS>
+ <SRS>EPSG:24719</SRS>
+ <SRS>EPSG:24720</SRS>
+ <SRS>EPSG:24817</SRS>
+ <SRS>EPSG:24818</SRS>
+ <SRS>EPSG:24819</SRS>
+ <SRS>EPSG:24820</SRS>
+ <SRS>EPSG:24821</SRS>
+ <SRS>EPSG:24877</SRS>
+ <SRS>EPSG:24878</SRS>
+ <SRS>EPSG:24879</SRS>
+ <SRS>EPSG:24880</SRS>
+ <SRS>EPSG:24881</SRS>
+ <SRS>EPSG:24882</SRS>
+ <SRS>EPSG:24891</SRS>
+ <SRS>EPSG:24892</SRS>
+ <SRS>EPSG:24893</SRS>
+ <SRS>EPSG:25000</SRS>
+ <SRS>EPSG:25231</SRS>
+ <SRS>EPSG:25391</SRS>
+ <SRS>EPSG:25392</SRS>
+ <SRS>EPSG:25393</SRS>
+ <SRS>EPSG:25394</SRS>
+ <SRS>EPSG:25395</SRS>
+ <SRS>EPSG:25700</SRS>
+ <SRS>EPSG:25828</SRS>
+ <SRS>EPSG:25829</SRS>
+ <SRS>EPSG:25830</SRS>
+ <SRS>EPSG:25831</SRS>
+ <SRS>EPSG:25832</SRS>
+ <SRS>EPSG:25833</SRS>
+ <SRS>EPSG:25834</SRS>
+ <SRS>EPSG:25835</SRS>
+ <SRS>EPSG:25836</SRS>
+ <SRS>EPSG:25837</SRS>
+ <SRS>EPSG:25838</SRS>
+ <SRS>EPSG:25884</SRS>
+ <SRS>EPSG:25932</SRS>
+ <SRS>EPSG:26191</SRS>
+ <SRS>EPSG:26192</SRS>
+ <SRS>EPSG:26193</SRS>
+ <SRS>EPSG:26194</SRS>
+ <SRS>EPSG:26195</SRS>
+ <SRS>EPSG:26237</SRS>
+ <SRS>EPSG:26331</SRS>
+ <SRS>EPSG:26332</SRS>
+ <SRS>EPSG:26391</SRS>
+ <SRS>EPSG:26392</SRS>
+ <SRS>EPSG:26393</SRS>
+ <SRS>EPSG:26432</SRS>
+ <SRS>EPSG:26591</SRS>
+ <SRS>EPSG:26592</SRS>
+ <SRS>EPSG:26632</SRS>
+ <SRS>EPSG:26692</SRS>
+ <SRS>EPSG:26701</SRS>
+ <SRS>EPSG:26702</SRS>
+ <SRS>EPSG:26703</SRS>
+ <SRS>EPSG:26704</SRS>
+ <SRS>EPSG:26705</SRS>
+ <SRS>EPSG:26706</SRS>
+ <SRS>EPSG:26707</SRS>
+ <SRS>EPSG:26708</SRS>
+ <SRS>EPSG:26709</SRS>
+ <SRS>EPSG:26710</SRS>
+ <SRS>EPSG:26711</SRS>
+ <SRS>EPSG:26712</SRS>
+ <SRS>EPSG:26713</SRS>
+ <SRS>EPSG:26714</SRS>
+ <SRS>EPSG:26715</SRS>
+ <SRS>EPSG:26716</SRS>
+ <SRS>EPSG:26717</SRS>
+ <SRS>EPSG:26718</SRS>
+ <SRS>EPSG:26719</SRS>
+ <SRS>EPSG:26720</SRS>
+ <SRS>EPSG:26721</SRS>
+ <SRS>EPSG:26722</SRS>
+ <SRS>EPSG:26729</SRS>
+ <SRS>EPSG:26730</SRS>
+ <SRS>EPSG:26731</SRS>
+ <SRS>EPSG:26732</SRS>
+ <SRS>EPSG:26733</SRS>
+ <SRS>EPSG:26734</SRS>
+ <SRS>EPSG:26735</SRS>
+ <SRS>EPSG:26736</SRS>
+ <SRS>EPSG:26737</SRS>
+ <SRS>EPSG:26738</SRS>
+ <SRS>EPSG:26739</SRS>
+ <SRS>EPSG:26740</SRS>
+ <SRS>EPSG:26741</SRS>
+ <SRS>EPSG:26742</SRS>
+ <SRS>EPSG:26743</SRS>
+ <SRS>EPSG:26744</SRS>
+ <SRS>EPSG:26745</SRS>
+ <SRS>EPSG:26746</SRS>
+ <SRS>EPSG:26747</SRS>
+ <SRS>EPSG:26748</SRS>
+ <SRS>EPSG:26749</SRS>
+ <SRS>EPSG:26750</SRS>
+ <SRS>EPSG:26751</SRS>
+ <SRS>EPSG:26752</SRS>
+ <SRS>EPSG:26753</SRS>
+ <SRS>EPSG:26754</SRS>
+ <SRS>EPSG:26755</SRS>
+ <SRS>EPSG:26756</SRS>
+ <SRS>EPSG:26757</SRS>
+ <SRS>EPSG:26758</SRS>
+ <SRS>EPSG:26759</SRS>
+ <SRS>EPSG:26760</SRS>
+ <SRS>EPSG:26766</SRS>
+ <SRS>EPSG:26767</SRS>
+ <SRS>EPSG:26768</SRS>
+ <SRS>EPSG:26769</SRS>
+ <SRS>EPSG:26770</SRS>
+ <SRS>EPSG:26771</SRS>
+ <SRS>EPSG:26772</SRS>
+ <SRS>EPSG:26773</SRS>
+ <SRS>EPSG:26774</SRS>
+ <SRS>EPSG:26775</SRS>
+ <SRS>EPSG:26776</SRS>
+ <SRS>EPSG:26777</SRS>
+ <SRS>EPSG:26778</SRS>
+ <SRS>EPSG:26779</SRS>
+ <SRS>EPSG:26780</SRS>
+ <SRS>EPSG:26781</SRS>
+ <SRS>EPSG:26782</SRS>
+ <SRS>EPSG:26783</SRS>
+ <SRS>EPSG:26784</SRS>
+ <SRS>EPSG:26785</SRS>
+ <SRS>EPSG:26786</SRS>
+ <SRS>EPSG:26787</SRS>
+ <SRS>EPSG:26791</SRS>
+ <SRS>EPSG:26792</SRS>
+ <SRS>EPSG:26793</SRS>
+ <SRS>EPSG:26794</SRS>
+ <SRS>EPSG:26795</SRS>
+ <SRS>EPSG:26796</SRS>
+ <SRS>EPSG:26797</SRS>
+ <SRS>EPSG:26798</SRS>
+ <SRS>EPSG:26799</SRS>
+ <SRS>EPSG:26801</SRS>
+ <SRS>EPSG:26802</SRS>
+ <SRS>EPSG:26803</SRS>
+ <SRS>EPSG:26811</SRS>
+ <SRS>EPSG:26812</SRS>
+ <SRS>EPSG:26813</SRS>
+ <SRS>EPSG:26901</SRS>
+ <SRS>EPSG:26902</SRS>
+ <SRS>EPSG:26903</SRS>
+ <SRS>EPSG:26904</SRS>
+ <SRS>EPSG:26905</SRS>
+ <SRS>EPSG:26906</SRS>
+ <SRS>EPSG:26907</SRS>
+ <SRS>EPSG:26908</SRS>
+ <SRS>EPSG:26909</SRS>
+ <SRS>EPSG:26910</SRS>
+ <SRS>EPSG:26911</SRS>
+ <SRS>EPSG:26912</SRS>
+ <SRS>EPSG:26913</SRS>
+ <SRS>EPSG:26914</SRS>
+ <SRS>EPSG:26915</SRS>
+ <SRS>EPSG:26916</SRS>
+ <SRS>EPSG:26917</SRS>
+ <SRS>EPSG:26918</SRS>
+ <SRS>EPSG:26919</SRS>
+ <SRS>EPSG:26920</SRS>
+ <SRS>EPSG:26921</SRS>
+ <SRS>EPSG:26922</SRS>
+ <SRS>EPSG:26923</SRS>
+ <SRS>EPSG:26929</SRS>
+ <SRS>EPSG:26930</SRS>
+ <SRS>EPSG:26931</SRS>
+ <SRS>EPSG:26932</SRS>
+ <SRS>EPSG:26933</SRS>
+ <SRS>EPSG:26934</SRS>
+ <SRS>EPSG:26935</SRS>
+ <SRS>EPSG:26936</SRS>
+ <SRS>EPSG:26937</SRS>
+ <SRS>EPSG:26938</SRS>
+ <SRS>EPSG:26939</SRS>
+ <SRS>EPSG:26940</SRS>
+ <SRS>EPSG:26941</SRS>
+ <SRS>EPSG:26942</SRS>
+ <SRS>EPSG:26943</SRS>
+ <SRS>EPSG:26944</SRS>
+ <SRS>EPSG:26945</SRS>
+ <SRS>EPSG:26946</SRS>
+ <SRS>EPSG:26948</SRS>
+ <SRS>EPSG:26949</SRS>
+ <SRS>EPSG:26950</SRS>
+ <SRS>EPSG:26951</SRS>
+ <SRS>EPSG:26952</SRS>
+ <SRS>EPSG:26953</SRS>
+ <SRS>EPSG:26954</SRS>
+ <SRS>EPSG:26955</SRS>
+ <SRS>EPSG:26956</SRS>
+ <SRS>EPSG:26957</SRS>
+ <SRS>EPSG:26958</SRS>
+ <SRS>EPSG:26959</SRS>
+ <SRS>EPSG:26960</SRS>
+ <SRS>EPSG:26961</SRS>
+ <SRS>EPSG:26962</SRS>
+ <SRS>EPSG:26963</SRS>
+ <SRS>EPSG:26964</SRS>
+ <SRS>EPSG:26965</SRS>
+ <SRS>EPSG:26966</SRS>
+ <SRS>EPSG:26967</SRS>
+ <SRS>EPSG:26968</SRS>
+ <SRS>EPSG:26969</SRS>
+ <SRS>EPSG:26970</SRS>
+ <SRS>EPSG:26971</SRS>
+ <SRS>EPSG:26972</SRS>
+ <SRS>EPSG:26973</SRS>
+ <SRS>EPSG:26974</SRS>
+ <SRS>EPSG:26975</SRS>
+ <SRS>EPSG:26976</SRS>
+ <SRS>EPSG:26977</SRS>
+ <SRS>EPSG:26978</SRS>
+ <SRS>EPSG:26979</SRS>
+ <SRS>EPSG:26980</SRS>
+ <SRS>EPSG:26981</SRS>
+ <SRS>EPSG:26982</SRS>
+ <SRS>EPSG:26983</SRS>
+ <SRS>EPSG:26984</SRS>
+ <SRS>EPSG:26985</SRS>
+ <SRS>EPSG:26986</SRS>
+ <SRS>EPSG:26987</SRS>
+ <SRS>EPSG:26988</SRS>
+ <SRS>EPSG:26989</SRS>
+ <SRS>EPSG:26990</SRS>
+ <SRS>EPSG:26991</SRS>
+ <SRS>EPSG:26992</SRS>
+ <SRS>EPSG:26993</SRS>
+ <SRS>EPSG:26994</SRS>
+ <SRS>EPSG:26995</SRS>
+ <SRS>EPSG:26996</SRS>
+ <SRS>EPSG:26997</SRS>
+ <SRS>EPSG:26998</SRS>
+ <SRS>EPSG:27037</SRS>
+ <SRS>EPSG:27038</SRS>
+ <SRS>EPSG:27039</SRS>
+ <SRS>EPSG:27040</SRS>
+ <SRS>EPSG:27120</SRS>
+ <SRS>EPSG:27200</SRS>
+ <SRS>EPSG:27205</SRS>
+ <SRS>EPSG:27206</SRS>
+ <SRS>EPSG:27207</SRS>
+ <SRS>EPSG:27208</SRS>
+ <SRS>EPSG:27209</SRS>
+ <SRS>EPSG:27210</SRS>
+ <SRS>EPSG:27211</SRS>
+ <SRS>EPSG:27212</SRS>
+ <SRS>EPSG:27213</SRS>
+ <SRS>EPSG:27214</SRS>
+ <SRS>EPSG:27215</SRS>
+ <SRS>EPSG:27216</SRS>
+ <SRS>EPSG:27217</SRS>
+ <SRS>EPSG:27218</SRS>
+ <SRS>EPSG:27219</SRS>
+ <SRS>EPSG:27220</SRS>
+ <SRS>EPSG:27221</SRS>
+ <SRS>EPSG:27222</SRS>
+ <SRS>EPSG:27223</SRS>
+ <SRS>EPSG:27224</SRS>
+ <SRS>EPSG:27225</SRS>
+ <SRS>EPSG:27226</SRS>
+ <SRS>EPSG:27227</SRS>
+ <SRS>EPSG:27228</SRS>
+ <SRS>EPSG:27229</SRS>
+ <SRS>EPSG:27230</SRS>
+ <SRS>EPSG:27231</SRS>
+ <SRS>EPSG:27232</SRS>
+ <SRS>EPSG:27258</SRS>
+ <SRS>EPSG:27259</SRS>
+ <SRS>EPSG:27260</SRS>
+ <SRS>EPSG:27291</SRS>
+ <SRS>EPSG:27292</SRS>
+ <SRS>EPSG:27391</SRS>
+ <SRS>EPSG:27392</SRS>
+ <SRS>EPSG:27393</SRS>
+ <SRS>EPSG:27394</SRS>
+ <SRS>EPSG:27395</SRS>
+ <SRS>EPSG:27396</SRS>
+ <SRS>EPSG:27397</SRS>
+ <SRS>EPSG:27398</SRS>
+ <SRS>EPSG:27429</SRS>
+ <SRS>EPSG:27492</SRS>
+ <SRS>EPSG:27500</SRS>
+ <SRS>EPSG:27561</SRS>
+ <SRS>EPSG:27562</SRS>
+ <SRS>EPSG:27563</SRS>
+ <SRS>EPSG:27564</SRS>
+ <SRS>EPSG:27571</SRS>
+ <SRS>EPSG:27572</SRS>
+ <SRS>EPSG:27573</SRS>
+ <SRS>EPSG:27574</SRS>
+ <SRS>EPSG:27581</SRS>
+ <SRS>EPSG:27582</SRS>
+ <SRS>EPSG:27583</SRS>
+ <SRS>EPSG:27584</SRS>
+ <SRS>EPSG:27591</SRS>
+ <SRS>EPSG:27592</SRS>
+ <SRS>EPSG:27593</SRS>
+ <SRS>EPSG:27594</SRS>
+ <SRS>EPSG:27700</SRS>
+ <SRS>EPSG:28191</SRS>
+ <SRS>EPSG:28192</SRS>
+ <SRS>EPSG:28193</SRS>
+ <SRS>EPSG:28232</SRS>
+ <SRS>EPSG:28348</SRS>
+ <SRS>EPSG:28349</SRS>
+ <SRS>EPSG:28350</SRS>
+ <SRS>EPSG:28351</SRS>
+ <SRS>EPSG:28352</SRS>
+ <SRS>EPSG:28353</SRS>
+ <SRS>EPSG:28354</SRS>
+ <SRS>EPSG:28355</SRS>
+ <SRS>EPSG:28356</SRS>
+ <SRS>EPSG:28357</SRS>
+ <SRS>EPSG:28358</SRS>
+ <SRS>EPSG:28402</SRS>
+ <SRS>EPSG:28403</SRS>
+ <SRS>EPSG:28404</SRS>
+ <SRS>EPSG:28405</SRS>
+ <SRS>EPSG:28406</SRS>
+ <SRS>EPSG:28407</SRS>
+ <SRS>EPSG:28408</SRS>
+ <SRS>EPSG:28409</SRS>
+ <SRS>EPSG:28410</SRS>
+ <SRS>EPSG:28411</SRS>
+ <SRS>EPSG:28412</SRS>
+ <SRS>EPSG:28413</SRS>
+ <SRS>EPSG:28414</SRS>
+ <SRS>EPSG:28415</SRS>
+ <SRS>EPSG:28416</SRS>
+ <SRS>EPSG:28417</SRS>
+ <SRS>EPSG:28418</SRS>
+ <SRS>EPSG:28419</SRS>
+ <SRS>EPSG:28420</SRS>
+ <SRS>EPSG:28421</SRS>
+ <SRS>EPSG:28422</SRS>
+ <SRS>EPSG:28423</SRS>
+ <SRS>EPSG:28424</SRS>
+ <SRS>EPSG:28425</SRS>
+ <SRS>EPSG:28426</SRS>
+ <SRS>EPSG:28427</SRS>
+ <SRS>EPSG:28428</SRS>
+ <SRS>EPSG:28429</SRS>
+ <SRS>EPSG:28430</SRS>
+ <SRS>EPSG:28431</SRS>
+ <SRS>EPSG:28432</SRS>
+ <SRS>EPSG:28462</SRS>
+ <SRS>EPSG:28463</SRS>
+ <SRS>EPSG:28464</SRS>
+ <SRS>EPSG:28465</SRS>
+ <SRS>EPSG:28466</SRS>
+ <SRS>EPSG:28467</SRS>
+ <SRS>EPSG:28468</SRS>
+ <SRS>EPSG:28469</SRS>
+ <SRS>EPSG:28470</SRS>
+ <SRS>EPSG:28471</SRS>
+ <SRS>EPSG:28472</SRS>
+ <SRS>EPSG:28473</SRS>
+ <SRS>EPSG:28474</SRS>
+ <SRS>EPSG:28475</SRS>
+ <SRS>EPSG:28476</SRS>
+ <SRS>EPSG:28477</SRS>
+ <SRS>EPSG:28478</SRS>
+ <SRS>EPSG:28479</SRS>
+ <SRS>EPSG:28480</SRS>
+ <SRS>EPSG:28481</SRS>
+ <SRS>EPSG:28482</SRS>
+ <SRS>EPSG:28483</SRS>
+ <SRS>EPSG:28484</SRS>
+ <SRS>EPSG:28485</SRS>
+ <SRS>EPSG:28486</SRS>
+ <SRS>EPSG:28487</SRS>
+ <SRS>EPSG:28488</SRS>
+ <SRS>EPSG:28489</SRS>
+ <SRS>EPSG:28490</SRS>
+ <SRS>EPSG:28491</SRS>
+ <SRS>EPSG:28492</SRS>
+ <SRS>EPSG:28600</SRS>
+ <SRS>EPSG:28991</SRS>
+ <SRS>EPSG:28992</SRS>
+ <SRS>EPSG:29100</SRS>
+ <SRS>EPSG:29101</SRS>
+ <SRS>EPSG:29118</SRS>
+ <SRS>EPSG:29119</SRS>
+ <SRS>EPSG:29120</SRS>
+ <SRS>EPSG:29121</SRS>
+ <SRS>EPSG:29122</SRS>
+ <SRS>EPSG:29168</SRS>
+ <SRS>EPSG:29169</SRS>
+ <SRS>EPSG:29170</SRS>
+ <SRS>EPSG:29171</SRS>
+ <SRS>EPSG:29172</SRS>
+ <SRS>EPSG:29177</SRS>
+ <SRS>EPSG:29178</SRS>
+ <SRS>EPSG:29179</SRS>
+ <SRS>EPSG:29180</SRS>
+ <SRS>EPSG:29181</SRS>
+ <SRS>EPSG:29182</SRS>
+ <SRS>EPSG:29183</SRS>
+ <SRS>EPSG:29184</SRS>
+ <SRS>EPSG:29185</SRS>
+ <SRS>EPSG:29187</SRS>
+ <SRS>EPSG:29188</SRS>
+ <SRS>EPSG:29189</SRS>
+ <SRS>EPSG:29190</SRS>
+ <SRS>EPSG:29191</SRS>
+ <SRS>EPSG:29192</SRS>
+ <SRS>EPSG:29193</SRS>
+ <SRS>EPSG:29194</SRS>
+ <SRS>EPSG:29195</SRS>
+ <SRS>EPSG:29220</SRS>
+ <SRS>EPSG:29221</SRS>
+ <SRS>EPSG:29333</SRS>
+ <SRS>EPSG:29371</SRS>
+ <SRS>EPSG:29373</SRS>
+ <SRS>EPSG:29375</SRS>
+ <SRS>EPSG:29377</SRS>
+ <SRS>EPSG:29379</SRS>
+ <SRS>EPSG:29381</SRS>
+ <SRS>EPSG:29383</SRS>
+ <SRS>EPSG:29385</SRS>
+ <SRS>EPSG:29635</SRS>
+ <SRS>EPSG:29636</SRS>
+ <SRS>EPSG:29700</SRS>
+ <SRS>EPSG:29701</SRS>
+ <SRS>EPSG:29702</SRS>
+ <SRS>EPSG:29738</SRS>
+ <SRS>EPSG:29739</SRS>
+ <SRS>EPSG:29849</SRS>
+ <SRS>EPSG:29850</SRS>
+ <SRS>EPSG:29871</SRS>
+ <SRS>EPSG:29872</SRS>
+ <SRS>EPSG:29873</SRS>
+ <SRS>EPSG:29900</SRS>
+ <SRS>EPSG:29901</SRS>
+ <SRS>EPSG:29902</SRS>
+ <SRS>EPSG:29903</SRS>
+ <SRS>EPSG:30161</SRS>
+ <SRS>EPSG:30162</SRS>
+ <SRS>EPSG:30163</SRS>
+ <SRS>EPSG:30164</SRS>
+ <SRS>EPSG:30165</SRS>
+ <SRS>EPSG:30166</SRS>
+ <SRS>EPSG:30167</SRS>
+ <SRS>EPSG:30168</SRS>
+ <SRS>EPSG:30169</SRS>
+ <SRS>EPSG:30170</SRS>
+ <SRS>EPSG:30171</SRS>
+ <SRS>EPSG:30172</SRS>
+ <SRS>EPSG:30173</SRS>
+ <SRS>EPSG:30174</SRS>
+ <SRS>EPSG:30175</SRS>
+ <SRS>EPSG:30176</SRS>
+ <SRS>EPSG:30177</SRS>
+ <SRS>EPSG:30178</SRS>
+ <SRS>EPSG:30179</SRS>
+ <SRS>EPSG:30200</SRS>
+ <SRS>EPSG:30339</SRS>
+ <SRS>EPSG:30340</SRS>
+ <SRS>EPSG:30491</SRS>
+ <SRS>EPSG:30492</SRS>
+ <SRS>EPSG:30493</SRS>
+ <SRS>EPSG:30494</SRS>
+ <SRS>EPSG:30729</SRS>
+ <SRS>EPSG:30730</SRS>
+ <SRS>EPSG:30731</SRS>
+ <SRS>EPSG:30732</SRS>
+ <SRS>EPSG:30791</SRS>
+ <SRS>EPSG:30792</SRS>
+ <SRS>EPSG:30800</SRS>
+ <SRS>EPSG:31028</SRS>
+ <SRS>EPSG:31121</SRS>
+ <SRS>EPSG:31154</SRS>
+ <SRS>EPSG:31170</SRS>
+ <SRS>EPSG:31171</SRS>
+ <SRS>EPSG:31251</SRS>
+ <SRS>EPSG:31252</SRS>
+ <SRS>EPSG:31253</SRS>
+ <SRS>EPSG:31254</SRS>
+ <SRS>EPSG:31255</SRS>
+ <SRS>EPSG:31256</SRS>
+ <SRS>EPSG:31257</SRS>
+ <SRS>EPSG:31258</SRS>
+ <SRS>EPSG:31259</SRS>
+ <SRS>EPSG:31265</SRS>
+ <SRS>EPSG:31266</SRS>
+ <SRS>EPSG:31267</SRS>
+ <SRS>EPSG:31268</SRS>
+ <SRS>EPSG:31275</SRS>
+ <SRS>EPSG:31276</SRS>
+ <SRS>EPSG:31277</SRS>
+ <SRS>EPSG:31278</SRS>
+ <SRS>EPSG:31279</SRS>
+ <SRS>EPSG:31281</SRS>
+ <SRS>EPSG:31282</SRS>
+ <SRS>EPSG:31283</SRS>
+ <SRS>EPSG:31284</SRS>
+ <SRS>EPSG:31285</SRS>
+ <SRS>EPSG:31286</SRS>
+ <SRS>EPSG:31287</SRS>
+ <SRS>EPSG:31288</SRS>
+ <SRS>EPSG:31289</SRS>
+ <SRS>EPSG:31290</SRS>
+ <SRS>EPSG:31291</SRS>
+ <SRS>EPSG:31292</SRS>
+ <SRS>EPSG:31293</SRS>
+ <SRS>EPSG:31294</SRS>
+ <SRS>EPSG:31295</SRS>
+ <SRS>EPSG:31296</SRS>
+ <SRS>EPSG:31297</SRS>
+ <SRS>EPSG:31300</SRS>
+ <SRS>EPSG:31370</SRS>
+ <SRS>EPSG:31461</SRS>
+ <SRS>EPSG:31462</SRS>
+ <SRS>EPSG:31463</SRS>
+ <SRS>EPSG:31464</SRS>
+ <SRS>EPSG:31465</SRS>
+ <SRS>EPSG:31466</SRS>
+ <SRS>EPSG:31467</SRS>
+ <SRS>EPSG:31468</SRS>
+ <SRS>EPSG:31469</SRS>
+ <SRS>EPSG:31528</SRS>
+ <SRS>EPSG:31529</SRS>
+ <SRS>EPSG:31600</SRS>
+ <SRS>EPSG:31700</SRS>
+ <SRS>EPSG:31838</SRS>
+ <SRS>EPSG:31839</SRS>
+ <SRS>EPSG:31900</SRS>
+ <SRS>EPSG:31901</SRS>
+ <SRS>EPSG:31965</SRS>
+ <SRS>EPSG:31966</SRS>
+ <SRS>EPSG:31967</SRS>
+ <SRS>EPSG:31968</SRS>
+ <SRS>EPSG:31969</SRS>
+ <SRS>EPSG:31970</SRS>
+ <SRS>EPSG:31971</SRS>
+ <SRS>EPSG:31972</SRS>
+ <SRS>EPSG:31973</SRS>
+ <SRS>EPSG:31974</SRS>
+ <SRS>EPSG:31975</SRS>
+ <SRS>EPSG:31976</SRS>
+ <SRS>EPSG:31977</SRS>
+ <SRS>EPSG:31978</SRS>
+ <SRS>EPSG:31979</SRS>
+ <SRS>EPSG:31980</SRS>
+ <SRS>EPSG:31981</SRS>
+ <SRS>EPSG:31982</SRS>
+ <SRS>EPSG:31983</SRS>
+ <SRS>EPSG:31984</SRS>
+ <SRS>EPSG:31985</SRS>
+ <SRS>EPSG:31986</SRS>
+ <SRS>EPSG:31987</SRS>
+ <SRS>EPSG:31988</SRS>
+ <SRS>EPSG:31989</SRS>
+ <SRS>EPSG:31990</SRS>
+ <SRS>EPSG:31991</SRS>
+ <SRS>EPSG:31992</SRS>
+ <SRS>EPSG:31993</SRS>
+ <SRS>EPSG:31994</SRS>
+ <SRS>EPSG:31995</SRS>
+ <SRS>EPSG:31996</SRS>
+ <SRS>EPSG:31997</SRS>
+ <SRS>EPSG:31998</SRS>
+ <SRS>EPSG:31999</SRS>
+ <SRS>EPSG:32000</SRS>
+ <SRS>EPSG:32001</SRS>
+ <SRS>EPSG:32002</SRS>
+ <SRS>EPSG:32003</SRS>
+ <SRS>EPSG:32005</SRS>
+ <SRS>EPSG:32006</SRS>
+ <SRS>EPSG:32007</SRS>
+ <SRS>EPSG:32008</SRS>
+ <SRS>EPSG:32009</SRS>
+ <SRS>EPSG:32010</SRS>
+ <SRS>EPSG:32011</SRS>
+ <SRS>EPSG:32012</SRS>
+ <SRS>EPSG:32013</SRS>
+ <SRS>EPSG:32014</SRS>
+ <SRS>EPSG:32015</SRS>
+ <SRS>EPSG:32016</SRS>
+ <SRS>EPSG:32017</SRS>
+ <SRS>EPSG:32018</SRS>
+ <SRS>EPSG:32019</SRS>
+ <SRS>EPSG:32020</SRS>
+ <SRS>EPSG:32021</SRS>
+ <SRS>EPSG:32022</SRS>
+ <SRS>EPSG:32023</SRS>
+ <SRS>EPSG:32024</SRS>
+ <SRS>EPSG:32025</SRS>
+ <SRS>EPSG:32026</SRS>
+ <SRS>EPSG:32027</SRS>
+ <SRS>EPSG:32028</SRS>
+ <SRS>EPSG:32029</SRS>
+ <SRS>EPSG:32030</SRS>
+ <SRS>EPSG:32031</SRS>
+ <SRS>EPSG:32033</SRS>
+ <SRS>EPSG:32034</SRS>
+ <SRS>EPSG:32035</SRS>
+ <SRS>EPSG:32036</SRS>
+ <SRS>EPSG:32037</SRS>
+ <SRS>EPSG:32038</SRS>
+ <SRS>EPSG:32039</SRS>
+ <SRS>EPSG:32040</SRS>
+ <SRS>EPSG:32041</SRS>
+ <SRS>EPSG:32042</SRS>
+ <SRS>EPSG:32043</SRS>
+ <SRS>EPSG:32044</SRS>
+ <SRS>EPSG:32045</SRS>
+ <SRS>EPSG:32046</SRS>
+ <SRS>EPSG:32047</SRS>
+ <SRS>EPSG:32048</SRS>
+ <SRS>EPSG:32049</SRS>
+ <SRS>EPSG:32050</SRS>
+ <SRS>EPSG:32051</SRS>
+ <SRS>EPSG:32052</SRS>
+ <SRS>EPSG:32053</SRS>
+ <SRS>EPSG:32054</SRS>
+ <SRS>EPSG:32055</SRS>
+ <SRS>EPSG:32056</SRS>
+ <SRS>EPSG:32057</SRS>
+ <SRS>EPSG:32058</SRS>
+ <SRS>EPSG:32061</SRS>
+ <SRS>EPSG:32062</SRS>
+ <SRS>EPSG:32064</SRS>
+ <SRS>EPSG:32065</SRS>
+ <SRS>EPSG:32066</SRS>
+ <SRS>EPSG:32067</SRS>
+ <SRS>EPSG:32074</SRS>
+ <SRS>EPSG:32075</SRS>
+ <SRS>EPSG:32076</SRS>
+ <SRS>EPSG:32077</SRS>
+ <SRS>EPSG:32081</SRS>
+ <SRS>EPSG:32082</SRS>
+ <SRS>EPSG:32083</SRS>
+ <SRS>EPSG:32084</SRS>
+ <SRS>EPSG:32085</SRS>
+ <SRS>EPSG:32086</SRS>
+ <SRS>EPSG:32098</SRS>
+ <SRS>EPSG:32099</SRS>
+ <SRS>EPSG:32100</SRS>
+ <SRS>EPSG:32104</SRS>
+ <SRS>EPSG:32107</SRS>
+ <SRS>EPSG:32108</SRS>
+ <SRS>EPSG:32109</SRS>
+ <SRS>EPSG:32110</SRS>
+ <SRS>EPSG:32111</SRS>
+ <SRS>EPSG:32112</SRS>
+ <SRS>EPSG:32113</SRS>
+ <SRS>EPSG:32114</SRS>
+ <SRS>EPSG:32115</SRS>
+ <SRS>EPSG:32116</SRS>
+ <SRS>EPSG:32117</SRS>
+ <SRS>EPSG:32118</SRS>
+ <SRS>EPSG:32119</SRS>
+ <SRS>EPSG:32120</SRS>
+ <SRS>EPSG:32121</SRS>
+ <SRS>EPSG:32122</SRS>
+ <SRS>EPSG:32123</SRS>
+ <SRS>EPSG:32124</SRS>
+ <SRS>EPSG:32125</SRS>
+ <SRS>EPSG:32126</SRS>
+ <SRS>EPSG:32127</SRS>
+ <SRS>EPSG:32128</SRS>
+ <SRS>EPSG:32129</SRS>
+ <SRS>EPSG:32130</SRS>
+ <SRS>EPSG:32133</SRS>
+ <SRS>EPSG:32134</SRS>
+ <SRS>EPSG:32135</SRS>
+ <SRS>EPSG:32136</SRS>
+ <SRS>EPSG:32137</SRS>
+ <SRS>EPSG:32138</SRS>
+ <SRS>EPSG:32139</SRS>
+ <SRS>EPSG:32140</SRS>
+ <SRS>EPSG:32141</SRS>
+ <SRS>EPSG:32142</SRS>
+ <SRS>EPSG:32143</SRS>
+ <SRS>EPSG:32144</SRS>
+ <SRS>EPSG:32145</SRS>
+ <SRS>EPSG:32146</SRS>
+ <SRS>EPSG:32147</SRS>
+ <SRS>EPSG:32148</SRS>
+ <SRS>EPSG:32149</SRS>
+ <SRS>EPSG:32150</SRS>
+ <SRS>EPSG:32151</SRS>
+ <SRS>EPSG:32152</SRS>
+ <SRS>EPSG:32153</SRS>
+ <SRS>EPSG:32154</SRS>
+ <SRS>EPSG:32155</SRS>
+ <SRS>EPSG:32156</SRS>
+ <SRS>EPSG:32157</SRS>
+ <SRS>EPSG:32158</SRS>
+ <SRS>EPSG:32161</SRS>
+ <SRS>EPSG:32164</SRS>
+ <SRS>EPSG:32165</SRS>
+ <SRS>EPSG:32166</SRS>
+ <SRS>EPSG:32167</SRS>
+ <SRS>EPSG:32180</SRS>
+ <SRS>EPSG:32181</SRS>
+ <SRS>EPSG:32182</SRS>
+ <SRS>EPSG:32183</SRS>
+ <SRS>EPSG:32184</SRS>
+ <SRS>EPSG:32185</SRS>
+ <SRS>EPSG:32186</SRS>
+ <SRS>EPSG:32187</SRS>
+ <SRS>EPSG:32188</SRS>
+ <SRS>EPSG:32189</SRS>
+ <SRS>EPSG:32190</SRS>
+ <SRS>EPSG:32191</SRS>
+ <SRS>EPSG:32192</SRS>
+ <SRS>EPSG:32193</SRS>
+ <SRS>EPSG:32194</SRS>
+ <SRS>EPSG:32195</SRS>
+ <SRS>EPSG:32196</SRS>
+ <SRS>EPSG:32197</SRS>
+ <SRS>EPSG:32198</SRS>
+ <SRS>EPSG:32199</SRS>
+ <SRS>EPSG:32201</SRS>
+ <SRS>EPSG:32202</SRS>
+ <SRS>EPSG:32203</SRS>
+ <SRS>EPSG:32204</SRS>
+ <SRS>EPSG:32205</SRS>
+ <SRS>EPSG:32206</SRS>
+ <SRS>EPSG:32207</SRS>
+ <SRS>EPSG:32208</SRS>
+ <SRS>EPSG:32209</SRS>
+ <SRS>EPSG:32210</SRS>
+ <SRS>EPSG:32211</SRS>
+ <SRS>EPSG:32212</SRS>
+ <SRS>EPSG:32213</SRS>
+ <SRS>EPSG:32214</SRS>
+ <SRS>EPSG:32215</SRS>
+ <SRS>EPSG:32216</SRS>
+ <SRS>EPSG:32217</SRS>
+ <SRS>EPSG:32218</SRS>
+ <SRS>EPSG:32219</SRS>
+ <SRS>EPSG:32220</SRS>
+ <SRS>EPSG:32221</SRS>
+ <SRS>EPSG:32222</SRS>
+ <SRS>EPSG:32223</SRS>
+ <SRS>EPSG:32224</SRS>
+ <SRS>EPSG:32225</SRS>
+ <SRS>EPSG:32226</SRS>
+ <SRS>EPSG:32227</SRS>
+ <SRS>EPSG:32228</SRS>
+ <SRS>EPSG:32229</SRS>
+ <SRS>EPSG:32230</SRS>
+ <SRS>EPSG:32231</SRS>
+ <SRS>EPSG:32232</SRS>
+ <SRS>EPSG:32233</SRS>
+ <SRS>EPSG:32234</SRS>
+ <SRS>EPSG:32235</SRS>
+ <SRS>EPSG:32236</SRS>
+ <SRS>EPSG:32237</SRS>
+ <SRS>EPSG:32238</SRS>
+ <SRS>EPSG:32239</SRS>
+ <SRS>EPSG:32240</SRS>
+ <SRS>EPSG:32241</SRS>
+ <SRS>EPSG:32242</SRS>
+ <SRS>EPSG:32243</SRS>
+ <SRS>EPSG:32244</SRS>
+ <SRS>EPSG:32245</SRS>
+ <SRS>EPSG:32246</SRS>
+ <SRS>EPSG:32247</SRS>
+ <SRS>EPSG:32248</SRS>
+ <SRS>EPSG:32249</SRS>
+ <SRS>EPSG:32250</SRS>
+ <SRS>EPSG:32251</SRS>
+ <SRS>EPSG:32252</SRS>
+ <SRS>EPSG:32253</SRS>
+ <SRS>EPSG:32254</SRS>
+ <SRS>EPSG:32255</SRS>
+ <SRS>EPSG:32256</SRS>
+ <SRS>EPSG:32257</SRS>
+ <SRS>EPSG:32258</SRS>
+ <SRS>EPSG:32259</SRS>
+ <SRS>EPSG:32260</SRS>
+ <SRS>EPSG:32301</SRS>
+ <SRS>EPSG:32302</SRS>
+ <SRS>EPSG:32303</SRS>
+ <SRS>EPSG:32304</SRS>
+ <SRS>EPSG:32305</SRS>
+ <SRS>EPSG:32306</SRS>
+ <SRS>EPSG:32307</SRS>
+ <SRS>EPSG:32308</SRS>
+ <SRS>EPSG:32309</SRS>
+ <SRS>EPSG:32310</SRS>
+ <SRS>EPSG:32311</SRS>
+ <SRS>EPSG:32312</SRS>
+ <SRS>EPSG:32313</SRS>
+ <SRS>EPSG:32314</SRS>
+ <SRS>EPSG:32315</SRS>
+ <SRS>EPSG:32316</SRS>
+ <SRS>EPSG:32317</SRS>
+ <SRS>EPSG:32318</SRS>
+ <SRS>EPSG:32319</SRS>
+ <SRS>EPSG:32320</SRS>
+ <SRS>EPSG:32321</SRS>
+ <SRS>EPSG:32322</SRS>
+ <SRS>EPSG:32323</SRS>
+ <SRS>EPSG:32324</SRS>
+ <SRS>EPSG:32325</SRS>
+ <SRS>EPSG:32326</SRS>
+ <SRS>EPSG:32327</SRS>
+ <SRS>EPSG:32328</SRS>
+ <SRS>EPSG:32329</SRS>
+ <SRS>EPSG:32330</SRS>
+ <SRS>EPSG:32331</SRS>
+ <SRS>EPSG:32332</SRS>
+ <SRS>EPSG:32333</SRS>
+ <SRS>EPSG:32334</SRS>
+ <SRS>EPSG:32335</SRS>
+ <SRS>EPSG:32336</SRS>
+ <SRS>EPSG:32337</SRS>
+ <SRS>EPSG:32338</SRS>
+ <SRS>EPSG:32339</SRS>
+ <SRS>EPSG:32340</SRS>
+ <SRS>EPSG:32341</SRS>
+ <SRS>EPSG:32342</SRS>
+ <SRS>EPSG:32343</SRS>
+ <SRS>EPSG:32344</SRS>
+ <SRS>EPSG:32345</SRS>
+ <SRS>EPSG:32346</SRS>
+ <SRS>EPSG:32347</SRS>
+ <SRS>EPSG:32348</SRS>
+ <SRS>EPSG:32349</SRS>
+ <SRS>EPSG:32350</SRS>
+ <SRS>EPSG:32351</SRS>
+ <SRS>EPSG:32352</SRS>
+ <SRS>EPSG:32353</SRS>
+ <SRS>EPSG:32354</SRS>
+ <SRS>EPSG:32355</SRS>
+ <SRS>EPSG:32356</SRS>
+ <SRS>EPSG:32357</SRS>
+ <SRS>EPSG:32358</SRS>
+ <SRS>EPSG:32359</SRS>
+ <SRS>EPSG:32360</SRS>
+ <SRS>EPSG:32401</SRS>
+ <SRS>EPSG:32402</SRS>
+ <SRS>EPSG:32403</SRS>
+ <SRS>EPSG:32404</SRS>
+ <SRS>EPSG:32405</SRS>
+ <SRS>EPSG:32406</SRS>
+ <SRS>EPSG:32407</SRS>
+ <SRS>EPSG:32408</SRS>
+ <SRS>EPSG:32409</SRS>
+ <SRS>EPSG:32410</SRS>
+ <SRS>EPSG:32411</SRS>
+ <SRS>EPSG:32412</SRS>
+ <SRS>EPSG:32413</SRS>
+ <SRS>EPSG:32414</SRS>
+ <SRS>EPSG:32415</SRS>
+ <SRS>EPSG:32416</SRS>
+ <SRS>EPSG:32417</SRS>
+ <SRS>EPSG:32418</SRS>
+ <SRS>EPSG:32419</SRS>
+ <SRS>EPSG:32420</SRS>
+ <SRS>EPSG:32421</SRS>
+ <SRS>EPSG:32422</SRS>
+ <SRS>EPSG:32423</SRS>
+ <SRS>EPSG:32424</SRS>
+ <SRS>EPSG:32425</SRS>
+ <SRS>EPSG:32426</SRS>
+ <SRS>EPSG:32427</SRS>
+ <SRS>EPSG:32428</SRS>
+ <SRS>EPSG:32429</SRS>
+ <SRS>EPSG:32430</SRS>
+ <SRS>EPSG:32431</SRS>
+ <SRS>EPSG:32432</SRS>
+ <SRS>EPSG:32433</SRS>
+ <SRS>EPSG:32434</SRS>
+ <SRS>EPSG:32435</SRS>
+ <SRS>EPSG:32436</SRS>
+ <SRS>EPSG:32437</SRS>
+ <SRS>EPSG:32438</SRS>
+ <SRS>EPSG:32439</SRS>
+ <SRS>EPSG:32440</SRS>
+ <SRS>EPSG:32441</SRS>
+ <SRS>EPSG:32442</SRS>
+ <SRS>EPSG:32443</SRS>
+ <SRS>EPSG:32444</SRS>
+ <SRS>EPSG:32445</SRS>
+ <SRS>EPSG:32446</SRS>
+ <SRS>EPSG:32447</SRS>
+ <SRS>EPSG:32448</SRS>
+ <SRS>EPSG:32449</SRS>
+ <SRS>EPSG:32450</SRS>
+ <SRS>EPSG:32451</SRS>
+ <SRS>EPSG:32452</SRS>
+ <SRS>EPSG:32453</SRS>
+ <SRS>EPSG:32454</SRS>
+ <SRS>EPSG:32455</SRS>
+ <SRS>EPSG:32456</SRS>
+ <SRS>EPSG:32457</SRS>
+ <SRS>EPSG:32458</SRS>
+ <SRS>EPSG:32459</SRS>
+ <SRS>EPSG:32460</SRS>
+ <SRS>EPSG:32501</SRS>
+ <SRS>EPSG:32502</SRS>
+ <SRS>EPSG:32503</SRS>
+ <SRS>EPSG:32504</SRS>
+ <SRS>EPSG:32505</SRS>
+ <SRS>EPSG:32506</SRS>
+ <SRS>EPSG:32507</SRS>
+ <SRS>EPSG:32508</SRS>
+ <SRS>EPSG:32509</SRS>
+ <SRS>EPSG:32510</SRS>
+ <SRS>EPSG:32511</SRS>
+ <SRS>EPSG:32512</SRS>
+ <SRS>EPSG:32513</SRS>
+ <SRS>EPSG:32514</SRS>
+ <SRS>EPSG:32515</SRS>
+ <SRS>EPSG:32516</SRS>
+ <SRS>EPSG:32517</SRS>
+ <SRS>EPSG:32518</SRS>
+ <SRS>EPSG:32519</SRS>
+ <SRS>EPSG:32520</SRS>
+ <SRS>EPSG:32521</SRS>
+ <SRS>EPSG:32522</SRS>
+ <SRS>EPSG:32523</SRS>
+ <SRS>EPSG:32524</SRS>
+ <SRS>EPSG:32525</SRS>
+ <SRS>EPSG:32526</SRS>
+ <SRS>EPSG:32527</SRS>
+ <SRS>EPSG:32528</SRS>
+ <SRS>EPSG:32529</SRS>
+ <SRS>EPSG:32530</SRS>
+ <SRS>EPSG:32531</SRS>
+ <SRS>EPSG:32532</SRS>
+ <SRS>EPSG:32533</SRS>
+ <SRS>EPSG:32534</SRS>
+ <SRS>EPSG:32535</SRS>
+ <SRS>EPSG:32536</SRS>
+ <SRS>EPSG:32537</SRS>
+ <SRS>EPSG:32538</SRS>
+ <SRS>EPSG:32539</SRS>
+ <SRS>EPSG:32540</SRS>
+ <SRS>EPSG:32541</SRS>
+ <SRS>EPSG:32542</SRS>
+ <SRS>EPSG:32543</SRS>
+ <SRS>EPSG:32544</SRS>
+ <SRS>EPSG:32545</SRS>
+ <SRS>EPSG:32546</SRS>
+ <SRS>EPSG:32547</SRS>
+ <SRS>EPSG:32548</SRS>
+ <SRS>EPSG:32549</SRS>
+ <SRS>EPSG:32550</SRS>
+ <SRS>EPSG:32551</SRS>
+ <SRS>EPSG:32552</SRS>
+ <SRS>EPSG:32553</SRS>
+ <SRS>EPSG:32554</SRS>
+ <SRS>EPSG:32555</SRS>
+ <SRS>EPSG:32556</SRS>
+ <SRS>EPSG:32557</SRS>
+ <SRS>EPSG:32558</SRS>
+ <SRS>EPSG:32559</SRS>
+ <SRS>EPSG:32560</SRS>
+ <SRS>EPSG:32600</SRS>
+ <SRS>EPSG:32601</SRS>
+ <SRS>EPSG:32602</SRS>
+ <SRS>EPSG:32603</SRS>
+ <SRS>EPSG:32604</SRS>
+ <SRS>EPSG:32605</SRS>
+ <SRS>EPSG:32606</SRS>
+ <SRS>EPSG:32607</SRS>
+ <SRS>EPSG:32608</SRS>
+ <SRS>EPSG:32609</SRS>
+ <SRS>EPSG:32610</SRS>
+ <SRS>EPSG:32611</SRS>
+ <SRS>EPSG:32612</SRS>
+ <SRS>EPSG:32613</SRS>
+ <SRS>EPSG:32614</SRS>
+ <SRS>EPSG:32615</SRS>
+ <SRS>EPSG:32616</SRS>
+ <SRS>EPSG:32617</SRS>
+ <SRS>EPSG:32618</SRS>
+ <SRS>EPSG:32619</SRS>
+ <SRS>EPSG:32620</SRS>
+ <SRS>EPSG:32621</SRS>
+ <SRS>EPSG:32622</SRS>
+ <SRS>EPSG:32623</SRS>
+ <SRS>EPSG:32624</SRS>
+ <SRS>EPSG:32625</SRS>
+ <SRS>EPSG:32626</SRS>
+ <SRS>EPSG:32627</SRS>
+ <SRS>EPSG:32628</SRS>
+ <SRS>EPSG:32629</SRS>
+ <SRS>EPSG:32630</SRS>
+ <SRS>EPSG:32631</SRS>
+ <SRS>EPSG:32632</SRS>
+ <SRS>EPSG:32633</SRS>
+ <SRS>EPSG:32634</SRS>
+ <SRS>EPSG:32635</SRS>
+ <SRS>EPSG:32636</SRS>
+ <SRS>EPSG:32637</SRS>
+ <SRS>EPSG:32638</SRS>
+ <SRS>EPSG:32639</SRS>
+ <SRS>EPSG:32640</SRS>
+ <SRS>EPSG:32641</SRS>
+ <SRS>EPSG:32642</SRS>
+ <SRS>EPSG:32643</SRS>
+ <SRS>EPSG:32644</SRS>
+ <SRS>EPSG:32645</SRS>
+ <SRS>EPSG:32646</SRS>
+ <SRS>EPSG:32647</SRS>
+ <SRS>EPSG:32648</SRS>
+ <SRS>EPSG:32649</SRS>
+ <SRS>EPSG:32650</SRS>
+ <SRS>EPSG:32651</SRS>
+ <SRS>EPSG:32652</SRS>
+ <SRS>EPSG:32653</SRS>
+ <SRS>EPSG:32654</SRS>
+ <SRS>EPSG:32655</SRS>
+ <SRS>EPSG:32656</SRS>
+ <SRS>EPSG:32657</SRS>
+ <SRS>EPSG:32658</SRS>
+ <SRS>EPSG:32659</SRS>
+ <SRS>EPSG:32660</SRS>
+ <SRS>EPSG:32661</SRS>
+ <SRS>EPSG:32662</SRS>
+ <SRS>EPSG:32664</SRS>
+ <SRS>EPSG:32665</SRS>
+ <SRS>EPSG:32666</SRS>
+ <SRS>EPSG:32667</SRS>
+ <SRS>EPSG:32700</SRS>
+ <SRS>EPSG:32701</SRS>
+ <SRS>EPSG:32702</SRS>
+ <SRS>EPSG:32703</SRS>
+ <SRS>EPSG:32704</SRS>
+ <SRS>EPSG:32705</SRS>
+ <SRS>EPSG:32706</SRS>
+ <SRS>EPSG:32707</SRS>
+ <SRS>EPSG:32708</SRS>
+ <SRS>EPSG:32709</SRS>
+ <SRS>EPSG:32710</SRS>
+ <SRS>EPSG:32711</SRS>
+ <SRS>EPSG:32712</SRS>
+ <SRS>EPSG:32713</SRS>
+ <SRS>EPSG:32714</SRS>
+ <SRS>EPSG:32715</SRS>
+ <SRS>EPSG:32716</SRS>
+ <SRS>EPSG:32717</SRS>
+ <SRS>EPSG:32718</SRS>
+ <SRS>EPSG:32719</SRS>
+ <SRS>EPSG:32720</SRS>
+ <SRS>EPSG:32721</SRS>
+ <SRS>EPSG:32722</SRS>
+ <SRS>EPSG:32723</SRS>
+ <SRS>EPSG:32724</SRS>
+ <SRS>EPSG:32725</SRS>
+ <SRS>EPSG:32726</SRS>
+ <SRS>EPSG:32727</SRS>
+ <SRS>EPSG:32728</SRS>
+ <SRS>EPSG:32729</SRS>
+ <SRS>EPSG:32730</SRS>
+ <SRS>EPSG:32731</SRS>
+ <SRS>EPSG:32732</SRS>
+ <SRS>EPSG:32733</SRS>
+ <SRS>EPSG:32734</SRS>
+ <SRS>EPSG:32735</SRS>
+ <SRS>EPSG:32736</SRS>
+ <SRS>EPSG:32737</SRS>
+ <SRS>EPSG:32738</SRS>
+ <SRS>EPSG:32739</SRS>
+ <SRS>EPSG:32740</SRS>
+ <SRS>EPSG:32741</SRS>
+ <SRS>EPSG:32742</SRS>
+ <SRS>EPSG:32743</SRS>
+ <SRS>EPSG:32744</SRS>
+ <SRS>EPSG:32745</SRS>
+ <SRS>EPSG:32746</SRS>
+ <SRS>EPSG:32747</SRS>
+ <SRS>EPSG:32748</SRS>
+ <SRS>EPSG:32749</SRS>
+ <SRS>EPSG:32750</SRS>
+ <SRS>EPSG:32751</SRS>
+ <SRS>EPSG:32752</SRS>
+ <SRS>EPSG:32753</SRS>
+ <SRS>EPSG:32754</SRS>
+ <SRS>EPSG:32755</SRS>
+ <SRS>EPSG:32756</SRS>
+ <SRS>EPSG:32757</SRS>
+ <SRS>EPSG:32758</SRS>
+ <SRS>EPSG:32759</SRS>
+ <SRS>EPSG:32760</SRS>
+ <SRS>EPSG:32761</SRS>
+ <SRS>EPSG:32766</SRS>
+ <SRS>EPSG:61206405</SRS>
+ <SRS>EPSG:61216405</SRS>
+ <SRS>EPSG:61226405</SRS>
+ <SRS>EPSG:61236405</SRS>
+ <SRS>EPSG:61246405</SRS>
+ <SRS>EPSG:61266405</SRS>
+ <SRS>EPSG:61266413</SRS>
+ <SRS>EPSG:61276405</SRS>
+ <SRS>EPSG:61286405</SRS>
+ <SRS>EPSG:61296405</SRS>
+ <SRS>EPSG:61306405</SRS>
+ <SRS>EPSG:61306413</SRS>
+ <SRS>EPSG:61316405</SRS>
+ <SRS>EPSG:61326405</SRS>
+ <SRS>EPSG:61336405</SRS>
+ <SRS>EPSG:61346405</SRS>
+ <SRS>EPSG:61356405</SRS>
+ <SRS>EPSG:61366405</SRS>
+ <SRS>EPSG:61376405</SRS>
+ <SRS>EPSG:61386405</SRS>
+ <SRS>EPSG:61396405</SRS>
+ <SRS>EPSG:61406405</SRS>
+ <SRS>EPSG:61406413</SRS>
+ <SRS>EPSG:61416405</SRS>
+ <SRS>EPSG:61426405</SRS>
+ <SRS>EPSG:61436405</SRS>
+ <SRS>EPSG:61446405</SRS>
+ <SRS>EPSG:61456405</SRS>
+ <SRS>EPSG:61466405</SRS>
+ <SRS>EPSG:61476405</SRS>
+ <SRS>EPSG:61486405</SRS>
+ <SRS>EPSG:61486413</SRS>
+ <SRS>EPSG:61496405</SRS>
+ <SRS>EPSG:61506405</SRS>
+ <SRS>EPSG:61516405</SRS>
+ <SRS>EPSG:61516413</SRS>
+ <SRS>EPSG:61526405</SRS>
+ <SRS>EPSG:61526413</SRS>
+ <SRS>EPSG:61536405</SRS>
+ <SRS>EPSG:61546405</SRS>
+ <SRS>EPSG:61556405</SRS>
+ <SRS>EPSG:61566405</SRS>
+ <SRS>EPSG:61576405</SRS>
+ <SRS>EPSG:61586405</SRS>
+ <SRS>EPSG:61596405</SRS>
+ <SRS>EPSG:61606405</SRS>
+ <SRS>EPSG:61616405</SRS>
+ <SRS>EPSG:61626405</SRS>
+ <SRS>EPSG:61636405</SRS>
+ <SRS>EPSG:61636413</SRS>
+ <SRS>EPSG:61646405</SRS>
+ <SRS>EPSG:61656405</SRS>
+ <SRS>EPSG:61666405</SRS>
+ <SRS>EPSG:61676405</SRS>
+ <SRS>EPSG:61676413</SRS>
+ <SRS>EPSG:61686405</SRS>
+ <SRS>EPSG:61696405</SRS>
+ <SRS>EPSG:61706405</SRS>
+ <SRS>EPSG:61706413</SRS>
+ <SRS>EPSG:61716405</SRS>
+ <SRS>EPSG:61716413</SRS>
+ <SRS>EPSG:61736405</SRS>
+ <SRS>EPSG:61736413</SRS>
+ <SRS>EPSG:61746405</SRS>
+ <SRS>EPSG:61756405</SRS>
+ <SRS>EPSG:61766405</SRS>
+ <SRS>EPSG:61766413</SRS>
+ <SRS>EPSG:61786405</SRS>
+ <SRS>EPSG:61796405</SRS>
+ <SRS>EPSG:61806405</SRS>
+ <SRS>EPSG:61806413</SRS>
+ <SRS>EPSG:61816405</SRS>
+ <SRS>EPSG:61826405</SRS>
+ <SRS>EPSG:61836405</SRS>
+ <SRS>EPSG:61846405</SRS>
+ <SRS>EPSG:61886405</SRS>
+ <SRS>EPSG:61896405</SRS>
+ <SRS>EPSG:61896413</SRS>
+ <SRS>EPSG:61906405</SRS>
+ <SRS>EPSG:61906413</SRS>
+ <SRS>EPSG:61916405</SRS>
+ <SRS>EPSG:61926405</SRS>
+ <SRS>EPSG:61936405</SRS>
+ <SRS>EPSG:61946405</SRS>
+ <SRS>EPSG:61956405</SRS>
+ <SRS>EPSG:61966405</SRS>
+ <SRS>EPSG:61976405</SRS>
+ <SRS>EPSG:61986405</SRS>
+ <SRS>EPSG:61996405</SRS>
+ <SRS>EPSG:62006405</SRS>
+ <SRS>EPSG:62016405</SRS>
+ <SRS>EPSG:62026405</SRS>
+ <SRS>EPSG:62036405</SRS>
+ <SRS>EPSG:62046405</SRS>
+ <SRS>EPSG:62056405</SRS>
+ <SRS>EPSG:62066405</SRS>
+ <SRS>EPSG:62076405</SRS>
+ <SRS>EPSG:62086405</SRS>
+ <SRS>EPSG:62096405</SRS>
+ <SRS>EPSG:62106405</SRS>
+ <SRS>EPSG:62116405</SRS>
+ <SRS>EPSG:62126405</SRS>
+ <SRS>EPSG:62136405</SRS>
+ <SRS>EPSG:62146405</SRS>
+ <SRS>EPSG:62156405</SRS>
+ <SRS>EPSG:62166405</SRS>
+ <SRS>EPSG:62186405</SRS>
+ <SRS>EPSG:62196405</SRS>
+ <SRS>EPSG:62206405</SRS>
+ <SRS>EPSG:62216405</SRS>
+ <SRS>EPSG:62226405</SRS>
+ <SRS>EPSG:62236405</SRS>
+ <SRS>EPSG:62246405</SRS>
+ <SRS>EPSG:62256405</SRS>
+ <SRS>EPSG:62276405</SRS>
+ <SRS>EPSG:62296405</SRS>
+ <SRS>EPSG:62306405</SRS>
+ <SRS>EPSG:62316405</SRS>
+ <SRS>EPSG:62326405</SRS>
+ <SRS>EPSG:62336405</SRS>
+ <SRS>EPSG:62366405</SRS>
+ <SRS>EPSG:62376405</SRS>
+ <SRS>EPSG:62386405</SRS>
+ <SRS>EPSG:62396405</SRS>
+ <SRS>EPSG:62406405</SRS>
+ <SRS>EPSG:62416405</SRS>
+ <SRS>EPSG:62426405</SRS>
+ <SRS>EPSG:62436405</SRS>
+ <SRS>EPSG:62446405</SRS>
+ <SRS>EPSG:62456405</SRS>
+ <SRS>EPSG:62466405</SRS>
+ <SRS>EPSG:62476405</SRS>
+ <SRS>EPSG:62486405</SRS>
+ <SRS>EPSG:62496405</SRS>
+ <SRS>EPSG:62506405</SRS>
+ <SRS>EPSG:62516405</SRS>
+ <SRS>EPSG:62526405</SRS>
+ <SRS>EPSG:62536405</SRS>
+ <SRS>EPSG:62546405</SRS>
+ <SRS>EPSG:62556405</SRS>
+ <SRS>EPSG:62566405</SRS>
+ <SRS>EPSG:62576405</SRS>
+ <SRS>EPSG:62586405</SRS>
+ <SRS>EPSG:62586413</SRS>
+ <SRS>EPSG:62596405</SRS>
+ <SRS>EPSG:62616405</SRS>
+ <SRS>EPSG:62626405</SRS>
+ <SRS>EPSG:62636405</SRS>
+ <SRS>EPSG:62646405</SRS>
+ <SRS>EPSG:62656405</SRS>
+ <SRS>EPSG:62666405</SRS>
+ <SRS>EPSG:62676405</SRS>
+ <SRS>EPSG:62686405</SRS>
+ <SRS>EPSG:62696405</SRS>
+ <SRS>EPSG:62706405</SRS>
+ <SRS>EPSG:62716405</SRS>
+ <SRS>EPSG:62726405</SRS>
+ <SRS>EPSG:62736405</SRS>
+ <SRS>EPSG:62746405</SRS>
+ <SRS>EPSG:62756405</SRS>
+ <SRS>EPSG:62766405</SRS>
+ <SRS>EPSG:62776405</SRS>
+ <SRS>EPSG:62786405</SRS>
+ <SRS>EPSG:62796405</SRS>
+ <SRS>EPSG:62806405</SRS>
+ <SRS>EPSG:62816405</SRS>
+ <SRS>EPSG:62826405</SRS>
+ <SRS>EPSG:62836405</SRS>
+ <SRS>EPSG:62836413</SRS>
+ <SRS>EPSG:62846405</SRS>
+ <SRS>EPSG:62856405</SRS>
+ <SRS>EPSG:62866405</SRS>
+ <SRS>EPSG:62886405</SRS>
+ <SRS>EPSG:62896405</SRS>
+ <SRS>EPSG:62926405</SRS>
+ <SRS>EPSG:62936405</SRS>
+ <SRS>EPSG:62956405</SRS>
+ <SRS>EPSG:62976405</SRS>
+ <SRS>EPSG:62986405</SRS>
+ <SRS>EPSG:62996405</SRS>
+ <SRS>EPSG:63006405</SRS>
+ <SRS>EPSG:63016405</SRS>
+ <SRS>EPSG:63026405</SRS>
+ <SRS>EPSG:63036405</SRS>
+ <SRS>EPSG:63046405</SRS>
+ <SRS>EPSG:63066405</SRS>
+ <SRS>EPSG:63076405</SRS>
+ <SRS>EPSG:63086405</SRS>
+ <SRS>EPSG:63096405</SRS>
+ <SRS>EPSG:63106405</SRS>
+ <SRS>EPSG:63116405</SRS>
+ <SRS>EPSG:63126405</SRS>
+ <SRS>EPSG:63136405</SRS>
+ <SRS>EPSG:63146405</SRS>
+ <SRS>EPSG:63156405</SRS>
+ <SRS>EPSG:63166405</SRS>
+ <SRS>EPSG:63176405</SRS>
+ <SRS>EPSG:63186405</SRS>
+ <SRS>EPSG:63196405</SRS>
+ <SRS>EPSG:63226405</SRS>
+ <SRS>EPSG:63246405</SRS>
+ <SRS>EPSG:63266405</SRS>
+ <SRS>EPSG:63266406</SRS>
+ <SRS>EPSG:63266407</SRS>
+ <SRS>EPSG:63266408</SRS>
+ <SRS>EPSG:63266409</SRS>
+ <SRS>EPSG:63266410</SRS>
+ <SRS>EPSG:63266411</SRS>
+ <SRS>EPSG:63266412</SRS>
+ <SRS>EPSG:63266413</SRS>
+ <SRS>EPSG:63266414</SRS>
+ <SRS>EPSG:63266415</SRS>
+ <SRS>EPSG:63266416</SRS>
+ <SRS>EPSG:63266417</SRS>
+ <SRS>EPSG:63266418</SRS>
+ <SRS>EPSG:63266419</SRS>
+ <SRS>EPSG:63266420</SRS>
+ <SRS>EPSG:66006405</SRS>
+ <SRS>EPSG:66016405</SRS>
+ <SRS>EPSG:66026405</SRS>
+ <SRS>EPSG:66036405</SRS>
+ <SRS>EPSG:66046405</SRS>
+ <SRS>EPSG:66056405</SRS>
+ <SRS>EPSG:66066405</SRS>
+ <SRS>EPSG:66076405</SRS>
+ <SRS>EPSG:66086405</SRS>
+ <SRS>EPSG:66096405</SRS>
+ <SRS>EPSG:66106405</SRS>
+ <SRS>EPSG:66116405</SRS>
+ <SRS>EPSG:66126405</SRS>
+ <SRS>EPSG:66126413</SRS>
+ <SRS>EPSG:66136405</SRS>
+ <SRS>EPSG:66146405</SRS>
+ <SRS>EPSG:66156405</SRS>
+ <SRS>EPSG:66166405</SRS>
+ <SRS>EPSG:66186405</SRS>
+ <SRS>EPSG:66196405</SRS>
+ <SRS>EPSG:66196413</SRS>
+ <SRS>EPSG:66206405</SRS>
+ <SRS>EPSG:66216405</SRS>
+ <SRS>EPSG:66226405</SRS>
+ <SRS>EPSG:66236405</SRS>
+ <SRS>EPSG:66246405</SRS>
+ <SRS>EPSG:66246413</SRS>
+ <SRS>EPSG:66256405</SRS>
+ <SRS>EPSG:66266405</SRS>
+ <SRS>EPSG:66276405</SRS>
+ <SRS>EPSG:66276413</SRS>
+ <SRS>EPSG:66286405</SRS>
+ <SRS>EPSG:66296405</SRS>
+ <SRS>EPSG:66306405</SRS>
+ <SRS>EPSG:66316405</SRS>
+ <SRS>EPSG:66326405</SRS>
+ <SRS>EPSG:66336405</SRS>
+ <SRS>EPSG:66346405</SRS>
+ <SRS>EPSG:66356405</SRS>
+ <SRS>EPSG:66366405</SRS>
+ <SRS>EPSG:66376405</SRS>
+ <SRS>EPSG:66386405</SRS>
+ <SRS>EPSG:66396405</SRS>
+ <SRS>EPSG:66406405</SRS>
+ <SRS>EPSG:66406413</SRS>
+ <SRS>EPSG:66416405</SRS>
+ <SRS>EPSG:66426405</SRS>
+ <SRS>EPSG:66436405</SRS>
+ <SRS>EPSG:66446405</SRS>
+ <SRS>EPSG:66456405</SRS>
+ <SRS>EPSG:66456413</SRS>
+ <SRS>EPSG:66466405</SRS>
+ <SRS>EPSG:66576405</SRS>
+ <SRS>EPSG:66586405</SRS>
+ <SRS>EPSG:66596405</SRS>
+ <SRS>EPSG:66596413</SRS>
+ <SRS>EPSG:66606405</SRS>
+ <SRS>EPSG:66616405</SRS>
+ <SRS>EPSG:66616413</SRS>
+ <SRS>EPSG:66636405</SRS>
+ <SRS>EPSG:66646405</SRS>
+ <SRS>EPSG:66656405</SRS>
+ <SRS>EPSG:66666405</SRS>
+ <SRS>EPSG:66676405</SRS>
+ <SRS>EPSG:68016405</SRS>
+ <SRS>EPSG:68026405</SRS>
+ <SRS>EPSG:68036405</SRS>
+ <SRS>EPSG:68046405</SRS>
+ <SRS>EPSG:68056405</SRS>
+ <SRS>EPSG:68066405</SRS>
+ <SRS>EPSG:68086405</SRS>
+ <SRS>EPSG:68096405</SRS>
+ <SRS>EPSG:68136405</SRS>
+ <SRS>EPSG:68146405</SRS>
+ <SRS>EPSG:68156405</SRS>
+ <SRS>EPSG:68186405</SRS>
+ <SRS>EPSG:68206405</SRS>
+ <SRS>EPSG:69036405</SRS>
+ <SRS>EPSG:42302</SRS>
+ <SRS>EPSG:42301</SRS>
+ <SRS>EPSG:900913</SRS>
+ <SRS>EPSG:45556</SRS>
+ <SRS>EPSG:45555</SRS>
+ <SRS>EPSG:54004</SRS>
+ <SRS>EPSG:41001</SRS>
+ <SRS>EPSG:42311</SRS>
+ <SRS>EPSG:42310</SRS>
+ <SRS>EPSG:18001</SRS>
+ <SRS>EPSG:100003</SRS>
+ <SRS>EPSG:42106</SRS>
+ <SRS>EPSG:100002</SRS>
+ <SRS>EPSG:42105</SRS>
+ <SRS>EPSG:100001</SRS>
+ <SRS>EPSG:42309</SRS>
+ <SRS>EPSG:42104</SRS>
+ <SRS>EPSG:42308</SRS>
+ <SRS>EPSG:42103</SRS>
+ <SRS>EPSG:42307</SRS>
+ <SRS>EPSG:42102</SRS>
+ <SRS>EPSG:42306</SRS>
+ <SRS>EPSG:42101</SRS>
+ <SRS>EPSG:42305</SRS>
+ <SRS>EPSG:42304</SRS>
+ <SRS>EPSG:42303</SRS>
+ <LatLonBoundingBox minx="-257.0843245637291" miny="-257.0843245637291" maxx="257.0843245637291" maxy="257.0843245637291"/>
+ <Layer queryable="1">
+ <Name>tiger:poly_landmarks</Name>
+ <Title>Manhattan (NY) landmarks</Title>
+ <Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract>
+ <KeywordList>
+ <Keyword>DS_poly_landmarks</Keyword>
+ <Keyword>poly_landmarks</Keyword>
+ <Keyword>landmarks</Keyword>
+ <Keyword>manhattan</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-74.1008830202198" miny="40.65748247978021" maxx="-73.8541219797802" maxy="40.90424352021979"/>
+ <BoundingBox SRS="EPSG:4326" minx="-74.047185" miny="40.679648" maxx="-73.90782" maxy="40.882078"/>
+ <Style>
+ <Name>poly_landmarks</Name>
+ <Title>Default Styler</Title>
+ <Abstract/>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poly_landmarks"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>tiger:poi</Name>
+ <Title>Manhattan (NY) points of interest</Title>
+ <Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract>
+ <KeywordList>
+ <Keyword>poi</Keyword>
+ <Keyword>DS_poi</Keyword>
+ <Keyword>points_of_interest</Keyword>
+ <Keyword>Manhattan</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-74.01288357289539" miny="40.70706518152972" maxx="-74.00752144792617" maxy="40.71242730649893"/>
+ <BoundingBox SRS="EPSG:4326" minx="-74.0118315772888" miny="40.70754683896324" maxx="-74.00153046439813" maxy="40.719885123828675"/>
+ <Style>
+ <Name>poi</Name>
+ <Title>Points of interest</Title>
+ <Abstract>Manhattan points of interest</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poi"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>tiger:tiger_roads</Name>
+ <Title>Manhattan (NY) roads</Title>
+ <Abstract>Highly simplified road layout of Manhattan in New York..</Abstract>
+ <KeywordList>
+ <Keyword>DS_tiger_roads</Keyword>
+ <Keyword>tiger_roads</Keyword>
+ <Keyword>roads</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-74.08769307536667" miny="40.660618924633326" maxx="-73.84653192463333" maxy="40.90178007536667"/>
+ <BoundingBox SRS="EPSG:4326" minx="-74.02722" miny="40.684221" maxx="-73.907005" maxy="40.878178"/>
+ <Style>
+ <Name>tiger_roads</Name>
+ <Title>Default Styler</Title>
+ <Abstract/>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:tiger_roads"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>sf:archsites</Name>
+ <Title>Spearfish archeological sites</Title>
+ <Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract>
+ <KeywordList>
+ <Keyword>archsites</Keyword>
+ <Keyword>sfArchsites</Keyword>
+ <Keyword>spearfish</Keyword>
+ <Keyword>archeology</Keyword>
+ </KeywordList>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.89000625326194" miny="44.29796961116877" maxx="-103.62049935931161" maxy="44.5674765051191"/>
+ <BoundingBox SRS="EPSG:26713" minx="588926.6865343997" miny="4913890.332215005" maxx="609271.2114429093" maxy="4927102.448786693"/>
+ <Style>
+ <Name>point</Name>
+ <Title>Default point</Title>
+ <Abstract>A sample style that just prints out a 6px wide red square</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:archsites"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>sf:bugsites</Name>
+ <Title>Spearfish bug locations</Title>
+ <Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract>
+ <KeywordList>
+ <Keyword>sfBugsites</Keyword>
+ <Keyword>bugsites</Keyword>
+ <Keyword>insects</Keyword>
+ <Keyword>spearfish</Keyword>
+ <Keyword>tiger_beetles</Keyword>
+ </KeywordList>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.89041901614995" miny="44.266492773791775" maxx="-103.61527753322848" maxy="44.54163425671326"/>
+ <BoundingBox SRS="EPSG:26713" minx="589311.4871629482" miny="4913787.082099182" maxx="609374.4115724327" maxy="4920844.691225147"/>
+ <Style>
+ <Name>capitals</Name>
+ <Title>Capital cities</Title>
+ <Abstract/>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:bugsites"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>sf:restricted</Name>
+ <Title>Spearfish restricted areas</Title>
+ <Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract>
+ <KeywordList>
+ <Keyword>restricted</Keyword>
+ <Keyword>sfRestricted</Keyword>
+ <Keyword>spearfish</Keyword>
+ <Keyword>areas</Keyword>
+ </KeywordList>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.86063428986338" miny="44.37661974734028" maxx="-103.73735238788223" maxy="44.49990164932145"/>
+ <BoundingBox SRS="EPSG:26713" minx="591175.6988413236" miny="4915754.888027622" maxx="600052.4121365736" maxy="4926353.920417598"/>
+ <Style>
+ <Name>restricted</Name>
+ <Title>Red, translucent style</Title>
+ <Abstract>A sample style that just prints out a transparent red interior with a red outline</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:restricted"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>sf:roads</Name>
+ <Title>Spearfish roads</Title>
+ <Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract>
+ <KeywordList>
+ <Keyword>sfRoads</Keyword>
+ <Keyword>roads</Keyword>
+ <Keyword>spearfish</Keyword>
+ </KeywordList>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.90534996703491" miny="44.2800314829381" maxx="-103.5943809967035" maxy="44.5910004532695"/>
+ <BoundingBox SRS="EPSG:26713" minx="588430.2387813567" miny="4913303.484828213" maxx="610531.8279023392" maxy="4928766.251023613"/>
+ <Style>
+ <Name>simple_roads</Name>
+ <Title>Default Styler for simple road segments</Title>
+ <Abstract>Light red line, 2px wide</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:roads"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>sf:streams</Name>
+ <Title>Spearfish streams</Title>
+ <Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract>
+ <KeywordList>
+ <Keyword>sfStreams</Keyword>
+ <Keyword>streams</Keyword>
+ <Keyword>spearfish</Keyword>
+ </KeywordList>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.9089219204826" miny="44.278738996398694" maxx="-103.59184616696963" maxy="44.595814749911675"/>
+ <BoundingBox SRS="EPSG:26713" minx="588430.3113926318" miny="4913241.156915463" maxx="610522.3974737043" maxy="4928777.235349244"/>
+ <Style>
+ <Name>simple_streams</Name>
+ <Title>Default Styler for streams segments</Title>
+ <Abstract>Blue lines, 2px wide</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:streams"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>topp:tasmania_cities</Name>
+ <Title>Tasmania cities</Title>
+ <Abstract>Cities in Tasmania (actually, just the capital)</Abstract>
+ <KeywordList>
+ <Keyword>cities</Keyword>
+ <Keyword>Tasmania</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="144.93357593664516" miny="-43.93984106335484" maxx="148.53694406335487" maxy="-40.33647293664516"/>
+ <BoundingBox SRS="EPSG:4326" minx="147.2910004483" miny="-42.851001816890005" maxx="147.2910004483" maxy="-42.851001816890005"/>
+ <Style>
+ <Name>capitals</Name>
+ <Title>Capital cities</Title>
+ <Abstract/>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_cities"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>topp:tasmania_roads</Name>
+ <Title>Tasmania roads</Title>
+ <Abstract>Main Tasmania roads</Abstract>
+ <KeywordList>
+ <Keyword>Roads</Keyword>
+ <Keyword>Tasmania</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="144.8607879004856" miny="-44.01262909951439" maxx="148.60973209951442" maxy="-40.26368490048561"/>
+ <BoundingBox SRS="EPSG:4326" minx="145.19754" miny="-43.423512" maxx="148.27298000000002" maxy="-40.852802"/>
+ <Style>
+ <Name>simple_roads</Name>
+ <Title>Default Styler for simple road segments</Title>
+ <Abstract>Light red line, 2px wide</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_roads"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>topp:tasmania_state_boundaries</Name>
+ <Title>Tasmania state boundaries</Title>
+ <Abstract>Tasmania state boundaries</Abstract>
+ <KeywordList>
+ <Keyword>tasmania_state_boundaries</Keyword>
+ <Keyword>Tasmania</Keyword>
+ <Keyword>boundaries</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="142.70637712387594" miny="-45.06157887612408" maxx="149.60758787612411" maxy="-38.16036812387592"/>
+ <BoundingBox SRS="EPSG:4326" minx="143.83482400000003" miny="-43.648056" maxx="148.47914100000003" maxy="-39.573891"/>
+ <Style>
+ <Name>green</Name>
+ <Title>Green polygon</Title>
+ <Abstract>Green fill with black outline</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_state_boundaries"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>topp:tasmania_water_bodies</Name>
+ <Title>Tasmania water bodies</Title>
+ <Abstract>Tasmania water bodies</Abstract>
+ <KeywordList>
+ <Keyword>Lakes</Keyword>
+ <Keyword>Bodies</Keyword>
+ <Keyword>Australia</Keyword>
+ <Keyword>Water</Keyword>
+ <Keyword>Tasmania</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="145.82989373832018" miny="-43.16951476167979" maxx="147.3614212616798" maxy="-41.63798723832021"/>
+ <BoundingBox SRS="EPSG:4326" minx="145.97161899999998" miny="-43.031944" maxx="147.219696" maxy="-41.775558"/>
+ <Style>
+ <Name>cite_lakes</Name>
+ <Title>Blue lake</Title>
+ <Abstract>A blue fill, solid black outline style</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_water_bodies"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>topp:states</Name>
+ <Title>USA Population</Title>
+ <Abstract>This is some census data on the states.</Abstract>
+ <KeywordList>
+ <Keyword>census</Keyword>
+ <Keyword>united</Keyword>
+ <Keyword>boundaries</Keyword>
+ <Keyword>state</Keyword>
+ <Keyword>states</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-131.05615308855994" miny="1.958333411440066" maxx="-60.645117911440046" maxy="72.36936858855995"/>
+ <BoundingBox SRS="EPSG:4326" minx="-124.73142200000001" miny="24.955967" maxx="-66.969849" maxy="49.371735"/>
+ <Style>
+ <Name>population</Name>
+ <Title>Population in the United States</Title>
+ <Abstract>A sample filter that filters the United States into three
+ categories of population, drawn in different colors</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:states"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>tiger:giant_polygon</Name>
+ <Title>World rectangle</Title>
+ <Abstract>A simple rectangular polygon covering most of the world, it\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract>
+ <KeywordList>
+ <Keyword>DS_giant_polygon</Keyword>
+ <Keyword>giant_polygon</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-257.0843245637291" miny="-257.0843245637291" maxx="257.0843245637291" maxy="257.0843245637291"/>
+ <BoundingBox SRS="EPSG:4326" minx="-180.0" miny="-90.0" maxx="180.0" maxy="90.0"/>
+ <Style>
+ <Name>giant_polygon</Name>
+ <Title>Border-less gray fill</Title>
+ <Abstract>Light gray polygon fill without a border</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:giant_polygon"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>nurc:Arc_Sample</Name>
+ <Title>Global annual rainfall</Title>
+ <Abstract>Global annual rainfall in ArcGrid format</Abstract>
+ <KeywordList>
+ <Keyword>WCS</Keyword>
+ <Keyword>arcGridSample</Keyword>
+ <Keyword>arcGridSample_Coverage</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-180.0" miny="-90.0" maxx="180.0" maxy="90.0"/>
+ <BoundingBox SRS="EPSG:4326" minx="-180.0" miny="-90.0" maxx="180.0" maxy="90.0"/>
+ <Style>
+ <Name>raster</Name>
+ <Title>Raster</Title>
+ <Abstract>A sample style for rasters, good for displaying imagery</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Arc_Sample"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>nurc:Img_Sample</Name>
+ <Title>North America sample imagery</Title>
+ <Abstract>A very rough imagery of North America</Abstract>
+ <KeywordList>
+ <Keyword>WCS</Keyword>
+ <Keyword>worldImageSample</Keyword>
+ <Keyword>worldImageSample_Coverage</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-130.85168" miny="20.7052" maxx="-62.0054" maxy="54.1141"/>
+ <BoundingBox SRS="EPSG:4326" minx="-130.85168" miny="20.7052" maxx="-62.0054" maxy="54.1141"/>
+ <Style>
+ <Name>raster</Name>
+ <Title>Raster</Title>
+ <Abstract>A sample style for rasters, good for displaying imagery</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Img_Sample"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>nurc:mosaic</Name>
+ <Title>Sample PNG mosaic</Title>
+ <Abstract>Subsampled satellite imagery loaded as a mosaic of PNG images</Abstract>
+ <KeywordList>
+ <Keyword>WCS</Keyword>
+ <Keyword>mosaic</Keyword>
+ <Keyword>mosaic</Keyword>
+ </KeywordList>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="6.34617490847439" miny="36.4917718219401" maxx="20.8296831527815" maxy="46.5907669751351"/>
+ <BoundingBox SRS="EPSG:4326" minx="6.34617490847439" miny="36.4917718219401" maxx="20.8296831527815" maxy="46.5907669751351"/>
+ <Style>
+ <Name>raster</Name>
+ <Title>Raster</Title>
+ <Abstract>A sample style for rasters, good for displaying imagery</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:mosaic"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>nurc:Pk50095</Name>
+ <Title>Sample scanned and georerenced map</Title>
+ <Abstract>This is a sample for the world image format (wld + prj + tiff)</Abstract>
+ <KeywordList>
+ <Keyword>WCS</Keyword>
+ <Keyword>img_sample2</Keyword>
+ <Keyword>Pk50095</Keyword>
+ </KeywordList>
+ <SRS>EPSG:32633</SRS>
+ <LatLonBoundingBox minx="12.999446822650462" miny="46.722110379286" maxx="13.308182612644663" maxy="46.91359611878293"/>
+ <BoundingBox SRS="EPSG:32633" minx="347649.93086859107" miny="5176214.082539256" maxx="370725.976428591" maxy="5196961.352859256"/>
+ <Style>
+ <Name>raster</Name>
+ <Title>Raster</Title>
+ <Abstract>A sample style for rasters, good for displaying imagery</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Pk50095"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>sf:sfdem</Name>
+ <Title>sfdem is a Tagged Image File Format with Geographic information</Title>
+ <Abstract>Generated from sfdem</Abstract>
+ <KeywordList>
+ <Keyword>WCS</Keyword>
+ <Keyword>sfdem</Keyword>
+ <Keyword>sfdem</Keyword>
+ </KeywordList>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.87108701853181" miny="44.370187074132616" maxx="-103.62940739432703" maxy="44.5016011535299"/>
+ <BoundingBox SRS="EPSG:26713" minx="589980.0" miny="4913700.0" maxx="609000.0" maxy="4928010.0"/>
+ <Style>
+ <Name>dem</Name>
+ <Title>Simple DEM style</Title>
+ <Abstract>Classic elevation color progression</Abstract>
+ <LegendURL width="20" height="20">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:sfdem"/>
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="0">
+ <Name>spearfish</Name>
+ <Title>spearfish</Title>
+ <Abstract>Layer-Group type layer: spearfish</Abstract>
+ <SRS>EPSG:26713</SRS>
+ <LatLonBoundingBox minx="-103.87799562257162" miny="44.37244213023845" maxx="-103.62286957414864" maxy="44.5023266635277"/>
+ <BoundingBox SRS="EPSG:26713" minx="589425.9342365642" miny="4913959.224611808" maxx="609518.6719560538" maxy="4928082.949945881"/>
+ </Layer>
+ <Layer queryable="0">
+ <Name>tasmania</Name>
+ <Title>tasmania</Title>
+ <Abstract>Layer-Group type layer: tasmania</Abstract>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="143.83482400000003" miny="-43.648056" maxx="148.47914100000003" maxy="-39.573891"/>
+ <BoundingBox SRS="EPSG:4326" minx="143.83482400000003" miny="-43.648056" maxx="148.47914100000003" maxy="-39.573891"/>
+ </Layer>
+ <Layer queryable="0">
+ <Name>tiger-ny</Name>
+ <Title>tiger-ny</Title>
+ <Abstract>Layer-Group type layer: tiger-ny</Abstract>
+ <SRS>EPSG:4326</SRS>
+ <LatLonBoundingBox minx="-74.047185" miny="40.679648" maxx="-73.907005" maxy="40.882078"/>
+ <BoundingBox SRS="EPSG:4326" minx="-74.047185" miny="40.679648" maxx="-73.907005" maxy="40.882078"/>
+ </Layer>
+ </Layer>
+ </Capability>
+</WMT_MS_Capabilities>--></div>
+
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1_WMSC.html b/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1_WMSC.html
new file mode 100644
index 0000000..044773d
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1_WMSC.html
@@ -0,0 +1,348 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read(t) {
+
+ t.plan(9);
+
+ var xml = document.getElementById("wmsc").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var format = new OpenLayers.Format.WMSCapabilities({profile: "WMSC"});
+ var obj = format.read(doc);
+ var tilesets = obj.capability.vendorSpecific.tileSets;
+ t.eq(tilesets.length, 2, "We expect 2 tilesets to be parsed");
+ var tileset = tilesets[0];
+ t.eq(tileset.bbox["EPSG:900913"].bbox, [-13697515.466796875, 5165920.118906248, -13619243.94984375, 5244191.635859374], "BBOX correctly parsed");
+ t.eq(tileset.format, "image/png", "Format correctly parsed");
+ t.eq(tileset.height, 256, "Height correctly parsed");
+ t.eq(tileset.width, 256, "Width correctly parsed");
+ t.eq(tileset.layers, "medford:hydro", "Layers correctly parsed");
+ t.eq(tileset.srs["EPSG:900913"], true, "SRS correctly parsed");
+ t.eq(tileset.resolutions, [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, 0.07464553542435169, 0.037322767712175846, 0.018661383856087923, 0.009330691928043961, 0.004665345964021981], "Resolutions correctly parsed");
+ t.eq(tileset.styles, "", "Styles correctly parsed");
+ }
+
+ function test_read_fallback(t) {
+ t.plan(1);
+ var xml = document.getElementById("fallback").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var format = new OpenLayers.Format.WMSCapabilities({profile: "WMSC", allowFallback: true});
+ var obj = format.read(doc);
+ t.eq(obj.capability.layers.length, 2, "2 layers parsed with allowFallback true");
+ }
+
+ </script>
+</head>
+<body>
+
+<div id="fallback"><!--
+<?xml version='1.0' encoding="ISO-8859-1" standalone="no" ?>
+<!DOCTYPE WMT_MS_Capabilities SYSTEM "http://schemas.opengis.net/wms/1.1.0/capabilities_1_1_0.dtd"
+ [
+ <!ELEMENT VendorSpecificCapabilities EMPTY>
+ ]>
+<WMT_MS_Capabilities version="1.1.0">
+
+<Service>
+ <Name>OGC:WMS</Name>
+ <Title>i3Geo - i3geo</Title>
+ <Abstract>Web services gerados da base de dados do i3Geo. Para chamar um tema especificamente, veja o sistema de ajuda, digitando no navegador web ogc.php?ajuda=, para uma lista compacta de todos os servicos, digite ogc.php?lista=temas</Abstract>
+ <KeywordList>
+ <Keyword>i3Geo</Keyword>
+ </KeywordList>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/>
+ <ContactInformation>
+ <ContactPersonPrimary>
+ <ContactPerson>Web Master</ContactPerson>
+ <ContactOrganization>Coordena??o Geral de TI</ContactOrganization>
+ </ContactPersonPrimary>
+ <ContactPosition>Administrador do s?tio web</ContactPosition>
+ <ContactAddress>
+ <AddressType>uri</AddressType>
+ <Address>http://www.mma.gov.br</Address>
+ <City>Brasilia</City>
+ <StateOrProvince>DF</StateOrProvince>
+ <PostCode></PostCode>
+ <Country>Brasil</Country>
+ </ContactAddress>
+ <ContactElectronicMailAddress>geoprocessamento@mma.gov.br</ContactElectronicMailAddress>
+ </ContactInformation>
+ <Fees>none</Fees>
+ <AccessConstraints>vedado o uso comercial</AccessConstraints>
+</Service>
+
+<Capability>
+ <Request>
+ <GetCapabilities>
+ <Format>application/vnd.ogc.wms_xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Get>
+ <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Post>
+ </HTTP>
+ </DCPType>
+ </GetCapabilities>
+ <GetMap>
+ <Format>image/png</Format>
+ <Format>image/jpeg</Format>
+ <Format>image/gif</Format>
+ <Format>image/png; mode=8bit</Format>
+ <Format>application/x-pdf</Format>
+ <Format>image/svg+xml</Format>
+ <Format>image/tiff</Format>
+ <Format>application/vnd.google-earth.kml+xml</Format>
+ <Format>application/vnd.google-earth.kmz</Format>
+ <DCPType>
+ <HTTP>
+ <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Get>
+ <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Post>
+ </HTTP>
+ </DCPType>
+ </GetMap>
+ <GetFeatureInfo>
+ <Format>text/plain</Format>
+ <Format>application/vnd.ogc.gml</Format>
+ <DCPType>
+ <HTTP>
+ <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Get>
+ <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Post>
+ </HTTP>
+ </DCPType>
+ </GetFeatureInfo>
+ <DescribeLayer>
+ <Format>text/xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Get>
+ <Post><OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo/ogc.php?"/></Post>
+ </HTTP>
+ </DCPType>
+ </DescribeLayer>
+ </Request>
+ <Exception>
+ <Format>application/vnd.ogc.se_xml</Format>
+ <Format>application/vnd.ogc.se_inimage</Format>
+ <Format>application/vnd.ogc.se_blank</Format>
+ </Exception>
+ <VendorSpecificCapabilities />
+ <UserDefinedSymbolization SupportSLD="1" UserLayer="0" UserStyle="1" RemoteWFS="0"/>
+ <Layer>
+ <Name>i3geoogc</Name>
+ <Title>i3Geo - i3geo</Title>
+ <Abstract>Web services gerados da base de dados do i3Geo. Para chamar um tema especificamente, veja o sistema de ajuda, digitando no navegador web ogc.php?ajuda=, para uma lista compacta de todos os servicos, digite ogc.php?lista=temas</Abstract>
+ <KeywordList>
+ <Keyword>i3Geo</Keyword>
+ </KeywordList>
+ <SRS></SRS>
+ <LatLonBoundingBox minx="-76.5126" miny="-36.9484" maxx="-29.5852" maxy="7.04601" />
+ <BoundingBox SRS=""
+ minx="-76.5126" miny="-36.9484" maxx="-29.5852" maxy="7.04601" />
+ <Attribution>
+ <Title>i3Geo</Title>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://mapas.mma.gov.br/i3geo"/>
+ <LogoURL width="85" height="56">
+ <Format>image/png</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://mapas.mma.gov.br/i3geo/imagens/i3geo.png"/>
+ </LogoURL>
+ </Attribution>
+ <Layer queryable="1" opaque="0" cascaded="0">
+ <Name>antigo_caminantes</Name>
+ <Title>Guia de Caminantes - 1817</Title>
+ <SRS> EPSG:4618 EPSG:4291 EPSG:4326 EPSG:22521 EPSG:22522 EPSG:22523 EPSG:22524 EPSG:22525 EPSG:29101 EPSG:29119 EPSG:29120 EPSG:29121 EPSG:29122 EPSG:29177 EPSG:29178 EPSG:29179 EPSG:29180 EPSG:29181 EPSG:29182 EPSG:29183 EPSG:29184 EPSG:29185</SRS>
+ <LatLonBoundingBox minx="-75.2336" miny="-33.7516" maxx="-27.593" maxy="5.27216" />
+ <BoundingBox SRS=""
+ minx="-75.2336" miny="-33.7516" maxx="-27.593" maxy="5.27216" />
+ <MetadataURL type="TC211">
+ <Format>text/html</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://consorcio.bn.br"/>
+ </MetadataURL>
+ </Layer>
+ </Layer>
+</Capability>
+</WMT_MS_Capabilities>
+--></div>
+
+<div id="wmsc"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE WMT_MS_Capabilities SYSTEM "http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.dtd"[
+<!ELEMENT VendorSpecificCapabilities (TileSet*) >
+<!ELEMENT TileSet (SRS, BoundingBox?, Resolutions, Width, Height, Format, Layers*, Styles*) >
+<!ELEMENT Resolutions (#PCDATA) >
+<!ELEMENT Width (#PCDATA) >
+<!ELEMENT Height (#PCDATA) >
+<!ELEMENT Layers (#PCDATA) >
+<!ELEMENT Styles (#PCDATA) >
+]>
+<WMT_MS_Capabilities version="1.1.1" updateSequence="57">
+ <Service>
+ <Name>OGC:WMS</Name>
+ <Title>GeoServer Web Map Service</Title>
+ <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>
+ <KeywordList>
+ <Keyword>WFS</Keyword>
+ <Keyword>WMS</Keyword>
+ <Keyword>GEOSERVER</Keyword>
+ </KeywordList>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms"/>
+ <ContactInformation>
+ <ContactPersonPrimary>
+ <ContactPerson>OpenGeo</ContactPerson>
+ <ContactOrganization>OpenGeo</ContactOrganization>
+ </ContactPersonPrimary>
+ <ContactPosition>Outreach</ContactPosition>
+ <ContactAddress>
+ <AddressType>Work</AddressType>
+ <Address/>
+ <City>New York</City>
+ <StateOrProvince/>
+ <PostCode/>
+ <Country>USA</Country>
+ </ContactAddress>
+ <ContactVoiceTelephone/>
+ <ContactFacsimileTelephone/>
+ <ContactElectronicMailAddress>inquiry@opengeo.org</ContactElectronicMailAddress>
+ </ContactInformation>
+ <Fees>NONE</Fees>
+ <AccessConstraints>NONE</AccessConstraints>
+ </Service>
+ <Capability>
+ <Request>
+ <GetCapabilities>
+ <Format>application/vnd.ogc.wms_xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Post>
+ </HTTP>
+ </DCPType>
+ </GetCapabilities>
+ <GetMap>
+ <Format>image/png</Format>
+ <Format>application/atom xml</Format>
+ <Format>application/atom+xml</Format>
+ <Format>application/openlayers</Format>
+ <Format>application/pdf</Format>
+ <Format>application/rss xml</Format>
+ <Format>application/rss+xml</Format>
+ <Format>application/vnd.google-earth.kml</Format>
+ <Format>application/vnd.google-earth.kml xml</Format>
+ <Format>application/vnd.google-earth.kml+xml</Format>
+ <Format>application/vnd.google-earth.kmz</Format>
+ <Format>application/vnd.google-earth.kmz xml</Format>
+ <Format>application/vnd.google-earth.kmz+xml</Format>
+ <Format>atom</Format>
+ <Format>image/geotiff</Format>
+ <Format>image/geotiff8</Format>
+ <Format>image/gif</Format>
+ <Format>image/jpeg</Format>
+ <Format>image/png8</Format>
+ <Format>image/svg</Format>
+ <Format>image/svg xml</Format>
+ <Format>image/svg+xml</Format>
+ <Format>image/tiff</Format>
+ <Format>image/tiff8</Format>
+ <Format>kml</Format>
+ <Format>kmz</Format>
+ <Format>openlayers</Format>
+ <Format>rss</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetMap>
+ <GetFeatureInfo>
+ <Format>text/plain</Format>
+ <Format>application/vnd.ogc.gml</Format>
+ <Format>text/html</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Post>
+ </HTTP>
+ </DCPType>
+ </GetFeatureInfo>
+ <DescribeLayer>
+ <Format>application/vnd.ogc.wms_xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </DescribeLayer>
+ <GetLegendGraphic>
+ <Format>image/png</Format>
+ <Format>image/jpeg</Format>
+ <Format>image/gif</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetLegendGraphic>
+ <GetStyles>
+ <Format>application/vnd.ogc.sld+xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;"/>
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetStyles>
+ </Request>
+ <Exception>
+ <Format>application/vnd.ogc.se_xml</Format>
+ <Format>application/vnd.ogc.se_inimage</Format>
+ </Exception>
+ <VendorSpecificCapabilities>
+ <TileSet>
+ <SRS>EPSG:900913</SRS>
+ <BoundingBox SRS="EPSG:900913" minx="-1.3697515466796875E7" miny="5165920.118906248" maxx="-1.361924394984375E7" maxy="5244191.635859374"/>
+ <Resolutions>156543.03390625 78271.516953125 39135.7584765625 19567.87923828125 9783.939619140625 4891.9698095703125 2445.9849047851562 1222.9924523925781 611.4962261962891 305.74811309814453 152.87405654907226 76.43702827453613 38.218514137268066 19.109257068634033 9.554628534317017 4.777314267158508 2.388657133579254 1.194328566789627 0.5971642833948135 0.29858214169740677 0.14929107084870338 0.07464553542435169 0.037322767712175846 0.018661383856087923 0.009330691928043961 0.004665345964021981 </Resolutions>
+ <Width>256</Width>
+ <Height>256</Height>
+ <Format>image/png</Format>
+ <Layers>medford:hydro</Layers>
+ <Styles/>
+ </TileSet>
+ <TileSet>
+ <SRS>EPSG:4326</SRS>
+ <BoundingBox SRS="EPSG:4326" minx="-123.046875" miny="42.1875" maxx="-122.6953125" maxy="42.5390625"/>
+ <Resolutions>0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 6.866455078125E-4 3.4332275390625E-4 1.71661376953125E-4 8.58306884765625E-5 4.291534423828125E-5 2.1457672119140625E-5 1.0728836059570312E-5 5.364418029785156E-6 2.682209014892578E-6 1.341104507446289E-6 6.705522537231445E-7 3.3527612686157227E-7 1.6763806343078613E-7 8.381903171539307E-8 4.190951585769653E-8 2.0954757928848267E-8 </Resolutions>
+ <Width>256</Width>
+ <Height>256</Height>
+ <Format>image/gif</Format>
+ <Layers>medford</Layers>
+ <Styles/>
+ </TileSet>
+ </VendorSpecificCapabilities>
+ <UserDefinedSymbolization SupportSLD="1" UserLayer="1" UserStyle="1" RemoteWFS="1"/>
+ <Layer queryable="0" opaque="0" noSubsets="0">
+ <Title>GeoServer Web Map Service</Title>
+ <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>
+ <SRS>EPSG:4326</SRS>
+ <SRS>EPSG:900913</SRS>
+ <LatLonBoundingBox minx="-180.0" miny="-90.0" maxx="180.0" maxy="83.624"/>
+ </Layer>
+ </Capability>
+</WMT_MS_Capabilities>
+--></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMSCapabilities/v1_3_0.html b/misc/openlayers/tests/Format/WMSCapabilities/v1_3_0.html
new file mode 100644
index 0000000..7120b8c
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMSCapabilities/v1_3_0.html
@@ -0,0 +1,614 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_exception(t) {
+ t.plan(1);
+ var xml = document.getElementById("exceptionsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var format = new OpenLayers.Format.WMSCapabilities();
+ var obj = format.read(doc);
+ t.ok(!!obj.error, "Error reported correctly");
+ }
+
+ function test_layers(t) {
+
+ t.plan(25);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var capability = obj.capability;
+
+ var layers = {};
+ for (var i=0, len=capability.layers.length; i<len; i++) {
+ if ("name" in capability.layers[i]) {
+ layers[ capability.layers[i].name ] = capability.layers[i];
+ }
+ }
+
+ var rootlayer = capability.layers[ capability.layers.length - 1];
+
+ t.eq(rootlayer.srs,
+ {"CRS:84": true},
+ "SRS parsed correctly for root layer");
+ t.eq(layers["ROADS_RIVERS"].srs,
+ {"CRS:84": true, "EPSG:26986": true},
+ "Inheritance of SRS handled correctly when adding SRSes");
+ t.eq(layers["Temperature"].srs,
+ {"CRS:84": true},
+ "Inheritance of SRS handled correctly when redeclaring an inherited SRS");
+ t.eq(layers["Temperature"].infoFormats, ["text/xml", "text/plain", "text/html"], "infoFormats set correctly on layer");
+ var bbox = layers["ROADS_RIVERS"].bbox["EPSG:26986"];
+ t.eq(bbox.bbox,
+ [189000, 834000, 285000, 962000],
+ "Correct bbox from BoundingBox");
+ t.eq(bbox.res, {x: 1, y: 1}, "Correct resolution");
+ bbox = layers["ROADS_RIVERS"].bbox["CRS:84"];
+ t.eq(bbox.bbox,
+ [-71.63, 41.75, -70.78, 42.90],
+ "Correct bbox from BoundingBox (override)");
+ t.eq(bbox.res, {x: 0.01, y: 0.01}, "Correct resolution (override)");
+
+ bbox = layers["ROADS_1M"].bbox["EPSG:26986"];
+ t.eq(bbox.bbox,
+ [189000, 834000, 285000, 962000],
+ "Correctly inherited bbox");
+ t.eq(bbox.res, {x: 1, y: 1}, "Correctly inherited resolution");
+
+
+ var identifiers = layers["ROADS_RIVERS"].identifiers;
+ var authorities = layers["ROADS_RIVERS"].authorityURLs;
+
+ t.ok(identifiers, "got identifiers from layer ROADS_RIVERS");
+ t.ok("DIF_ID" in identifiers,
+ "authority attribute from Identifiers parsed correctly");
+ t.eq(identifiers["DIF_ID"],
+ "123456",
+ "Identifier value parsed correctly");
+ t.ok("DIF_ID" in authorities,
+ "AuthorityURLs parsed and inherited correctly");
+ t.eq(authorities["DIF_ID"],
+ "http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html",
+ "OnlineResource in AuthorityURLs parsed correctly");
+
+ var featurelist = layers["ROADS_RIVERS"].featureListURL;
+ t.ok(featurelist, "layer has FeatureListURL");
+ t.eq(featurelist.format,
+ "XML",
+ "FeatureListURL format parsed correctly");
+ t.eq(featurelist.href,
+ "http://www.university.edu/data/roads_rivers.gml",
+ "FeatureListURL OnlineResource parsed correctly");
+
+ t.eq(layers["Pressure"].queryable,
+ true,
+ "queryable property inherited correctly");
+ t.eq(layers["ozone_image"].queryable,
+ false,
+ "queryable property has correct default value");
+ t.eq(layers["population"].cascaded,
+ 1,
+ "cascaded property parsed correctly");
+ t.eq(layers["ozone_image"].fixedWidth,
+ 512,
+ "fixedWidth property correctly parsed");
+ t.eq(layers["ozone_image"].fixedHeight,
+ 256,
+ "fixedHeight property correctly parsed");
+ t.eq(layers["ozone_image"].opaque,
+ true,
+ "opaque property parsed correctly");
+ t.eq(layers["ozone_image"].noSubsets,
+ true,
+ "noSubsets property parsed correctly");
+
+
+ }
+
+ function test_dimensions(t) {
+
+ t.plan(8);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var capability = obj.capability;
+
+ var layers = {};
+ for (var i=0, len=capability.layers.length; i<len; i++) {
+ if ("name" in capability.layers[i]) {
+ layers[ capability.layers[i].name ] = capability.layers[i];
+ }
+ }
+
+ var time = layers["Clouds"].dimensions.time;
+ t.eq(time["default"], "2000-08-22", "Default time value parsed correctly");
+ t.eq(time.values.length, 1, "Currect number of time extent values/periods");
+ t.eq(time.values[0], "1999-01-01/2000-08-22/P1D", "Time extent values parsed correctly");
+
+ var elevation = layers["Pressure"].dimensions.elevation;
+ t.eq(elevation.units, "CRS:88", "Dimension units parsed correctly");
+ t.eq(elevation["default"], "0", "Default elevation value parsed correctly");
+ t.eq(elevation.nearestVal, true, "NearestValue parsed correctly");
+ t.eq(elevation.multipleVal, false, "Absense of MultipleValues handled correctly");
+ t.eq(elevation.values,
+ ["0","1000","3000","5000","10000"],
+ "Parsing of comma-separated values done correctly");
+
+
+ }
+
+ function test_contactinfo(t) {
+ t.plan(14);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var service = obj.service;
+
+ var contactinfo = service.contactInformation;
+ t.ok(contactinfo, "object contains contactInformation property");
+
+ var personPrimary = contactinfo.personPrimary;
+ t.ok(personPrimary, "object contains personPrimary property");
+
+ t.eq(personPrimary.person, "Jeff Smith", "ContactPerson parsed correctly");
+ t.eq(personPrimary.organization, "NASA", "ContactOrganization parsed correctly");
+
+ t.eq(contactinfo.position,
+ "Computer Scientist",
+ "ContactPosition parsed correctly");
+
+
+ var addr = contactinfo.contactAddress;
+ t.ok(addr, "object contains contactAddress property");
+
+ t.eq(addr.type, "postal", "AddressType parsed correctly");
+ t.eq(addr.address,
+ "NASA Goddard Space Flight Center",
+ "Address parsed correctly");
+ t.eq(addr.city, "Greenbelt", "City parsed correctly");
+ t.eq(addr.stateOrProvince, "MD", "StateOrProvince parsed correctly");
+ t.eq(addr.postcode, "20771", "PostCode parsed correctly");
+ t.eq(addr.country, "USA", "Country parsed correctly");
+
+ t.eq(contactinfo.phone,
+ "+1 301 555-1212",
+ "ContactVoiceTelephone parsed correctly");
+ t.eq(contactinfo.email,
+ "user@host.com",
+ "ContactElectronicMailAddress parsed correctly");
+ }
+
+ function test_feesAndConstraints(t) {
+ t.plan(2);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var service = obj.service;
+
+ t.ok(! ("fees" in service), "Fees=none handled correctly");
+ t.ok(! ("accessConstraints" in service), "AccessConstraints=none handled correctly");
+ }
+
+ function test_requests(t) {
+ t.plan(6);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var request = obj.capability.request;
+
+ t.ok(request, "request property exists");
+ t.ok("getmap" in request, "got GetMap request");
+
+ t.ok("getfeatureinfo" in request, "got GetFeatureInfo request");
+ t.eq(request.getfeatureinfo.formats,
+ ["text/xml", "text/plain", "text/html"],
+ "GetFeatureInfo formats correctly parsed");
+
+ var exception = obj.capability.exception;
+ t.ok(exception, "exception property exists");
+ t.eq(exception.formats,
+ ["XML", "INIMAGE", "BLANK"],
+ "Exception Format parsed");
+ }
+
+ function test_ogc(t) {
+ t.plan(14);
+
+ /*
+ * Set up
+ */
+
+ // needed for the minScale/maxScale test, see below
+ var dpi = OpenLayers.DOTS_PER_INCH;
+ OpenLayers.DOTS_PER_INCH = 90.71;
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+ var capability = obj.capability;
+
+ /*
+ * Test
+ */
+
+ var attribution = capability.layers[2].attribution;
+ t.eq(attribution.title, "State College University", "attribution title parsed correctly.");
+ t.eq(attribution.href, "http://www.university.edu/", "attribution href parsed correctly.")
+ t.eq(attribution.logo.href, "http://www.university.edu/icons/logo.gif", "attribution logo url parsed correctly.");
+ t.eq(attribution.logo.format, "image/gif", "attribution logo format parsed correctly.");
+ t.eq(attribution.logo.width, "100", "attribution logo width parsed correctly.");
+ t.eq(attribution.logo.height, "100", "attribution logo height parsed correctly.");
+
+ var keywords = capability.layers[0].keywords;
+ t.eq(keywords.length, 3, "layer has 3 keywords.");
+ t.eq(keywords[0].value, "road", "1st keyword parsed correctly.");
+
+ var metadataURLs = capability.layers[0].metadataURLs;
+ t.eq(metadataURLs.length, 2, "layer has 2 metadata urls.");
+ t.eq(metadataURLs[0].type, "FGDC:1998", "type parsed correctly.");
+ t.eq(metadataURLs[0].format, "text/plain", "format parsed correctly.");
+ t.eq(metadataURLs[0].href, "http://www.university.edu/metadata/roads.txt", "href parsed correctly.");
+
+ /*
+ Test minScale and maxScale
+ */
+ var minScale = 250000;
+ var maxScale = 1000;
+ t.eq(capability.layers[0].minScale, minScale.toPrecision(16), "layer.minScale is correct");
+ t.eq(capability.layers[0].maxScale, maxScale.toPrecision(16), "layer.maxScale is correct");
+
+ /*
+ * Tear down
+ */
+
+ OpenLayers.DOTS_PER_INCH = dpi;
+ }
+
+ function test_WMS13specials(t) {
+ t.plan(3);
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMSCapabilities().read(doc);
+
+ t.eq(obj.service.layerLimit, 16, "LayerLimit parsed correctly");
+ t.eq(obj.service.maxHeight, 2048, "MaxHeight parsed correctly");
+ t.eq(obj.service.maxWidth, 2048, "MaxWidth parsed correctly");
+
+ }
+
+ </script>
+</head>
+<body>
+
+<div id="exceptionsample"><!--
+<?xml version='1.0' encoding="UTF-8"?>
+<ServiceExceptionReport version="1.3.0" xmlns="http://www.opengis.net/ogc"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.opengis.net/ogc
+ http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
+ <ServiceException> Plain text message about an error. </ServiceException>
+ <ServiceException code="InvalidUpdateSequence"> Another error message, this one with a service
+ exception code supplied. </ServiceException>
+ <ServiceException>
+ <![CDATA[ Error in module <foo.c>, line 42
+A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:
+]]>
+ </ServiceException>
+ <ServiceException>
+ <![CDATA[ <Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation> ]]>
+ </ServiceException>
+</ServiceExceptionReport>
+--></div>
+
+<!--
+OGC example below taken from
+http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xml
+Changes:
+-removed comments
+-corrected typo in FeatureListURL Format XML with double quote
+-added MinScaleDenominator and MaxScaleDenominator
+-remove whitespace in Dimension tags
+-->
+<div id="ogcsample"><!--
+<?xml version='1.0' encoding="UTF-8"?>
+<WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd">
+<Service>
+ <Name>WMS</Name>
+ <Title>Acme Corp. Map Server</Title>
+ <Abstract>Map Server maintained by Acme Corporation. Contact: webmaster@wmt.acme.com. High-quality maps showing roadrunner nests and possible ambush locations.</Abstract>
+
+ <KeywordList>
+ <Keyword>bird</Keyword>
+ <Keyword>roadrunner</Keyword>
+ <Keyword>ambush</Keyword>
+ </KeywordList>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://hostname/" />
+
+
+ <ContactInformation>
+ <ContactPersonPrimary>
+ <ContactPerson>Jeff Smith</ContactPerson>
+ <ContactOrganization>NASA</ContactOrganization>
+ </ContactPersonPrimary>
+ <ContactPosition>Computer Scientist</ContactPosition>
+
+ <ContactAddress>
+ <AddressType>postal</AddressType>
+ <Address>NASA Goddard Space Flight Center</Address>
+ <City>Greenbelt</City>
+ <StateOrProvince>MD</StateOrProvince>
+ <PostCode>20771</PostCode>
+
+ <Country>USA</Country>
+ </ContactAddress>
+ <ContactVoiceTelephone>+1 301 555-1212</ContactVoiceTelephone>
+ <ContactElectronicMailAddress>user@host.com</ContactElectronicMailAddress>
+ </ContactInformation>
+
+ <Fees>none</Fees>
+
+ <AccessConstraints>none</AccessConstraints>
+ <LayerLimit>16</LayerLimit>
+ <MaxWidth>2048</MaxWidth>
+ <MaxHeight>2048</MaxHeight>
+</Service>
+<Capability>
+ <Request>
+ <GetCapabilities>
+
+ <Format>text/xml</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname/path?" />
+ </Get>
+ <Post>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname/path?" />
+
+ </Post>
+ </HTTP>
+ </DCPType>
+ </GetCapabilities>
+ <GetMap>
+ <Format>image/gif</Format>
+ <Format>image/png</Format>
+ <Format>image/jpeg</Format>
+
+ <DCPType>
+ <HTTP>
+ <Get>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname/path?" />
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetMap>
+
+ <GetFeatureInfo>
+ <Format>text/xml</Format>
+ <Format>text/plain</Format>
+ <Format>text/html</Format>
+ <DCPType>
+ <HTTP>
+ <Get>
+
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://hostname/path?" />
+ </Get>
+ </HTTP>
+ </DCPType>
+ </GetFeatureInfo>
+ </Request>
+ <Exception>
+ <Format>XML</Format>
+
+ <Format>INIMAGE</Format>
+ <Format>BLANK</Format>
+ </Exception>
+ <Layer>
+ <Title>Acme Corp. Map Server</Title>
+ <CRS>CRS:84</CRS>
+
+ <AuthorityURL name="DIF_ID">
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html" />
+ </AuthorityURL>
+ <BoundingBox CRS="CRS:84"
+ minx="-1" miny="-1" maxx="1" maxy="1" resx="0.0" resy="0.0"/>
+ <Layer>
+
+ <Name>ROADS_RIVERS</Name>
+ <Title>Roads and Rivers</Title>
+
+ <CRS>EPSG:26986</CRS>
+ <EX_GeographicBoundingBox>
+ <westBoundLongitude>-71.63</westBoundLongitude>
+ <eastBoundLongitude>-70.78</eastBoundLongitude>
+ <southBoundLatitude>41.75</southBoundLatitude>
+ <northBoundLatitude>42.90</northBoundLatitude>
+
+ </EX_GeographicBoundingBox>
+ <BoundingBox CRS="CRS:84"
+ minx="-71.63" miny="41.75" maxx="-70.78" maxy="42.90" resx="0.01" resy="0.01"/>
+ <BoundingBox CRS="EPSG:26986"
+ minx="189000" miny="834000" maxx="285000" maxy="962000" resx="1" resy="1" />
+ <Attribution>
+ <Title>State College University</Title>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://www.university.edu/" />
+
+ <LogoURL width="100" height="100">
+ <Format>image/gif</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/icons/logo.gif" />
+ </LogoURL>
+ </Attribution>
+ <Identifier authority="DIF_ID">123456</Identifier>
+ <FeatureListURL>
+
+ <Format>XML</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
+ xlink:href="http://www.university.edu/data/roads_rivers.gml" />
+ </FeatureListURL>
+ <Style>
+ <Name>USGS</Name>
+ <Title>USGS Topo Map Style</Title>
+ <Abstract>Features are shown in a style like that used in USGS topographic maps.</Abstract>
+
+ <LegendURL width="72" height="72">
+ <Format>image/gif</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/legends/usgs.gif" />
+ </LegendURL>
+ <StyleSheetURL>
+ <Format>text/xsl</Format>
+
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/stylesheets/usgs.xsl" />
+ </StyleSheetURL>
+ </Style>
+ <MinScaleDenominator>1000</MinScaleDenominator>
+ <MaxScaleDenominator>250000</MaxScaleDenominator>
+ <Layer queryable="1">
+ <Name>ROADS_1M</Name>
+ <Title>Roads at 1:1M scale</Title>
+ <Abstract>Roads at a scale of 1 to 1 million.</Abstract>
+
+ <KeywordList>
+ <Keyword>road</Keyword>
+ <Keyword>transportation</Keyword>
+ <Keyword>atlas</Keyword>
+ </KeywordList>
+ <Identifier authority="DIF_ID">123456</Identifier>
+ <MetadataURL type="FGDC:1998">
+
+ <Format>text/plain</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/metadata/roads.txt" />
+ </MetadataURL>
+ <MetadataURL type="ISO19115:2003">
+ <Format>text/xml</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/metadata/roads.xml" />
+ </MetadataURL>
+
+ <Style>
+ <Name>ATLAS</Name>
+ <Title>Road atlas style</Title>
+ <Abstract>Roads are shown in a style like that used in a commercial road atlas.</Abstract>
+ <LegendURL width="72" height="72">
+ <Format>image/gif</Format>
+ <OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:type="simple"
+ xlink:href="http://www.university.edu/legends/atlas.gif" />
+
+ </LegendURL>
+ </Style>
+ </Layer>
+ <Layer queryable="1">
+ <Name>RIVERS_1M</Name>
+ <Title>Rivers at 1:1M scale</Title>
+ <Abstract>Rivers at a scale of 1 to 1 million.</Abstract>
+
+ <KeywordList>
+ <Keyword>river</Keyword>
+ <Keyword>canal</Keyword>
+ <Keyword>waterway</Keyword>
+ </KeywordList>
+ </Layer>
+ </Layer>
+
+ <Layer queryable="1">
+ <Title>Weather Forecast Data</Title>
+ <CRS>CRS:84</CRS>
+
+ <EX_GeographicBoundingBox>
+ <westBoundLongitude>-180</westBoundLongitude>
+ <eastBoundLongitude>180</eastBoundLongitude>
+
+ <southBoundLatitude>-90</southBoundLatitude>
+ <northBoundLatitude>90</northBoundLatitude>
+ </EX_GeographicBoundingBox>
+ <Dimension name="time" units="ISO8601" default="2000-08-22">1999-01-01/2000-08-22/P1D</Dimension>
+ <Layer>
+
+ <Name>Clouds</Name>
+ <Title>Forecast cloud cover</Title>
+ </Layer>
+ <Layer>
+ <Name>Temperature</Name>
+ <Title>Forecast temperature</Title>
+ </Layer>
+
+ <Layer>
+ <Name>Pressure</Name>
+ <Title>Forecast barometric pressure</Title>
+ <Dimension name="elevation" units="EPSG:5030" />
+ <Dimension name="time" units="ISO8601" default="2000-08-22">
+ 1999-01-01/2000-08-22/P1D</Dimension>
+
+ <Dimension name="elevation" units="CRS:88" default="0" nearestValue="1">0,1000,3000,5000,10000</Dimension>
+ </Layer>
+ </Layer>
+ <Layer opaque="1" noSubsets="1" fixedWidth="512" fixedHeight="256">
+ <Name>ozone_image</Name>
+ <Title>Global ozone distribution (1992)</Title>
+
+ <EX_GeographicBoundingBox>
+ <westBoundLongitude>-180</westBoundLongitude>
+ <eastBoundLongitude>180</eastBoundLongitude>
+ <southBoundLatitude>-90</southBoundLatitude>
+ <northBoundLatitude>90</northBoundLatitude>
+ </EX_GeographicBoundingBox>
+ <Dimension name="time" units="ISO8601" default="1992">1992</Dimension>
+
+ </Layer>
+ <Layer cascaded="1">
+ <Name>population</Name>
+ <Title>World population, annual</Title>
+ <EX_GeographicBoundingBox>
+ <westBoundLongitude>-180</westBoundLongitude>
+
+ <eastBoundLongitude>180</eastBoundLongitude>
+ <southBoundLatitude>-90</southBoundLatitude>
+ <northBoundLatitude>90</northBoundLatitude>
+ </EX_GeographicBoundingBox>
+ <Dimension name="time" units="ISO8601" default="2000">1990/2000/P1Y</Dimension>
+ </Layer>
+ </Layer>
+
+</Capability>
+</WMS_Capabilities>
+--></div>
+
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMSDescribeLayer.html b/misc/openlayers/tests/Format/WMSDescribeLayer.html
new file mode 100644
index 0000000..7a53269
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMSDescribeLayer.html
@@ -0,0 +1,65 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_WMSDescribeLayer(t) {
+ t.plan(10);
+
+ var parser = new OpenLayers.Format.WMSDescribeLayer();
+
+ var text =
+ '<WMS_DescribeLayerResponse version="1.1.1">' +
+ ' <LayerDescription name="topp:states" wfs="http://geo.openplans.org:80/geoserver/wfs/WfsDispatcher?">' +
+ ' <Query typeName="topp:states"/>' +
+ ' </LayerDescription>' +
+ '</WMS_DescribeLayerResponse>';
+
+ var res = parser.read(text);
+
+ t.eq(res.layerDescriptions.length, 1,
+ "Only one LayerDescription in data, so only one parsed");
+
+ t.eq(res.layerDescriptions[0].owsType, "WFS",
+ "Properly parses owsType as WFS");
+
+ t.eq(res.layerDescriptions[0].owsURL, "http://geo.openplans.org:80/geoserver/wfs/WfsDispatcher?",
+ "Properly parses owsURL");
+
+ t.eq(res.layerDescriptions[0].typeName, "topp:states",
+ "Properly parses typeName");
+
+ t.eq(res.layerDescriptions[0].layerName, "topp:states",
+ "Properly parses name");
+
+ //TODO remove the 5 tests below when we deprecate the old structure
+ t.eq(res.length, 1,
+ "Only one LayerDescription in data, so only one parsed");
+ t.eq(res[0].owsType, "WFS",
+ "Properly parses owsType as WFS");
+ t.eq(res[0].owsURL, "http://geo.openplans.org:80/geoserver/wfs/WfsDispatcher?",
+ "Properly parses owsURL");
+ t.eq(res[0].typeName, "topp:states",
+ "Properly parses typeName");
+ t.eq(res[0].layerName, "topp:states",
+ "Properly parses name");
+
+ }
+
+ function test_read_exception(t) {
+ t.plan(1);
+ var text = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
+ '<!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd">' +
+ '<ServiceExceptionReport version="1.1.1" > <ServiceException code="LayerNotDefined">' +
+ 'geonode:_map_107_annotations: no such layer on this server' +
+ '</ServiceException></ServiceExceptionReport>';
+ var format = new OpenLayers.Format.WMSDescribeLayer();
+ var obj = format.read(text);
+ t.ok(!!obj.error, "Error reported correctly");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMSGetFeatureInfo.html b/misc/openlayers/tests/Format/WMSGetFeatureInfo.html
new file mode 100644
index 0000000..1301b65
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMSGetFeatureInfo.html
@@ -0,0 +1,319 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_FeatureInfoResponse(t) {
+ t.plan(7);
+
+ var parser = new OpenLayers.Format.WMSGetFeatureInfo();
+
+ // read empty response
+ var text =
+ '<?xml version="1.0" encoding="UTF-8" ?>' +
+ '<FeatureInfoResponse>' +
+ '</FeatureInfoResponse>';
+
+ var features = parser.read(text);
+ t.eq(features.length, 0,
+ "Parsing empty FeatureInfoResponse response succesfull");
+
+ // read 1 feature
+ text =
+ '<?xml version="1.0" encoding="UTF-8" ?>' +
+ '<FeatureInfoResponse>' +
+ ' <FIELDS OBJECTID="1188" HECTARES="1819.734" ZONENR="5854" NULZONES=" " AREA="18197340.1426" PERIMETER="19177.4073627" SHAPE="NULL" SE_ANNO_CAD_DATA="NULL" SHAPE.AREA="0" SHAPE.LEN="0"/>' +
+ '</FeatureInfoResponse>';
+
+ features = parser.read(text);
+ t.eq(features.length, 1,
+ "Parsed 1 feature in total");
+
+ t.eq(features[0].attributes.OBJECTID, '1188',
+ "Attribute OBJECTID contains the right value");
+
+ // read multiple features
+ text =
+ '<?xml version="1.0" encoding="UTF-8" ?>' +
+ '<FeatureInfoResponse>' +
+ ' <FIELDS OBJECTID="551" Shape="NULL" NAME="Carbon" STATE_NAME="Wyoming" AREA="7999.91062" POP2000="15639" POP00_SQMI="2" Shape_Length="6.61737274334215" Shape_Area="2.23938983524154"/>' +
+ ' <FIELDS OBJECTID="7" Shape="NULL" AREA="97803.199" STATE_NAME="Wyoming" SUB_REGION="Mtn" STATE_ABBR="WY" POP2000="493782" POP00_SQMI="5" Shape_Length="21.9870297323522" Shape_Area="27.9666881382635"/>' +
+ ' <FIELDS OBJECTID="99" Shape="NULL" LENGTH="378.836" TYPE="Multi-Lane Divided" ADMN_CLASS="Interstate" TOLL_RD="N" RTE_NUM1=" 80" RTE_NUM2=" " ROUTE="Interstate 80" Shape_Length="7.04294883879398"/>' +
+ '</FeatureInfoResponse>';
+
+ features = parser.read(text);
+
+ t.eq(features.length, 3,
+ "Parsed 3 features in total");
+
+ t.eq(features[1].attributes.STATE_NAME, 'Wyoming',
+ "Attribute STATE_NAME contains the right value");
+
+ text = '<FeatureInfoResponse>' +
+ '<FIELDS>' +
+ '<FIELD name="ID" value="B31A0154"/>' +
+ '<FIELD name="FID" value="31AL0011"/>' +
+ '</FIELDS>' +
+ '<FIELDS>' +
+ '<FIELD name="ID" value="B31A0153"/>' +
+ '<FIELD name="FID" value="31AL0011"/>' +
+ '</FIELDS>' +
+ '</FeatureInfoResponse>';
+
+ features = parser.read(text);
+
+ t.eq(features.length, 2,
+ "Parsed 2 features in total");
+
+ t.eq(features[1].attributes.FID, '31AL0011',
+ "Attribute FID contains the right value");
+
+ }
+
+ function test_read_msGMLOutput(t) {
+ t.plan(13);
+
+ var parser = new OpenLayers.Format.WMSGetFeatureInfo();
+
+ // read empty response
+ var text =
+ '<?xml version="1.0" encoding="ISO-8859-1"?>' +
+ '<msGMLOutput ' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' xmlns:xlink="http://www.w3.org/1999/xlink"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
+ '</msGMLOutput>';
+
+ var features = parser.read(text);
+ t.eq(features.length, 0,
+ "Parsing empty msGMLOutput response succesfull");
+
+ // read empty attribute
+ text =
+ '<?xml version="1.0" encoding="ISO-8859-1"?>' +
+ '<msGMLOutput ' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' xmlns:xlink="http://www.w3.org/1999/xlink"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
+ ' <AAA64_layer>' +
+ ' <AAA64_feature>' +
+ ' <gml:boundedBy>' +
+ ' <gml:Box srsName="EPSG:28992">' +
+ ' <gml:coordinates>107397.266000,460681.063000 116568.188000,480609.250000</gml:coordinates>' +
+ ' </gml:Box>' +
+ ' </gml:boundedBy>' +
+ ' <FOO>bar</FOO>' +
+ ' <EMPTY></EMPTY>' +
+ ' </AAA64_feature>' +
+ ' </AAA64_layer>' +
+ '</msGMLOutput>';
+ features = parser.read(text);
+ t.eq((features[0].attributes.EMPTY === null), true, "Empty attribute is parsed as null");
+
+ // read 1 feature from 1 layer
+ text =
+ '<?xml version="1.0" encoding="ISO-8859-1"?>' +
+ '<msGMLOutput ' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' xmlns:xlink="http://www.w3.org/1999/xlink"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
+ ' <AAA64_layer>' +
+ ' <AAA64_feature>' +
+ ' <gml:boundedBy>' +
+ ' <gml:Box srsName="EPSG:28992">' +
+ ' <gml:coordinates>107397.266000,460681.063000 116568.188000,480609.250000</gml:coordinates>' +
+ ' </gml:Box>' +
+ ' </gml:boundedBy>' +
+ ' <OBJECTID>109</OBJECTID>' +
+ ' <ROUTE>N231</ROUTE>' +
+ ' <ROUTE_CH>#N231</ROUTE_CH>' +
+ ' <COUNT>2</COUNT>' +
+ ' <BEHEERDER>P</BEHEERDER>' +
+ ' <LENGTH>28641.7</LENGTH>' +
+ ' <SHAPE>&lt;shape&gt;</SHAPE>' +
+ ' <SE_ANNO_CAD_DATA>&lt;null&gt;</SE_ANNO_CAD_DATA>' +
+ ' </AAA64_feature>' +
+ ' </AAA64_layer>' +
+ '</msGMLOutput>';
+
+ features = parser.read(text);
+
+ t.eq(features.length, 1,
+ "Parsed 1 feature in total");
+
+ t.eq(features[0].attributes.OBJECTID, '109',
+ "Attribute OBJECTID contains the right value");
+
+ t.eq(features[0].type, 'AAA64',
+ "Parsed the layer name correctly");
+
+ var bounds = features[0].bounds;
+ t.ok(bounds instanceof OpenLayers.Bounds, "feature given a bounds");
+ t.eq(bounds.left.toFixed(3), "107397.266", "Bounds left parsed correctly");
+ t.eq(bounds.right.toFixed(3), "116568.188", "Bounds right parsed correctly");
+ t.eq(bounds.bottom.toFixed(3), "460681.063", "Bounds bottom parsed correctly");
+ t.eq(bounds.top.toFixed(3), "480609.250", "Bounds top parsed correctly");
+
+ // read 2 features from 2 layers
+ text =
+ '<?xml version="1.0" encoding="ISO-8859-1"?>' +
+ '<msGMLOutput ' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' xmlns:xlink="http://www.w3.org/1999/xlink"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'+
+ ' <AAA64_layer>' +
+ ' <AAA64_feature>' +
+ ' <gml:boundedBy>' +
+ ' <gml:Box srsName="EPSG:28992">' +
+ ' <gml:coordinates>129799.109000,467950.250000 133199.906000,468904.063000</gml:coordinates>' +
+ ' </gml:Box>' +
+ ' </gml:boundedBy>' +
+ ' <OBJECTID>287</OBJECTID>' +
+ ' <ROUTE>N403</ROUTE>' +
+ ' <ROUTE_CH>#N403</ROUTE_CH>' +
+ ' <COUNT>1</COUNT>' +
+ ' <BEHEERDER>P</BEHEERDER>' +
+ ' <LENGTH>4091.25</LENGTH>' +
+ ' <SHAPE>&lt;shape&gt;</SHAPE>' +
+ ' <SE_ANNO_CAD_DATA>&lt;null&gt;</SE_ANNO_CAD_DATA>' +
+ ' </AAA64_feature>' +
+ ' </AAA64_layer>' +
+ ' <AAA62_layer>' +
+ ' <AAA62_feature>' +
+ ' <gml:boundedBy>' +
+ ' <gml:Box srsName="EPSG:28992">' +
+ ' <gml:coordinates>129936.000000,468362.000000 131686.000000,473119.000000</gml:coordinates>' +
+ ' </gml:Box>' +
+ ' </gml:boundedBy>' +
+ ' <OBJECTID>1251</OBJECTID>' +
+ ' <VWK_ID>1515</VWK_ID>' +
+ ' <VWK_BEGDTM>00:00:00 01/01/1998</VWK_BEGDTM>' +
+ ' <VWJ_ID_BEG>1472</VWJ_ID_BEG>' +
+ ' <VWJ_ID_END>1309</VWJ_ID_END>' +
+ ' <VAKTYPE>D</VAKTYPE>' +
+ ' <VRT_CODE>227</VRT_CODE>' +
+ ' <VRT_NAAM>Vecht</VRT_NAAM>' +
+ ' <VWG_NR>2</VWG_NR>' +
+ ' <VWG_NAAM>Vecht</VWG_NAAM>' +
+ ' <BEGKM>18.25</BEGKM>' +
+ ' <ENDKM>23.995</ENDKM>' +
+ ' <LENGTH>5745.09</LENGTH>' +
+ ' <SHAPE>&lt;shape&gt;</SHAPE>' +
+ ' <SE_ANNO_CAD_DATA>&lt;null&gt;</SE_ANNO_CAD_DATA>' +
+ ' </AAA62_feature>' +
+ ' </AAA62_layer>' +
+ '</msGMLOutput>';
+
+ features = parser.read(text);
+
+ t.eq(features.length, 2,
+ "Parsed 2 features in total");
+
+ t.eq((features[0].type == features[1].type), false,
+ "The layer name differs for the two features");
+
+ text =
+ '<?xml version="1.0" encoding="ISO-8859-1"?>' +
+ '<msGMLOutput ' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' xmlns:xlink="http://www.w3.org/1999/xlink"' +
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
+ ' <wegbeheerderinfo_layer>' +
+ ' <wegbeheerderinfo_feature>' +
+ ' <gml:boundedBy>' +
+ ' <gml:Box srsName="EPSG:28992">' +
+ ' <gml:coordinates>105002.943000,490037.863000 105271.523000,490262.208000</gml:coordinates>' +
+ ' </gml:Box>' +
+ ' </gml:boundedBy>' +
+ ' <geometry>' +
+ ' <gml:MultiLineString srsName="EPSG:28992">' +
+ ' <gml:lineStringMember>' +
+ ' <gml:LineString>' +
+ ' <gml:coordinates>105270.164000,490262.208000 105098.274000,490258.040000 105028.045000,490089.576000 105002.943000,490048.851000 105049.666000,490037.863000 105271.523000,490064.957000 </gml:coordinates>' +
+ ' </gml:LineString>' +
+ ' </gml:lineStringMember>' +
+ ' </gml:MultiLineString>' +
+ ' </geometry>' +
+ ' <OGR_FID>203327</OGR_FID>' +
+ ' </wegbeheerderinfo_feature>' +
+ ' </wegbeheerderinfo_layer>' +
+ '</msGMLOutput>';
+
+ features = parser.read(text);
+
+ t.eq((features[0].geometry instanceof OpenLayers.Geometry.MultiLineString), true,
+ "Parsed geometry is of type multi line string");
+
+ }
+
+ function test_read_GMLFeatureInfoResponse(t) {
+ t.plan(4);
+
+ var parser = new OpenLayers.Format.WMSGetFeatureInfo();
+
+ // read Ionic response, see if parser falls back to GML format
+ // url used:
+ /* http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA?service=WMS&request=GetFeatureInfo&layers=roads&version=1.1.1&bbox=-71.1,42.25,-71.05,42.3&width=500&height=500&format=image/png&SRS=EPSG:4326&styles=&x=174&y=252&query_layers=roads&info_format=application/vnd.ogc.gml */
+ var text =
+ "<?xml version='1.0' encoding='utf-8' ?>" +
+ ' <ogcwfs:FeatureCollection xsi:schemaLocation="http://www.ionicsoft.com/wfs http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA?REQUEST=DescribeAllFeatureType&amp;SERVICE=WFS http://www.opengis.net/wfs http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA/REQUEST/get/DATA/LPR/wfs/1.0.0/WFS-basic.xsd" xmlns:wfs="http://www.ionicsoft.com/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogcwfs="http://www.opengis.net/wfs">' +
+ ' <gml:boundedBy>' +
+ ' <gml:Box srsName="EPSG:4326">' +
+ ' <gml:coordinates>-71.08301710045646,42.27320863544783 -71.08020014900377,42.27480054530114</gml:coordinates>' +
+ ' </gml:Box>' +
+ ' </gml:boundedBy>' +
+ ' <gml:featureMember>' +
+ ' <wfs:roads fid="roads.9453.0">' +
+ ' <wfs:FNODE_>8943.0</wfs:FNODE_>' +
+ ' <wfs:TNODE_>9070.0</wfs:TNODE_>' +
+ ' <wfs:LPOLY_>0.0</wfs:LPOLY_>' +
+ ' <wfs:RPOLY_>0.0</wfs:RPOLY_>' +
+ ' <wfs:LENGTH>306.875</wfs:LENGTH>' +
+ ' <wfs:MRD_>13109.0</wfs:MRD_>' +
+ ' <wfs:MRD_ID>9453.0</wfs:MRD_ID>' +
+ ' <wfs:TILE_NAME>126</wfs:TILE_NAME>' +
+ ' <wfs:COUNTYCODE>M</wfs:COUNTYCODE>' +
+ ' <wfs:SERIAL_NUM>26000.0</wfs:SERIAL_NUM>' +
+ ' <wfs:CLASS>5.0</wfs:CLASS>' +
+ ' <wfs:ADMIN_TYPE>0.0</wfs:ADMIN_TYPE>' +
+ ' <wfs:ALTRT1TYPE>0.0</wfs:ALTRT1TYPE>' +
+ ' <wfs:STREETNAME>DOCTOR MARY MOORE BEATTY CIRCLE</wfs:STREETNAME>' +
+ ' <wfs:CSN>M 26000</wfs:CSN>' +
+ ' <wfs:GEOMETRY>' +
+ ' <gml:LineString srsName="EPSG:4326">' +
+ ' <gml:coordinates>-71.08300668868151,42.27480054530114 -71.08155305289881,42.27452010256956 -71.08021063085208,42.27320863544783</gml:coordinates>' +
+ ' </gml:LineString>' +
+ ' </wfs:GEOMETRY>' +
+ ' </wfs:roads>' +
+ ' </gml:featureMember>' +
+ ' </ogcwfs:FeatureCollection>';
+
+ var features = parser.read(text);
+
+ t.eq(features.length, 1,
+ "Parsing GML GetFeatureInfo response from Ionic succesfull");
+
+ t.eq(features[0].attributes.TILE_NAME, '126',
+ "Attribute TILE_NAME contains the right value");
+
+ // read Geoserver response
+ // taken from:
+/* http://demo.opengeo.org/geoserver/wms?service=WMS&request=GetFeatureInfo&layers=opengeo:roads&query_layers=opengeo:roads&format=image/png&version=1.1.1&styles=&bbox=-103.9,44.4,-103.7,44.5&srs=EPSG:4326&width=500&height=500&x=158&y=98&info_format=application/vnd.ogc.gml*/
+
+ text = '<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:opengeo="http://opengeo.org" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://opengeo.org http://demo.opengeo.org:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=opengeo:roads http://www.opengis.net/wfs http://demo.opengeo.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd"><gml:boundedBy><gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#26713"><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">591943.9375,4925605 593045.625,4925845</gml:coordinates></gml:Box></gml:boundedBy><gml:featureMember><opengeo:roads fid="roads.90"><opengeo:cat>3</opengeo:cat><opengeo:label>secondary highway, hard surface</opengeo:label><opengeo:the_geom><gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#26713"><gml:lineStringMember><gml:LineString><gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">593045.60746465,4925605.0059156 593024.32382915,4925606.79305411 592907.54863574,4925624.85647524 592687.35111096,4925670.76834012 592430.76279218,4925678.79393165 592285.97636109,4925715.70811767 592173.39165655,4925761.83511156 592071.1753393,4925793.95523514 591985.96972625,4925831.59842486 591943.98769455,4925844.93220071</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></opengeo:the_geom></opengeo:roads></gml:featureMember></wfs:FeatureCollection>';
+
+ features = parser.read(text);
+
+ t.eq(features.length, 1,
+ "Parsing GML GetFeatureInfo response from Geoserver succesfull");
+
+ t.eq(features[0].attributes.cat, '3',
+ "Attribute cat contains the right value");
+
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMTSCapabilities.html b/misc/openlayers/tests/Format/WMTSCapabilities.html
new file mode 100644
index 0000000..e7a51a3
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMTSCapabilities.html
@@ -0,0 +1,20 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+
+ t.plan(1);
+ var format = new OpenLayers.Format.WMTSCapabilities({
+ version: "foo"
+ });
+ t.eq(format.version, "foo", "version set on format");
+
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WMTSCapabilities/v1_0_0.html b/misc/openlayers/tests/Format/WMTSCapabilities/v1_0_0.html
new file mode 100644
index 0000000..f4fadeb
--- /dev/null
+++ b/misc/openlayers/tests/Format/WMTSCapabilities/v1_0_0.html
@@ -0,0 +1,1042 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_ows(t) {
+ t.plan(20);
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);
+ // ows:ServiceIdentification
+ var serviceIdentification = obj.serviceIdentification;
+ t.eq(serviceIdentification.title, "Web Map Tile Service", "ows:ServiceIdentification title is correct");
+ t.eq(serviceIdentification.serviceTypeVersion, "1.0.0", "ows:ServiceIdentification serviceTypeVersion is correct");
+ t.eq(serviceIdentification.serviceType.value, "OGC WMTS", "ows:ServiceIdentification serviceType is correct");
+
+ // ows:ServiceProvider
+ var serviceProvider = obj.serviceProvider;
+ t.eq(serviceProvider.providerName, "MiraMon", "ows:ServiceProvider providerName is correct");
+ t.eq(serviceProvider.providerSite, "http://www.creaf.uab.es/miramon", "ows:ServiceProvider providerSite is correct");
+ t.eq(serviceProvider.serviceContact.individualName, "Joan Maso Pau", "ows:ServiceProvider individualName is correct");
+ t.eq(serviceProvider.serviceContact.positionName, "Senior Software Engineer", "ows:ServiceProvider positionName is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.address.administrativeArea, "Barcelona", "ows:ServiceProvider address administrativeArea is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.address.city, "Bellaterra", "ows:ServiceProvider address city is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.address.country, "Spain", "ows:ServiceProvider address country is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.address.deliveryPoint, "Fac Ciencies UAB", "ows:ServiceProvider address deliveryPoint is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.address.electronicMailAddress, "joan.maso@uab.es", "ows:ServiceProvider address electronicMailAddress is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.address.postalCode, "08193", "ows:ServiceProvider address postalCode is correct");
+ t.eq(serviceProvider.serviceContact.contactInfo.phone.voice, "+34 93 581 1312", "ows:ServiceProvider phone voice is correct");
+
+ // ows:OperationsMetadata
+ var operationsMetadata = obj.operationsMetadata;
+ t.eq(operationsMetadata.GetCapabilities.dcp.http.get[0].url, "http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?", "ows:OperationsMetadata GetCapabilities url is correct");
+ t.eq(operationsMetadata.GetCapabilities.dcp.http.get[0].constraints.GetEncoding.allowedValues,
+ {'KVP': true},
+ "ows:OperationsMetadata GetCapabilities Constraints Get is correct");
+ t.eq(operationsMetadata.GetFeatureInfo.dcp.http.get[0].url, "http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?", "ows:OperationsMetadata GetFeatureInfo url is correct");
+ t.eq(operationsMetadata.GetFeatureInfo.dcp.http.get[0].constraints,
+ undefined,
+ "ows:OperationsMetadata GetFeatureInfo Constraints Get is correct");
+ t.eq(operationsMetadata.GetTile.dcp.http.get[0].url, "http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?", "ows:OperationsMetadata GetTile url is correct");
+ t.eq(operationsMetadata.GetTile.dcp.http.get[0].constraints,
+ undefined,
+ "ows:OperationsMetadata GetTile Constraints Get is correct");
+ }
+
+ function test_layers(t) {
+ t.plan(43);
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);
+ var contents = obj.contents;
+
+ var numOfLayers = contents.layers.length;
+ t.eq(numOfLayers, 1, "correct count of layers");
+
+ var layer = contents.layers[0];
+ t.eq(layer['abstract'], "Coastline/shorelines (BA010)", "layer abstract is correct");
+ t.eq(layer.identifier, "coastlines", "layer identifier is correct");
+ t.eq(layer.title, "Coastlines", "layer title is correct");
+
+ var numOfFormats = layer.formats.length;
+ t.eq(numOfFormats, 2, "correct count of formats");
+ t.eq(layer.formats[0], "image/png", "format image/png is correct");
+ t.eq(layer.formats[1], "image/gif", "format image/gif is correct");
+
+ var numOfStyles = layer.styles.length;
+ t.eq(numOfStyles, 2, "correct count of styles");
+ t.eq(layer.styles[0].identifier, "DarkBlue", "style 0 identifier is correct");
+ t.eq(layer.styles[0].isDefault, true, "style 0 isDefault is correct");
+ t.eq(layer.styles[0].title, "Dark Blue", "style 0 title is correct");
+ t.eq(layer.styles[0].legend.href, "http://www.miramon.uab.es/wmts/Coastlines/coastlines_darkBlue.png", "style 0 legend href is correct");
+ t.eq(layer.styles[0].legend.format, "image/png", "style 0 legend format is correct");
+ t.eq(layer.styles[1].identifier, "thickAndRed", "style 1 identifier is correct");
+ t.ok(!layer.styles[1].isDefault, "style 1 isDefault is correct");
+ t.eq(layer.styles[1].title, "Thick And Red", "style 1 title is correct");
+ t.eq(layer.styles[1].legend, undefined, "style 1 legend is not set");
+ //t.eq(layer.styles[1].abstract, "Specify this style if you want your maps to have thick red coastlines. ", "style 1 abstract is correct");
+
+ t.eq(layer.tileMatrixSetLinks.length, 1, "correct count of tileMatrixSetLinks");
+ t.eq(layer.tileMatrixSetLinks[0].tileMatrixSet, "BigWorld", "tileMatrixSet is correct");
+
+ var wgs84Bbox = layer.bounds;
+ t.ok(wgs84Bbox instanceof OpenLayers.Bounds, "wgs84BoudingBox instance of OpenLayers.Bounds");
+ t.eq(wgs84Bbox.left, -180.0, "wgs84BoudingBox left is correct");
+ t.eq(wgs84Bbox.right, 180.0, "wgs84BoudingBox right is correct");
+ t.eq(wgs84Bbox.bottom, -90.0, "wgs84BoudingBox bottom is correct");
+ t.eq(wgs84Bbox.top, 90.0, "wgs84BoudingBox top is correct");
+
+ t.eq(layer.resourceUrl.tile.format, "image/png", "resourceUrl.tile.format is correct");
+ t.eq(layer.resourceUrl.tile.template, "http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png",
+ "resourceUrl.tile.template is correct");
+
+ t.eq(layer.resourceUrl.FeatureInfo.format, "application/gml+xml; version=3.1", "resourceUrl.FeatureInfo.format is correct");
+ t.eq(layer.resourceUrl.FeatureInfo.template, "http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml",
+ "resourceUrl.FeatureInfo.template is correct");
+
+ t.eq(layer.resourceUrls[0].format, "image/png", "resourceUrls[0].format is correct");
+ t.eq(layer.resourceUrls[0].resourceType, "tile", "resourceUrls[0].resourceType is correct");
+ t.eq(layer.resourceUrls[0].template, "http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png",
+ "resourceUrls[0].template is correct");
+
+ t.eq(layer.resourceUrls[1].format, "application/gml+xml; version=3.1", "resourceUrls[0].format is correct");
+ t.eq(layer.resourceUrls[1].resourceType, "FeatureInfo", "resourceUrls[0].resourceType is correct");
+ t.eq(layer.resourceUrls[1].template, "http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml",
+ "resourceUrls[0].template is correct");
+
+ var dimensions = layer.dimensions;
+ t.eq(dimensions.length, 1, "correct count of dimensions");
+ t.eq(dimensions[0].title, "Time", "first dimension title is correct");
+ t.eq(dimensions[0]['abstract'], "Monthly datasets", "first dimension abstract is correct");
+ t.eq(dimensions[0].identifier, "TIME", "first dimension identifier is correct");
+ t.eq(dimensions[0]['default'], "default", "first dimension default is correct");
+ t.eq(dimensions[0].values.length, 3, "first dimension has correct count of values");
+ t.eq(dimensions[0].values[0], "2007-05", "first value is correct");
+ t.eq(dimensions[0].values[1], "2007-06", "second value is correct");
+ t.eq(dimensions[0].values[2], "2007-07", "third value is correct");
+ }
+
+ function test_tileMatrixSets(t) {
+ t.plan(19);
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);
+
+ var tileMatrixSets = obj.contents.tileMatrixSets;
+ t.ok(tileMatrixSets['BigWorld'], "tileMatrixSets 'BigWorld' found");
+ var bigWorld = tileMatrixSets['BigWorld'];
+ t.eq(bigWorld.identifier, "BigWorld", "tileMatrixSets identifier is correct");
+ t.eq(bigWorld.matrixIds.length, 2, "tileMatrix count is correct");
+ t.eq(bigWorld.matrixIds[0].identifier, "1e6", "tileMatrix 0 identifier is correct");
+ t.eq(bigWorld.matrixIds[0].matrixHeight, 50000, "tileMatrix 0 matrixHeight is correct");
+ t.eq(bigWorld.matrixIds[0].matrixWidth, 60000, "tileMatrix 0 matrixWidth is correct");
+ t.eq(bigWorld.matrixIds[0].scaleDenominator, 1000000, "tileMatrix 0 scaleDenominator is correct");
+ t.eq(bigWorld.matrixIds[0].tileWidth, 256, "tileMatrix 0 tileWidth is correct");
+ t.eq(bigWorld.matrixIds[0].tileHeight, 256, "tileMatrix 0 tileHeight is correct");
+ t.eq(bigWorld.matrixIds[0].topLeftCorner.lon, -180, "tileMatrix 0 topLeftCorner.lon is correct");
+ t.eq(bigWorld.matrixIds[0].topLeftCorner.lat, 84, "tileMatrix 0 topLeftCorner.lat is correct");
+
+ t.eq(bigWorld.matrixIds[1].identifier, "2.5e6", "tileMatrix 1 identifier is correct");
+ t.eq(bigWorld.matrixIds[1].matrixHeight, 7000, "tileMatrix 1 matrixHeight is correct");
+ t.eq(bigWorld.matrixIds[1].matrixWidth, 9000, "tileMatrix 1 matrixWidth is correct");
+ t.eq(bigWorld.matrixIds[1].scaleDenominator, 2500000, "tileMatrix 1 scaleDenominator is correct");
+ t.eq(bigWorld.matrixIds[1].tileWidth, 256, "tileMatrix 1 tileWidth is correct");
+ t.eq(bigWorld.matrixIds[1].tileHeight, 256, "tileMatrix 1 tileHeight is correct");
+ t.eq(bigWorld.matrixIds[1].topLeftCorner.lon, -180, "tileMatrix 1 topLeftCorner.lon is correct");
+ t.eq(bigWorld.matrixIds[1].topLeftCorner.lat, 84, "tileMatrix 1 topLeftCorner.lat is correct");
+ }
+
+ function test_createLayer(t) {
+ t.plan(43);
+
+ var format = new OpenLayers.Format.WMTSCapabilities();
+
+ var xml = document.getElementById("ogcsample").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+
+ var caps = format.read(doc);
+ var layer;
+
+ var success = true;
+ try {
+ // incomplete config (missing layer)
+ layer = format.createLayer(caps, {
+ });
+ } catch (err) {
+ success = false;
+ }
+ t.ok(!success, "createLayer throws error if provided incomplete layer config");
+
+ // bogus layer identifier
+ try {
+ layer = format.createLayer(caps, {
+ layer: "foo",
+ matrixSet: "BigWorld"
+ });
+ } catch (err) {
+ success = false;
+ }
+ t.ok(!success, "createLayer returns undefined given bad layer identifier");
+
+ // bogus matrixSet identifier
+ try {
+ layer = format.createLayer(caps, {
+ layer: "coastlines",
+ matrixSet: "TheWorld"
+ });
+ } catch (err) {
+ success = false;
+ }
+ t.ok(!success, "createLayer returns undefined given bad matrixSet identifier");
+
+ layer = format.createLayer(caps, {
+ layer: "coastlines",
+ matrixSet: "BigWorld"
+ });
+ t.ok(layer instanceof OpenLayers.Layer.WMTS, "correct instance");
+
+ // autodetect matrixSet
+ layer = format.createLayer(caps, {
+ layer: "coastlines"
+ });
+ t.ok(layer instanceof OpenLayers.Layer.WMTS, "correct instance, with autodetected matrixSet");
+
+ t.eq(layer.matrixIds.length, 2, "correct matrixIds length");
+ t.eq(layer.name, "Coastlines", "correct layer title");
+ t.eq(layer.style, "DarkBlue", "correct style identifier");
+ t.eq(layer.requestEncoding, "KVP", "correct requestEncoding");
+
+ xml = document.getElementById("restsample").firstChild.nodeValue;
+ doc = new OpenLayers.Format.XML().read(xml);
+ caps = format.read(doc);
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781"
+ });
+ t.ok(layer instanceof OpenLayers.Layer.WMTS, "correct instance");
+ t.eq(layer.url[0], "http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png", "correct url");
+ t.eq(layer.url[1], "http://wmts1.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png", "correct url");
+ t.eq(layer.matrixIds.length, 3, "correct matrixIds length");
+ t.eq(layer.requestEncoding, "REST", "correct requestEncoding");
+ t.eq(layer.name, "Agglomérations et villes isolées", "correct layer title");
+ t.eq(layer.style, "ch.are.agglomerationen_isolierte_staedte-2000", "correct style identifier");
+ t.eq(layer.projection.getCode(), "EPSG:21781", "correct projection");
+ t.eq(layer.units, "m", "correct untis");
+ t.ok(layer.serverResolutions === layer.resolutions, "serverResolutions set");
+ t.eq(layer.resolutions.length, 3, "correct resolutions length");
+ t.ok((layer.resolutions[0] - 4000) < 1, "correct first resolution");
+ t.eq(layer.dimensions.length, 1, "correct dimensions length");
+ t.eq(layer.dimensions[0], "Time", "correct dimensions");
+ t.eq(layer.params['TIME'], "20090101", "correct params");
+
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ style: "toto",
+ params: {"Time": "2012"}
+ });
+ t.eq(layer.matrixIds.length, 3, "correct matrixIds length");
+ t.eq(layer.style, "toto", "correct style identifier");
+ t.eq(layer.dimensions.length, 1, "correct dimensions length");
+ t.eq(layer.dimensions[0], "Time", "correct dimensions");
+ t.eq(layer.params['TIME'], "2012", "correct params");
+
+ // test projection and units
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ units: 'degrees'
+ });
+ t.eq(layer.units, "degrees", "correct units");
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ projection: "EPSG:4326"
+ });
+ t.eq(layer.projection.getCode(), "EPSG:4326", "correct projection");
+ t.eq(layer.units, "degrees", "correct units");
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ projection: "EPSG:4326",
+ units: 'm'
+ });
+ t.eq(layer.projection.getCode(), "EPSG:4326", "correct projection");
+ t.eq(layer.units, "m", "correct units");
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ projection: "EPSG:900913",
+ units: 'degrees'
+ });
+ t.eq(layer.projection.getCode(), "EPSG:900913", "correct projection");
+ t.eq(layer.units, "degrees", "correct units");
+
+
+ // test get the right url #608/3
+ xml = document.getElementById("multi-getile-1").firstChild.nodeValue;
+ doc = new OpenLayers.Format.XML().read(xml);
+ caps = format.read(doc);
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ requestEncoding: 'REST'
+ });
+ t.eq(layer.url[0], "http://wmts.geo.admin.ch/rest", "correct rest url 1");
+ t.eq(layer.url[1], "http://wmts1.geo.admin.ch/rest", "correct rest url 1");
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ requestEncoding: 'KVP'
+ });
+ t.eq(layer.url[0], "http://wmts.geo.admin.ch/kvp", "correct kvp url 2");
+ t.eq(layer.url[1], "http://wmts1.geo.admin.ch/kvp", "correct kvp url 2");
+ xml = document.getElementById("multi-getile-2").firstChild.nodeValue;
+ doc = new OpenLayers.Format.XML().read(xml);
+ caps = format.read(doc);
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ requestEncoding: 'REST'
+ });
+ t.eq(layer.url[0], "http://wmts.geo.admin.ch/rest", "correct rest url 2");
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781",
+ requestEncoding: 'KVP'
+ });
+ t.eq(layer.url[0], "http://wmts.geo.admin.ch/kvp", "correct kvp url 2");
+
+ // test RESTfull
+ xml = document.getElementById("arcgis").firstChild.nodeValue;
+ doc = new OpenLayers.Format.XML().read(xml);
+ caps = format.read(doc);
+ layer = format.createLayer(caps, {
+ layer: "WorldTimeZones"
+ });
+ t.eq(layer.requestEncoding, "REST", "correct requestEncoding (in RESTfull)");
+ }
+
+ function test_parse_projection(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.WMTSCapabilities();
+
+ var xml = document.getElementById("restsample-alternate-proj1").firstChild.nodeValue;
+ var doc = new OpenLayers.Format.XML().read(xml);
+ var caps = format.read(doc);
+ var layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781"
+ });
+ t.eq(layer.projection.getCode(), "EPSG:21781", "correct projection");
+
+ xml = document.getElementById("restsample-alternate-proj2").firstChild.nodeValue;
+ doc = new OpenLayers.Format.XML().read(xml);
+ caps = format.read(doc);
+ layer = format.createLayer(caps, {
+ layer: "ch.are.agglomerationen_isolierte_staedte-2000",
+ matrixSet: "21781"
+ });
+ t.eq(layer.projection.getCode(), "EPSG:21781", "correct projection");
+ }
+ </script>
+</head>
+<body>
+
+<!--
+OGC example below taken from
+http://schemas.opengis.net/wmts/1.0/examples/wmtsGetCapabilities_response.xml
+-->
+<div id="ogcsample"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:ServiceIdentification>
+ <ows:Title>Web Map Tile Service</ows:Title>
+ <ows:Abstract>Service that contrains the map access interface to some TileMatrixSets</ows:Abstract>
+ <ows:Keywords>
+ <ows:Keyword>tile</ows:Keyword>
+ <ows:Keyword>tile matrix set</ows:Keyword>
+ <ows:Keyword>map</ows:Keyword>
+ </ows:Keywords>
+ <ows:ServiceType>OGC WMTS</ows:ServiceType>
+ <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
+ <ows:Fees>none</ows:Fees>
+ <ows:AccessConstraints>none</ows:AccessConstraints>
+ </ows:ServiceIdentification>
+ <ows:ServiceProvider>
+ <ows:ProviderName>MiraMon</ows:ProviderName>
+ <ows:ProviderSite xlink:href="http://www.creaf.uab.es/miramon"/>
+ <ows:ServiceContact>
+ <ows:IndividualName>Joan Maso Pau</ows:IndividualName>
+ <ows:PositionName>Senior Software Engineer</ows:PositionName>
+ <ows:ContactInfo>
+ <ows:Phone>
+ <ows:Voice>+34 93 581 1312</ows:Voice>
+ <ows:Facsimile>+34 93 581 4151</ows:Facsimile>
+ </ows:Phone>
+ <ows:Address>
+ <ows:DeliveryPoint>Fac Ciencies UAB</ows:DeliveryPoint>
+ <ows:City>Bellaterra</ows:City>
+ <ows:AdministrativeArea>Barcelona</ows:AdministrativeArea>
+ <ows:PostalCode>08193</ows:PostalCode>
+ <ows:Country>Spain</ows:Country>
+ <ows:ElectronicMailAddress>joan.maso@uab.es</ows:ElectronicMailAddress>
+ </ows:Address>
+ </ows:ContactInfo>
+ </ows:ServiceContact>
+ </ows:ServiceProvider>
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetCapabilities">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>KVP</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?"/>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetFeatureInfo">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?"/>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>Coastlines</ows:Title>
+ <ows:Abstract>Coastline/shorelines (BA010)</ows:Abstract>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>-180 -90</ows:LowerCorner>
+ <ows:UpperCorner>180 90</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <ows:Identifier>coastlines</ows:Identifier>
+ <ResourceURL format="image/png" resourceType="tile"
+ template="http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png" />
+ <ResourceURL format="application/gml+xml; version=3.1" resourceType="FeatureInfo"
+ template="http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml" />
+ <Style isDefault="true">
+ <ows:Title>Dark Blue</ows:Title>
+ <ows:Identifier>DarkBlue</ows:Identifier>
+ <LegendURL format="image/png" xlink:href="http://www.miramon.uab.es/wmts/Coastlines/coastlines_darkBlue.png"/>
+ </Style>
+ <Style>
+ <ows:Title>Thick And Red</ows:Title>
+ <ows:Abstract>Specify this style if you want your maps to have thick red coastlines.
+ </ows:Abstract>
+ <ows:Identifier>thickAndRed</ows:Identifier>
+ </Style>
+ <Format>image/png</Format>
+ <Format>image/gif</Format>
+ <Dimension>
+ <ows:Title>Time</ows:Title>
+ <ows:Abstract>Monthly datasets</ows:Abstract>
+ <ows:Identifier>TIME</ows:Identifier>
+ <Value>2007-05</Value>
+ <Value>2007-06</Value>
+ <Value>2007-07</Value>
+ <Default>default</Default>
+ </Dimension>
+ <TileMatrixSetLink>
+ <TileMatrixSet>BigWorld</TileMatrixSet>
+ </TileMatrixSetLink>
+ </Layer>
+ <TileMatrixSet>
+ <ows:Identifier>BigWorld</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>
+ <TileMatrix>
+ <ows:Identifier>1e6</ows:Identifier>
+ <ScaleDenominator>1e6</ScaleDenominator>
+ <TopLeftCorner>-180 84</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>60000</MatrixWidth>
+ <MatrixHeight>50000</MatrixHeight>
+ </TileMatrix>
+ <TileMatrix>
+ <ows:Identifier>2.5e6</ows:Identifier>
+ <ScaleDenominator>2.5e6</ScaleDenominator>
+ <TopLeftCorner>-180 84</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>9000</MatrixWidth>
+ <MatrixHeight>7000</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <Themes>
+ <Theme>
+ <ows:Title>Foundation</ows:Title>
+ <ows:Abstract>"Digital Chart Of The World" data</ows:Abstract>
+ <ows:Identifier>Foundation</ows:Identifier>
+ <Theme>
+ <ows:Title>Boundaries</ows:Title>
+ <ows:Identifier>Boundaries</ows:Identifier>
+ <LayerRef>coastlines</LayerRef>
+ <LayerRef>politicalBoundaries</LayerRef>
+ <LayerRef>depthContours</LayerRef>
+ </Theme>
+ <Theme>
+ <ows:Title>Transportation</ows:Title>
+ <ows:Identifier>Transportation</ows:Identifier>
+ <LayerRef>roads</LayerRef>
+ <LayerRef>railroads</LayerRef>
+ <LayerRef>airports</LayerRef>
+ </Theme>
+ </Theme>
+ <Theme>
+ <ows:Title>World Geology</ows:Title>
+ <ows:Identifier>World Geology</ows:Identifier>
+ <LayerRef>worldAgeRockType</LayerRef>
+ <LayerRef>worldFaultLines</LayerRef>
+ <LayerRef>felsicMagmatic</LayerRef>
+ <LayerRef>maficMagmatic</LayerRef>
+ </Theme>
+ </Themes>
+</Capabilities>
+--></div>
+
+<div id="restsample"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:ServiceIdentification>
+ <ows:Title>Federal Geodata Infrastructure of Switzerland</ows:Title>
+ <ows:Abstract>Some Geodata are subject to license and fees</ows:Abstract>
+ <ows:Keywords>
+ <ows:Keyword>FGDI</ows:Keyword>
+ <ows:Keyword>Pixelkarte</ows:Keyword>
+ <ows:Keyword>Switzerland</ows:Keyword>
+ </ows:Keywords>
+ <ows:ServiceType>OGC WMTS</ows:ServiceType>
+ <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
+ <ows:Fees>yes</ows:Fees>
+ <ows:AccessConstraints>license</ows:AccessConstraints>
+ </ows:ServiceIdentification>
+ <ows:ServiceProvider>
+ <ows:ProviderName>swisstopo</ows:ProviderName>
+ <ows:ProviderSite xlink:href="http://www.swisstopo.admin.ch"/>
+ <ows:ServiceContact>
+ <ows:IndividualName>David Oesch</ows:IndividualName>
+ <ows:PositionName></ows:PositionName>
+ <ows:ContactInfo>
+ <ows:Phone>
+ <ows:Voice>+41 (0)31 / 963 21 11</ows:Voice>
+ <ows:Facsimile>+41 (0)31 / 963 24 59</ows:Facsimile>
+ </ows:Phone>
+ <ows:Address>
+ <ows:DeliveryPoint>swisstopo</ows:DeliveryPoint>
+ <ows:City>Bern</ows:City>
+ <ows:AdministrativeArea>BE</ows:AdministrativeArea>
+ <ows:PostalCode>3084</ows:PostalCode>
+ <ows:Country>Switzerland</ows:Country>
+ <ows:ElectronicMailAddress/>
+ </ows:Address>
+ </ows:ContactInfo>
+ </ows:ServiceContact>
+ </ows:ServiceProvider>
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetCapabilities">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
+ <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
+ <Style>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
+ </Style>
+ <Format>image/png</Format>
+ <Dimension>
+ <ows:Identifier>Time</ows:Identifier>
+ <Default>20090101</Default>
+ <Value>20090101</Value>
+ </Dimension>
+ <TileMatrixSetLink>
+ <TileMatrixSet>21781</TileMatrixSet>
+ </TileMatrixSetLink>
+ <ResourceURL format="image/png" resourceType="tile" template="http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
+ <ResourceURL format="image/png" resourceType="tile" template="http://wmts1.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
+ </Layer>
+ <TileMatrixSet>
+ <ows:Identifier>21781</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:EPSG::21781</ows:SupportedCRS>
+ <TileMatrix>
+ <ows:Identifier>0</ows:Identifier>
+ <ScaleDenominator>14285750.5715</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>1</MatrixWidth>
+ <MatrixHeight>1</MatrixHeight>
+ </TileMatrix>
+ <TileMatrix>
+ <ows:Identifier>8</ows:Identifier>
+ <ScaleDenominator>7142875.28575</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>1</MatrixWidth>
+ <MatrixHeight>1</MatrixHeight>
+ </TileMatrix>
+ <TileMatrix>
+ <ows:Identifier>12</ows:Identifier>
+ <ScaleDenominator>3571437.64288</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>2</MatrixWidth>
+ <MatrixHeight>2</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
+</Capabilities>
+--></div>
+
+<div id="restsample-alternate-proj1"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetCapabilities">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
+ <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
+ <Style>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
+ </Style>
+ <Format>image/png</Format>
+ <Dimension>
+ <ows:Identifier>Time</ows:Identifier>
+ <Default>20090101</Default>
+ <Value>20090101</Value>
+ </Dimension>
+ <TileMatrixSetLink>
+ <TileMatrixSet>21781</TileMatrixSet>
+ </TileMatrixSetLink>
+ <ResourceURL format="image/png" resourceType="tile" template="http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
+ </Layer>
+ <TileMatrixSet>
+ <ows:Identifier>21781</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:EPSG:21781</ows:SupportedCRS>
+ <TileMatrix>
+ <ows:Identifier>0</ows:Identifier>
+ <ScaleDenominator>14285750.5715</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>1</MatrixWidth>
+ <MatrixHeight>1</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
+</Capabilities>
+--></div>
+
+<div id="restsample-alternate-proj2"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetCapabilities">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
+ <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
+ <Style>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
+ </Style>
+ <Format>image/png</Format>
+ <Dimension>
+ <ows:Identifier>Time</ows:Identifier>
+ <Default>20090101</Default>
+ <Value>20090101</Value>
+ </Dimension>
+ <TileMatrixSetLink>
+ <TileMatrixSet>21781</TileMatrixSet>
+ </TileMatrixSetLink>
+ <ResourceURL format="image/png" resourceType="tile" template="http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"/>
+ </Layer>
+ <TileMatrixSet>
+ <ows:Identifier>21781</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>
+ <TileMatrix>
+ <ows:Identifier>0</ows:Identifier>
+ <ScaleDenominator>14285750.5715</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>1</MatrixWidth>
+ <MatrixHeight>1</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
+</Capabilities>
+--></div>
+
+<div id="multi-getile-1"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetCapabilities">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/rest">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ <ows:Get xlink:href="http://wmts1.geo.admin.ch/rest">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/kvp">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>KVP</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ <ows:Get xlink:href="http://wmts1.geo.admin.ch/kvp">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>KVP</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
+ <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
+ <Style>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
+ </Style>
+ <Format>image/png</Format>
+ <Dimension>
+ <ows:Identifier>Time</ows:Identifier>
+ <Default>20090101</Default>
+ <Value>20090101</Value>
+ </Dimension>
+ <TileMatrixSetLink>
+ <TileMatrixSet>21781</TileMatrixSet>
+ </TileMatrixSetLink>
+ </Layer>
+ <TileMatrixSet>
+ <ows:Identifier>21781</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>
+ <TileMatrix>
+ <ows:Identifier>0</ows:Identifier>
+ <ScaleDenominator>14285750.5715</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>1</MatrixWidth>
+ <MatrixHeight>1</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
+</Capabilities>
+--></div>
+<div id="arcgis"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:ServiceIdentification>
+ <ows:Title>WorldTimeZones</ows:Title>
+ <ows:ServiceType>OGC WMTS</ows:ServiceType>
+ <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
+ </ows:ServiceIdentification>
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS/tile/1.0.0/">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>RESTful</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ <ows:Get xlink:href="http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS?">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>KVP</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>WorldTimeZones</ows:Title>
+ <ows:Identifier>WorldTimeZones</ows:Identifier>
+ <ows:BoundingBox crs="urn:ogc:def:crs:EPSG::102100">
+ <ows:LowerCorner>-2.0037507067161843E7 -3.024097195838617E7</ows:LowerCorner>
+ <ows:UpperCorner>2.0037507067161843E7 3.0240971458386205E7</ows:UpperCorner>
+ </ows:BoundingBox>
+ <ows:WGS84BoundingBox crs="urn:ogc:def:crs:OGC:2:84">
+ <ows:LowerCorner>-179.99999550841463 -88.99999992161119</ows:LowerCorner>
+ <ows:UpperCorner>179.99999550841463 88.99999992161118</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <Style isDefault="true">
+ <ows:Title>Default Style</ows:Title>
+ <ows:Identifier>default</ows:Identifier>
+ </Style>
+ <Format>image/png</Format>
+ <TileMatrixSetLink>
+ <TileMatrixSet>GoogleMapsCompatible</TileMatrixSet>
+ </TileMatrixSetLink>
+ <ResourceURL format="image/png" resourceType="tile" template="http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS/tile/1.0.0/WorldTimeZones/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png" />
+ </Layer>
+ <TileMatrixSet>
+ <ows:Title>GoogleMapsCompatible</ows:Title>
+ <ows:Abstract>the wellknown 'GoogleMapsCompatible' tile matrix set defined by OGC WMTS specification</ows:Abstract>
+ <ows:Identifier>GoogleMapsCompatible</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:EPSG:6.18:3:3857</ows:SupportedCRS>
+ <WellKnownScaleSet>urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible</WellKnownScaleSet>
+ <TileMatrix>
+ <ows:Identifier>5</ows:Identifier>
+ <ScaleDenominator>17471320.75089743</ScaleDenominator>
+ <TopLeftCorner>-20037508.34278925 20037508.34278925</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>32</MatrixWidth>
+ <MatrixHeight>32</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <ServiceMetadataURL xlink:href="http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS/1.0.0/WMTSCapabilities.xml" />
+</Capabilities>
+--></div>
+
+<div id="multi-getile-2"><!--
+<?xml version="1.0" encoding="UTF-8"?>
+<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
+ <ows:OperationsMetadata>
+ <ows:Operation name="GetCapabilities">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ <ows:Operation name="GetTile">
+ <ows:DCP>
+ <ows:HTTP>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/kvp">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>KVP</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ <ows:Get xlink:href="http://wmts.geo.admin.ch/rest">
+ <ows:Constraint name="GetEncoding">
+ <ows:AllowedValues>
+ <ows:Value>REST</ows:Value>
+ </ows:AllowedValues>
+ </ows:Constraint>
+ </ows:Get>
+ </ows:HTTP>
+ </ows:DCP>
+ </ows:Operation>
+ </ows:OperationsMetadata>
+ <Contents>
+ <Layer>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>
+ <ows:WGS84BoundingBox>
+ <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>
+ <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>
+ </ows:WGS84BoundingBox>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <ows:Metadata xlink:href="http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm"/>
+ <Style>
+ <ows:Title>Agglomérations et villes isolées</ows:Title>
+ <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>
+ <LegendURL format="image/png" xlink:href="http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png" />
+ </Style>
+ <Format>image/png</Format>
+ <Dimension>
+ <ows:Identifier>Time</ows:Identifier>
+ <Default>20090101</Default>
+ <Value>20090101</Value>
+ </Dimension>
+ <TileMatrixSetLink>
+ <TileMatrixSet>21781</TileMatrixSet>
+ </TileMatrixSetLink>
+ </Layer>
+ <TileMatrixSet>
+ <ows:Identifier>21781</ows:Identifier>
+ <ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>
+ <TileMatrix>
+ <ows:Identifier>0</ows:Identifier>
+ <ScaleDenominator>14285750.5715</ScaleDenominator>
+ <TopLeftCorner>420000.0 350000.0</TopLeftCorner>
+ <TileWidth>256</TileWidth>
+ <TileHeight>256</TileHeight>
+ <MatrixWidth>1</MatrixWidth>
+ <MatrixHeight>1</MatrixHeight>
+ </TileMatrix>
+ </TileMatrixSet>
+ </Contents>
+ <ServiceMetadataURL xlink:href="http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml"/>
+</Capabilities>
+--></div>
+
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.html b/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.html
new file mode 100644
index 0000000..191f29f
--- /dev/null
+++ b/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.html
@@ -0,0 +1,30 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script src="v1_0_0.js"></script>
+ <script type="text/javascript">
+
+ function test_read(t) {
+
+ t.plan(7);
+
+ var format = new OpenLayers.Format.WPSCapabilities();
+ var obj = format.read(doc);
+
+ t.eq(obj.version, "1.0.0", "Version parsed correctly");
+
+ t.eq(obj.languages.length, 2, "2 language entries parsed");
+ t.eq(obj.languages[0].isDefault, true, "First language is the default language");
+ t.eq(obj.languages[0].language, "en-US", "First language is US English");
+
+ var buffer = obj.processOfferings["JTS:buffer"];
+ t.eq(buffer.processVersion, "1.0.0", "processVersion for buffer is 1.0.0");
+ t.eq(buffer.abstract, "Buffers a geometry using a certain distance", "Buffer abstract correctly read");
+ t.eq(buffer.title, "Buffers a geometry using a certain distance", "Buffer title correctly read");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.js b/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.js
new file mode 100644
index 0000000..19d12f2
--- /dev/null
+++ b/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.js
@@ -0,0 +1,112 @@
+var doc = new OpenLayers.Format.XML().read(
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<wps:Capabilities xml:lang="en" service="WPS" version="1.0.0"' +
+' xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"' +
+' xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">' +
+' <ows:ServiceIdentification>' +
+' <ows:Title>Prototype GeoServer WPS</ows:Title>' +
+' <ows:Abstract/>' +
+' <ows:ServiceType>WPS</ows:ServiceType>' +
+' <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>' +
+' </ows:ServiceIdentification>' +
+' <ows:ServiceProvider>' +
+' <ows:ProviderName>The ancient geographes INC</ows:ProviderName>' +
+' <ows:ProviderSite xlink:href="http://geoserver.org"/>' +
+' <ows:ServiceContact/>' +
+' </ows:ServiceProvider>' +
+' <ows:OperationsMetadata>' +
+' <ows:Operation name="GetCapabilities">' +
+' <ows:DCP>' +
+' <ows:HTTP>' +
+' <ows:Get xlink:href="http://localhost:8080/geoserver/wps"/>' +
+' <ows:Post xlink:href="http://localhost:8080/geoserver/wps"/>' +
+' </ows:HTTP>' +
+' </ows:DCP>' +
+' </ows:Operation>' +
+' <ows:Operation name="DescribeProcess">' +
+' <ows:DCP>' +
+' <ows:HTTP>' +
+' <ows:Get xlink:href="http://localhost:8080/geoserver/wps"/>' +
+' <ows:Post xlink:href="http://localhost:8080/geoserver/wps"/>' +
+' </ows:HTTP>' +
+' </ows:DCP>' +
+' </ows:Operation>' +
+' <ows:Operation name="Execute">' +
+' <ows:DCP>' +
+' <ows:HTTP>' +
+' <ows:Get xlink:href="http://localhost:8080/geoserver/wps"/>' +
+' <ows:Post xlink:href="http://localhost:8080/geoserver/wps"/>' +
+' </ows:HTTP>' +
+' </ows:DCP>' +
+' </ows:Operation>' +
+' </ows:OperationsMetadata>' +
+' <wps:ProcessOfferings>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>gt:Intersect</ows:Identifier>' +
+' <ows:Title>Intersection</ows:Title>' +
+' <ows:Abstract>Intersection between two literal geometry</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:length</ows:Identifier>' +
+' <ows:Title>Returns the geometry perimeters, computed using cartesian geometry' +
+' expressions in the same unit of measure as the geometry (will not return a valid' +
+' perimeter for geometries expressed geographic coordinates</ows:Title>' +
+' <ows:Abstract>Returns the geometry perimeters, computed using cartesian geometry' +
+' expressions in the same unit of measure as the geometry (will not return a valid' +
+' perimeter for geometries expressed geographic coordinates</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:isEmpty</ows:Identifier>' +
+' <ows:Title>Checks if the provided geometry is empty</ows:Title>' +
+' <ows:Abstract>Checks if the provided geometry is empty</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:contains</ows:Identifier>' +
+' <ows:Title>Checks if a contains b</ows:Title>' +
+' <ows:Abstract>Checks if a contains b</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:disjoint</ows:Identifier>' +
+' <ows:Title>Returns true if the two geometries have no points in common</ows:Title>' +
+' <ows:Abstract>Returns true if the two geometries have no points in common</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:intersects</ows:Identifier>' +
+' <ows:Title>Returns true if the two geometries intersect, false otherwise</ows:Title>' +
+' <ows:Abstract>Returns true if the two geometries intersect, false' +
+' otherwise</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:isClosed</ows:Identifier>' +
+' <ows:Title>Returns true if the line is closed</ows:Title>' +
+' <ows:Abstract>Returns true if the line is closed</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:isValid</ows:Identifier>' +
+' <ows:Title>Returns true if the geometry is topologically valid, false' +
+' otherwise</ows:Title>' +
+' <ows:Abstract>Returns true if the geometry is topologically valid, false' +
+' otherwise</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:buffer</ows:Identifier>' +
+' <ows:Title>Buffers a geometry using a certain distance</ows:Title>' +
+' <ows:Abstract>Buffers a geometry using a certain distance</ows:Abstract>' +
+' </wps:Process>' +
+' <wps:Process wps:processVersion="1.0.0">' +
+' <ows:Identifier>JTS:getY</ows:Identifier>' +
+' <ows:Title>Returns the Y ordinate of the point</ows:Title>' +
+' <ows:Abstract>Returns the Y ordinate of the point</ows:Abstract>' +
+' </wps:Process>' +
+' </wps:ProcessOfferings>' +
+' <wps:Languages>' +
+' <wps:Default>' +
+' <ows:Language>en-US</ows:Language>' +
+' </wps:Default>' +
+' <wps:Supported>' +
+' <ows:Language>en-US</ows:Language>' +
+' </wps:Supported>' +
+' </wps:Languages>' +
+'</wps:Capabilities>'
+);
diff --git a/misc/openlayers/tests/Format/WPSDescribeProcess.html b/misc/openlayers/tests/Format/WPSDescribeProcess.html
new file mode 100644
index 0000000..f52fd21
--- /dev/null
+++ b/misc/openlayers/tests/Format/WPSDescribeProcess.html
@@ -0,0 +1,206 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_read_WPSDescribeProcess(t) {
+ t.plan(17);
+
+ var parser = new OpenLayers.Format.WPSDescribeProcess();
+ var text =
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<wps:ProcessDescriptions xml:lang="en" service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+' xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"' +
+' xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink">' +
+' <ProcessDescription wps:processVersion="1.0.0" statusSupported="false"' +
+' storeSupported="false">' +
+' <ows:Identifier>JTS:buffer</ows:Identifier>' +
+' <ows:Title>Buffers a geometry using a certain distance</ows:Title>' +
+' <ows:Abstract>Buffers a geometry using a certain distance</ows:Abstract>' +
+' <DataInputs>' +
+' <Input maxOccurs="1" minOccurs="1">' +
+' <ows:Identifier>geom</ows:Identifier>' +
+' <ows:Title>geom</ows:Title>' +
+' <ows:Abstract>The geometry to be buffered</ows:Abstract>' +
+' <ComplexData>' +
+' <Default>' +
+' <Format>' +
+' <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +
+' </Format>' +
+' </Default>' +
+' <Supported>' +
+' <Format>' +
+' <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>text/xml; subtype=gml/2.1.2</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/wkt</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/gml-3.1.1</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/gml-2.1.2</MimeType>' +
+' </Format>' +
+' </Supported>' +
+' </ComplexData>' +
+' </Input>' +
+' <Input maxOccurs="1" minOccurs="1">' +
+' <ows:Identifier>distance</ows:Identifier>' +
+' <ows:Title>distance</ows:Title>' +
+' <ows:Abstract>The distance (same unit of measure as the geometry)</ows:Abstract>' +
+' <LiteralData>' +
+' <ows:DataType>xs:double</ows:DataType>' +
+' <ows:AnyValue/>' +
+' </LiteralData>' +
+' </Input>' +
+' <Input maxOccurs="1" minOccurs="0">' +
+' <ows:Identifier>quadrantSegments</ows:Identifier>' +
+' <ows:Title>quadrantSegments</ows:Title>' +
+' <ows:Abstract>Number of quadrant segments. Use &gt; 0 for round joins, 0 for' +
+' flat joins, &lt; 0 for mitred joins</ows:Abstract>' +
+' <LiteralData>' +
+' <ows:DataType>xs:int</ows:DataType>' +
+' <ows:AnyValue/>' +
+' </LiteralData>' +
+' </Input>' +
+' <Input maxOccurs="1" minOccurs="0">' +
+' <ows:Identifier>capStyle</ows:Identifier>' +
+' <ows:Title>capStyle</ows:Title>' +
+' <ows:Abstract>The buffer cap style, round, flat, square</ows:Abstract>' +
+' <LiteralData>' +
+' <ows:AllowedValues>' +
+' <ows:Value>Round</ows:Value>' +
+' <ows:Value>Flat</ows:Value>' +
+' <ows:Value>Square</ows:Value>' +
+' </ows:AllowedValues>' +
+' </LiteralData>' +
+' </Input>' +
+' </DataInputs>' +
+' <ProcessOutputs>' +
+' <Output>' +
+' <ows:Identifier>result</ows:Identifier>' +
+' <ows:Title>result</ows:Title>' +
+' <ComplexOutput>' +
+' <Default>' +
+' <Format>' +
+' <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +
+' </Format>' +
+' </Default>' +
+' <Supported>' +
+' <Format>' +
+' <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>text/xml; subtype=gml/2.1.2</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/wkt</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/gml-3.1.1</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/gml-2.1.2</MimeType>' +
+' </Format>' +
+' </Supported>' +
+' </ComplexOutput>' +
+' </Output>' +
+' <Output>' +
+' <ows:Identifier>literal</ows:Identifier>' +
+' <ows:Title>literal output</ows:Title>' +
+' <LiteralOutput>' +
+' <ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#integer">integer</ows:DataType>'+
+' </LiteralOutput>' +
+' </Output>' +
+' </ProcessOutputs>' +
+' </ProcessDescription>' +
+'</wps:ProcessDescriptions>';
+
+ var res = parser.read(text);
+ var buffer = res.processDescriptions["JTS:buffer"];
+ t.eq(buffer.statusSupported, false, "statusSupported read correctly");
+ t.eq(buffer.storeSupported, false, "storeSupported read correctly");
+ t.eq(buffer.processVersion, "1.0.0", "processVersion read correctly");
+ var capStyle = buffer.dataInputs[3];
+ t.eq(capStyle.abstract, "The buffer cap style, round, flat, square", "capStyle abstract read correctly");
+ t.eq(capStyle.minOccurs, 0, "capStyle minOccurs read correctly");
+ t.eq(capStyle.maxOccurs, 1, "maxOccurs read correctly");
+ t.eq(capStyle.literalData.allowedValues["Flat"], true, "capStyle allowedValues read correctly");
+ var distance = buffer.dataInputs[1];
+ t.eq(distance.literalData.anyValue, true, "distance anyValue read correctly");
+ t.eq(distance.literalData.dataType, "xs:double", "distance dataType read correctly");
+ var geom = buffer.dataInputs[0];
+ t.eq(geom.complexData["default"].formats["text/xml; subtype=gml/3.1.1"], true, "geom complexData default read correctly");
+ t.eq(geom.complexData["supported"].formats["application/gml-2.1.2"], true, "geom complexData supported read correctly [1/2]");
+ t.eq(geom.complexData["supported"].formats["application/gml-3.1.1"], true, "geom complexData supported read correctly [2/2]");
+ var result = buffer.processOutputs[0];
+ t.eq(result.complexOutput["default"].formats["text/xml; subtype=gml/3.1.1"], true, "processOutputs default format read correctly");
+ t.eq(result.complexOutput["supported"].formats["text/xml; subtype=gml/3.1.1"], true, "processOutputs supported format read correctly [1/2]");
+ t.eq(result.complexOutput["supported"].formats["application/wkt"], true, "processOutputs supported format read correctly [1/2]");
+
+ var literalresult = buffer.processOutputs[1];
+ t.eq(literalresult.literalOutput.dataType, "integer", "processOutputs supported data type read corectly");
+
+ text = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<wps:ProcessDescriptions service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0"' +
+' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en"' +
+' xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"' +
+' xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink">' +
+' <ProcessDescription wps:processVersion="1.0.0" statusSupported="false"' +
+' storeSupported="false">' +
+' <ows:Identifier>gt:VectorToRaster</ows:Identifier>' +
+' <ows:Title>Rasterize features</ows:Title>' +
+' <ows:Abstract>Rasterize all or selected features in a FeatureCollection</ows:Abstract>' +
+' <DataInputs>' +
+' <Input maxOccurs="1" minOccurs="0">' +
+' <ows:Identifier>bounds</ows:Identifier>' +
+' <ows:Title>Bounds</ows:Title>' +
+' <ows:Abstract>Bounds of the area to rasterize</ows:Abstract>' +
+' <BoundingBoxData>' +
+' <Default>' +
+' <CRS>EPSG:4326</CRS>' +
+' </Default>' +
+' <Supported>' +
+' <CRS>EPSG:4326</CRS>' +
+' </Supported>' +
+' </BoundingBoxData>' +
+' </Input>' +
+' </DataInputs>' +
+' <ProcessOutputs>' +
+' <Output>' +
+' <ows:Identifier>result</ows:Identifier>' +
+' <ows:Title>Result</ows:Title>' +
+' <ComplexOutput>' +
+' <Default>' +
+' <Format>' +
+' <MimeType>image/tiff</MimeType>' +
+' </Format>' +
+' </Default>' +
+' <Supported>' +
+' <Format>' +
+' <MimeType>image/tiff</MimeType>' +
+' </Format>' +
+' <Format>' +
+' <MimeType>application/arcgrid</MimeType>' +
+' </Format>' +
+' </Supported>' +
+' </ComplexOutput>' +
+' </Output>' +
+' </ProcessOutputs>' +
+' </ProcessDescription>' +
+'</wps:ProcessDescriptions>';
+
+ res = parser.read(text);
+ var vector2Raster = res.processDescriptions["gt:VectorToRaster"];
+ t.eq(vector2Raster.dataInputs[0].boundingBoxData["default"].CRSs["EPSG:4326"], true, "BoundingBoxData CRS parsed correctly");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/WPSExecute.html b/misc/openlayers/tests/Format/WPSExecute.html
new file mode 100644
index 0000000..e820800
--- /dev/null
+++ b/misc/openlayers/tests/Format/WPSExecute.html
@@ -0,0 +1,549 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_write_WPSExecute_WCS(t) {
+ t.plan(1);
+ var expected = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">' +
+' <ows:Identifier>gs:GeorectifyCoverage</ows:Identifier>' +
+' <wps:DataInputs>' +
+' <wps:Input>' +
+' <ows:Identifier>data</ows:Identifier>' +
+' <wps:Reference mimeType="image/tiff" xlink:href="http://geoserver/wcs" method="POST">' +
+' <wps:Body>' +
+' <wcs:GetCoverage service="WCS" version="1.1.2">' +
+' <ows:Identifier>topp:asbuilt</ows:Identifier>' +
+' <wcs:DomainSubset>' +
+' <ows:BoundingBox crs="http://www.opengis.net/gml/srs/epsg.xml#404000">' +
+' <ows:LowerCorner>0 -7070</ows:LowerCorner>' +
+' <ows:UpperCorner>10647 1</ows:UpperCorner>' +
+' </ows:BoundingBox>' +
+' </wcs:DomainSubset>' +
+' <wcs:Output format="image/tiff"/>' +
+' </wcs:GetCoverage>' +
+' </wps:Body>' +
+' </wps:Reference>' +
+' </wps:Input>' +
+' <wps:Input>' +
+' <ows:Identifier>gcp</ows:Identifier>' +
+' <wps:Data>' +
+' <wps:LiteralData>[[[2721, 3263], [-122.472109, 37.73106003]], [[4163, 3285], [-122.4693417, 37.729929851]], [[5773, 4046], [-122.466702461, 37.7271906]], [[8885, 4187], [-122.462333, 37.725167]]]</wps:LiteralData>' +
+' </wps:Data>' +
+' </wps:Input>' +
+' <wps:Input>' +
+' <ows:Identifier>targetCRS</ows:Identifier>' +
+' <wps:Data>' +
+' <wps:LiteralData>EPSG:4326</wps:LiteralData>' +
+' </wps:Data>' +
+' </wps:Input>' +
+' <wps:Input>' +
+' <ows:Identifier>transparent</ows:Identifier>' +
+' <wps:Data>' +
+' <wps:LiteralData>true</wps:LiteralData>' +
+' </wps:Data>' +
+' </wps:Input>' +
+' </wps:DataInputs>' +
+' <wps:ResponseForm>' +
+' <wps:RawDataOutput mimeType="image/tiff">' +
+' <ows:Identifier>result</ows:Identifier>' +
+' </wps:RawDataOutput>' +
+' </wps:ResponseForm>' +
+'</wps:Execute>';
+
+ var format = new OpenLayers.Format.WPSExecute();
+ var result = format.write({
+ identifier: "gs:GeorectifyCoverage",
+ dataInputs: [{
+ identifier: 'data',
+ reference: {
+ mimeType: "image/tiff",
+ href: "http://geoserver/wcs",
+ method: "POST",
+ body: {
+ wcs: {
+ identifier: 'topp:asbuilt',
+ version: '1.1.2',
+ domainSubset: {
+ boundingBox: {
+ projection: 'http://www.opengis.net/gml/srs/epsg.xml#404000',
+ bounds: new OpenLayers.Bounds(0.0, -7070.0, 10647.0, 1.0)
+ }
+ },
+ output: {format: 'image/tiff'}
+ }
+ }
+ }
+ }, {
+ identifier: 'gcp',
+ data: {
+ literalData: {
+ value: '[[[2721, 3263], [-122.472109, 37.73106003]], [[4163, 3285], [-122.4693417, 37.729929851]], [[5773, 4046], [-122.466702461, 37.7271906]], [[8885, 4187], [-122.462333, 37.725167]]]'
+ }
+ }
+ }, {
+ identifier: 'targetCRS',
+ data: {
+ literalData: {
+ value: 'EPSG:4326'
+ }
+ }
+ }, {
+ identifier: 'transparent',
+ data: {
+ literalData: {
+ value: 'true'
+ }
+ }
+ }],
+ responseForm: {
+ rawDataOutput: {
+ mimeType: "image/tiff",
+ identifier: "result"
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WPS Execute with embedded WCS GetCoverage written out correctly");
+
+ }
+
+ function test_write_WPSExecute(t) {
+ t.plan(1);
+ var expected = '<?xml version="1.0" encoding="UTF-8"?>' +
+'<wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
+' xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs"' +
+' xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1"' +
+' xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc"' +
+' xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink"' +
+' xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">' +
+' <ows:Identifier>JTS:area</ows:Identifier>' +
+' <wps:DataInputs>' +
+' <wps:Input>' +
+' <ows:Identifier>geom</ows:Identifier>' +
+' <wps:Reference mimeType="text/xml; subtype=gml/3.1.1" xlink:href="http://geoserver/wps"' +
+' method="POST">' +
+' <wps:Body>' +
+' <wps:Execute service="WPS" version="1.0.0">' +
+' <ows:Identifier>gs:CollectGeometries</ows:Identifier>' +
+' <wps:DataInputs>' +
+' <wps:Input>' +
+' <ows:Identifier>features</ows:Identifier>' +
+' <wps:Reference mimeType="text/xml; subtype=wfs-collection/1.0"' +
+' xlink:href="http://geoserver/wfs" method="POST">' +
+' <wps:Body>' +
+' <wfs:GetFeature service="WFS" version="1.0.0"' +
+' outputFormat="GML2">' +
+' <wfs:Query typeName="sf:archsites"/>' +
+' </wfs:GetFeature>' +
+' </wps:Body>' +
+' </wps:Reference>' +
+' </wps:Input>' +
+' </wps:DataInputs>' +
+' <wps:ResponseForm>' +
+' <wps:RawDataOutput mimeType="text/xml; subtype=gml/3.1.1">' +
+' <ows:Identifier>result</ows:Identifier>' +
+' </wps:RawDataOutput>' +
+' </wps:ResponseForm>' +
+' </wps:Execute>' +
+' </wps:Body>' +
+' </wps:Reference>' +
+' </wps:Input>' +
+' </wps:DataInputs>' +
+' <wps:ResponseForm>' +
+' <wps:RawDataOutput>' +
+' <ows:Identifier>result</ows:Identifier>' +
+' </wps:RawDataOutput>' +
+' </wps:ResponseForm>' +
+'</wps:Execute>';
+
+ var format = new OpenLayers.Format.WPSExecute();
+ var result = format.write({
+ identifier: "JTS:area",
+ dataInputs: [{
+ identifier: 'geom',
+ reference: {
+ mimeType: "text/xml; subtype=gml/3.1.1",
+ href: "http://geoserver/wps",
+ method: "POST",
+ body: {
+ identifier: "gs:CollectGeometries",
+ dataInputs: [{
+ identifier: 'features',
+ reference: {
+ mimeType: "text/xml; subtype=wfs-collection/1.0",
+ href: "http://geoserver/wfs",
+ method: "POST",
+ body: {
+ wfs: {
+ version: "1.0.0",
+ outputFormat: "GML2",
+ featureType: "sf:archsites"
+ }
+ }
+ }
+ }],
+ responseForm: {
+ rawDataOutput: {
+ mimeType: "text/xml; subtype=gml/3.1.1",
+ identifier: "result"
+ }
+ }
+ }
+ }
+ }],
+ responseForm: {
+ rawDataOutput: {
+ identifier: "result"
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WPS Execute written out correctly");
+ }
+
+ function test_write_raw_data_output(t) {
+ t.plan(1);
+ // example request taken from: http://geoprocessing.info/wpsdoc/1x0ExecutePOST
+ var expected = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
+'<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" ' +
+'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">' +
+' <ows:Identifier>Buffer</ows:Identifier>' +
+' <wps:DataInputs>' +
+' <wps:Input>' +
+' <ows:Identifier>InputPolygon</ows:Identifier>' +
+' <ows:Title>Playground area</ows:Title>' +
+' <wps:Reference xlink:href="http://foo.bar/some_WFS_request.xml"/>' +
+' </wps:Input>' +
+' <wps:Input>' +
+' <ows:Identifier>BufferDistance</ows:Identifier>' +
+' <ows:Title>Distance which people will walk to get to a playground.</ows:Title>' +
+' <wps:Data>' +
+' <wps:LiteralData>400</wps:LiteralData>' +
+' </wps:Data>' +
+' </wps:Input>' +
+' </wps:DataInputs>' +
+' <wps:ResponseForm>' +
+' <wps:RawDataOutput>' +
+' <ows:Identifier>BufferedPolygon</ows:Identifier>' +
+' </wps:RawDataOutput>' +
+' </wps:ResponseForm>' +
+'</wps:Execute>';
+
+ var format = new OpenLayers.Format.WPSExecute();
+ var result = format.write({
+ identifier: "Buffer",
+ dataInputs: [{
+ identifier: 'InputPolygon',
+ title: 'Playground area',
+ reference: {
+ href: 'http://foo.bar/some_WFS_request.xml'
+ }
+ }, {
+ identifier: 'BufferDistance',
+ title: 'Distance which people will walk to get to a playground.',
+ data: {
+ literalData: {
+ value: 400
+ }
+ }
+ }],
+ responseForm: {
+ rawDataOutput: {
+ identifier: "BufferedPolygon"
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WPS Execute written out correctly");
+ }
+
+ function test_write_request_responseDoc_defaultFormat(t) {
+ t.plan(1);
+ // taken from http://geoprocessing.info/schemas/wps/1.0/examples/51_wpsExecute_request_ResponseDocument.xml
+ var expected = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
+'<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" ' +
+'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">' +
+' <ows:Identifier>Buffer</ows:Identifier>' +
+' <wps:DataInputs>' +
+' <wps:Input>' +
+' <ows:Identifier>InputPolygon</ows:Identifier>' +
+' <ows:Title>Playground area</ows:Title>' +
+' <wps:Reference xlink:href="http://foo.bar/some_WFS_request.xml"/>' +
+' </wps:Input>' +
+' <wps:Input>' +
+' <ows:Identifier>BufferDistance</ows:Identifier>' +
+' <ows:Title>Distance which people will walk to get to a playground.</ows:Title>' +
+' <wps:Data>' +
+' <wps:LiteralData>400</wps:LiteralData>' +
+' </wps:Data>' +
+' </wps:Input>' +
+' </wps:DataInputs>' +
+' <wps:ResponseForm>' +
+' <wps:ResponseDocument storeExecuteResponse="true">' +
+' <wps:Output asReference="true">' +
+' <ows:Identifier>BufferedPolygon</ows:Identifier>' +
+' <ows:Title>Area serviced by playground.</ows:Title>' +
+' <ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>' +
+' </wps:Output>' +
+' </wps:ResponseDocument>' +
+' </wps:ResponseForm>' +
+'</wps:Execute>';
+
+ var format = new OpenLayers.Format.WPSExecute();
+ var result = format.write({
+ identifier: "Buffer",
+ dataInputs: [{
+ identifier: 'InputPolygon',
+ title: 'Playground area',
+ reference: {
+ href: 'http://foo.bar/some_WFS_request.xml'
+ }
+ }, {
+ identifier: 'BufferDistance',
+ title: 'Distance which people will walk to get to a playground.',
+ data: {
+ literalData: {
+ value: 400
+ }
+ }
+ }],
+ responseForm: {
+ responseDocument: {
+ storeExecuteResponse: true,
+ outputs: [{
+ asReference: true,
+ identifier: 'BufferedPolygon',
+ title: 'Area serviced by playground.',
+ 'abstract': 'Area within which most users of this playground will live.'
+ }]
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WPS Execute written out correctly");
+ }
+
+ function test_write_request_responseDoc_specifiedFormat(t) {
+ t.plan(1);
+ // taken from http://geoprocessing.info/schemas/wps/1.0/examples/52_wpsExecute_request_ResponseDocument.xml
+ var expected = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
+'<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" ' +
+'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">' +
+' <ows:Identifier>Buffer</ows:Identifier>' +
+' <wps:DataInputs>' +
+' <wps:Input>' +
+' <ows:Identifier>InputPolygon</ows:Identifier>' +
+' <ows:Title>Playground area</ows:Title>' +
+' <wps:Reference xlink:href="http://foo.bar/some_WFS_request.xml" method="POST" mimeType="text/xml" encoding="UTF-8" schema="http://foo.bar/gml_polygon_schema.xsd"/>' +
+' </wps:Input>' +
+' <wps:Input>' +
+' <ows:Identifier>BufferDistance</ows:Identifier>' +
+' <ows:Title>Distance which people will walk to get to a playground.</ows:Title>' +
+' <wps:Data>' +
+' <wps:LiteralData uom="feet">400</wps:LiteralData>' +
+' </wps:Data>' +
+' </wps:Input>' +
+' </wps:DataInputs>' +
+' <wps:ResponseForm>' +
+' <wps:ResponseDocument storeExecuteResponse="true" lineage="true" status="true">' +
+' <wps:Output asReference="true">' +
+' <ows:Identifier>BufferedPolygon</ows:Identifier>' +
+' <ows:Title>Area serviced by playground.</ows:Title>' +
+' <ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>' +
+' </wps:Output>' +
+' <wps:Output>' +
+' <ows:Identifier>literal</ows:Identifier>' +
+' <ows:Title/>' +
+' <ows:Abstract/>' +
+' </wps:Output>' +
+' </wps:ResponseDocument>' +
+' </wps:ResponseForm>' +
+'</wps:Execute>';
+
+ var format = new OpenLayers.Format.WPSExecute();
+ var result = format.write({
+ identifier: "Buffer",
+ dataInputs: [{
+ identifier: 'InputPolygon',
+ title: 'Playground area',
+ reference: {
+ href: 'http://foo.bar/some_WFS_request.xml',
+ method: "POST",
+ mimeType: "text/xml",
+ encoding: "UTF-8",
+ schema: "http://foo.bar/gml_polygon_schema.xsd"
+ }
+ }, {
+ identifier: 'BufferDistance',
+ title: 'Distance which people will walk to get to a playground.',
+ data: {
+ literalData: {
+ value: 400,
+ uom: 'feet'
+ }
+ }
+ }],
+ responseForm: {
+ responseDocument: {
+ storeExecuteResponse: true,
+ lineage: true,
+ status: true,
+ outputs: [
+ {
+ asReference: true,
+ identifier: 'BufferedPolygon',
+ title: 'Area serviced by playground.',
+ 'abstract': 'Area within which most users of this playground will live.'
+ },
+ {
+ identifier: 'literal'
+ }
+ ]
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WPS Execute written out correctly");
+ }
+
+ function test_write_request_complexData(t) {
+ t.plan(1);
+ // taken from http://geoprocessing.info/schemas/wps/1.0/examples/51_wpsExecute_request_ResponseDocument.xml
+ var expected = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
+ '<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" ' +
+ 'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">' +
+ ' <ows:Identifier>Buffer</ows:Identifier>' +
+ ' <wps:DataInputs>' +
+ ' <wps:Input>' +
+ ' <ows:Identifier>InputPolygon</ows:Identifier>' +
+ ' <ows:Title>Playground area</ows:Title>' +
+ ' <wps:Reference xlink:href="http://foo.bar/some_WFS_request.xml"/>' +
+ ' </wps:Input>' +
+ ' <wps:Input>' +
+ ' <ows:Identifier>ResultPage</ows:Identifier>' +
+ ' <ows:Title>Nicely formatted HTML of the result</ows:Title>' +
+ ' <wps:Data>' +
+ ' <wps:ComplexData><![CDATA[<html><head></head><body></body></head>]]></wps:ComplexData>' +
+ ' </wps:Data>' +
+ ' </wps:Input>' +
+ ' <wps:Input>' +
+ ' <ows:Identifier>GMLPoint</ows:Identifier>' +
+ ' <ows:Title>Point as GML</ows:Title>' +
+ ' <wps:Data>' +
+ ' <wps:ComplexData><feature:geometry xmlns:feature="http://www.opengis.net/gml"><feature:Point><feature:pos>10 10</feature:pos></feature:Point></feature:geometry></wps:ComplexData>' +
+ ' </wps:Data>' +
+ ' </wps:Input>' +
+ ' </wps:DataInputs>' +
+ ' <wps:ResponseForm>' +
+ ' <wps:ResponseDocument storeExecuteResponse="true">' +
+ ' <wps:Output asReference="true">' +
+ ' <ows:Identifier>BufferedPolygon</ows:Identifier>' +
+ ' <ows:Title>Area serviced by playground.</ows:Title>' +
+ ' <ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>' +
+ ' </wps:Output>' +
+ ' </wps:ResponseDocument>' +
+ ' </wps:ResponseForm>' +
+ '</wps:Execute>';
+
+ var format = new OpenLayers.Format.WPSExecute();
+ var result = format.write({
+ identifier: "Buffer",
+ dataInputs: [{
+ identifier: 'InputPolygon',
+ title: 'Playground area',
+ reference: {
+ href: 'http://foo.bar/some_WFS_request.xml'
+ }
+ }, {
+ identifier: 'ResultPage',
+ title: 'Nicely formatted HTML of the result',
+ data: {
+ complexData: {
+ value: "<html><head></head><body></body></head>"
+ }
+ }
+ }, {
+ identifier: "GMLPoint",
+ title: "Point as GML",
+ data: {
+ complexData: {
+ value: OpenLayers.Format.GML.v3.prototype.writers.feature["_geometry"].apply(new OpenLayers.Format.GML.v3({curve: true, surface: true}), [new OpenLayers.Geometry.Point(10, 10)])
+ }
+ }
+ }],
+ responseForm: {
+ responseDocument: {
+ storeExecuteResponse: true,
+ outputs: [{
+ asReference: true,
+ identifier: 'BufferedPolygon',
+ title: 'Area serviced by playground.',
+ 'abstract': 'Area within which most users of this playground will live.'
+ }]
+ }
+ }
+ });
+ t.xml_eq(result, expected, "WPS Execute written out correctly");
+ }
+
+ function test_write_WPSExecuteFID(t) {
+ t.plan(1);
+
+ var result,
+ expected,
+ format = ({geometryName: 'the_geom'});
+
+ expected = '<?xml version="1.0" encoding="UTF-8"?>' +
+ '<wps:Execute xmlns:wps="http://www.opengis.net/wps/1.0.0" version="1.0.0" service="WPS" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
+ ' <ows:Identifier xmlns:ows="http://www.opengis.net/ows/1.1">gs:Bounds</ows:Identifier>' +
+ ' <wps:DataInputs>' +
+ ' <wps:Input>' +
+ ' <ows:Identifier xmlns:ows="http://www.opengis.net/ows/1.1">features</ows:Identifier>' +
+ ' <wps:Reference mimeType="text/xml" xlink:href="http://geoserver/wfs" xmlns:xlink="http://www.w3.org/1999/xlink" method="POST">' +
+ ' <wps:Body>' +
+ ' <wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.0.0">' +
+ ' <wfs:Query typeName="foo:bar">' +
+ ' <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ ' <ogc:FeatureId fid="123"/>' +
+ ' </ogc:Filter>' +
+ ' </wfs:Query>' +
+ ' </wfs:GetFeature>' +
+ ' </wps:Body>' +
+ ' </wps:Reference>' +
+ ' </wps:Input>' +
+ ' </wps:DataInputs>' +
+ ' <wps:ResponseForm>' +
+ ' <wps:RawDataOutput>' +
+ ' <ows:Identifier xmlns:ows="http://www.opengis.net/ows/1.1">bounds</ows:Identifier>' +
+ ' </wps:RawDataOutput>' +
+ ' </wps:ResponseForm>' +
+ '</wps:Execute>';
+
+ result = new OpenLayers.Format.WPSExecute().write({
+ identifier: 'gs:Bounds',
+ dataInputs: [{
+ identifier: 'features',
+ reference: {
+ mimeType: 'text/xml',
+ href: 'http://geoserver/wfs',
+ method: 'POST',
+ body: {
+ wfs: {
+ featureType: 'foo:bar',
+ version: '1.0.0',
+ filter: new OpenLayers.Filter.FeatureId({fids: [123]})
+ }
+ }
+ }
+ }],
+ responseForm: {
+ rawDataOutput: {
+ identifier: 'bounds'
+ }
+ }
+ });
+ t.xml_eq(result, expected, 'WPS Execute written out correctly with a FID filter');
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/XLS/v1_1_0.html b/misc/openlayers/tests/Format/XLS/v1_1_0.html
new file mode 100644
index 0000000..8a744f9
--- /dev/null
+++ b/misc/openlayers/tests/Format/XLS/v1_1_0.html
@@ -0,0 +1,98 @@
+<html>
+<head>
+ <script src="../../../lib/OpenLayers.js"></script>
+ <script type="text/javascript">
+ function test_read(t) {
+ t.plan(16);
+ var response = '<xls:GeocodeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/LocationUtilityService.xsd" xmlns:xls="http://www.opengis.net/xls" xmlns:gml="http://www.opengis.net/gml"><xls:GeocodeResponseList numberOfGeocodedAddresses="1"><xls:GeocodedAddress><gml:Point srsName="EPSG:28992"><gml:pos dimension="2">122650 483904</gml:pos></gml:Point><xls:Address countryCode="NL"><xls:StreetAddress><xls:Building number="1"/><xls:Street>president kennedylaan</xls:Street></xls:StreetAddress><xls:Place type="MunicipalitySubdivision">amsterdam</xls:Place><xls:Place type="Municipality">amsterdam</xls:Place><xls:Place type="CountrySubdivision">noord holland</xls:Place><xls:PostalCode>1079MB</xls:PostalCode></xls:Address></xls:GeocodedAddress></xls:GeocodeResponseList></xls:GeocodeResponse>';
+ var format = new OpenLayers.Format.XLS();
+ var output = format.read(response);
+ t.eq(output.responseLists.length, 1, "Output contains 1 responseList");
+ var responseList = output.responseLists[0];
+ t.eq(responseList.numberOfGeocodedAddresses, 1, "Responselist contains 1 geocoded address");
+ t.eq(responseList.features.length, 1, "1 feature parsed");
+ var feature = responseList.features[0];
+ var address = feature.attributes.address;
+ t.eq(address.building["number"], "1", "Building number correctly parsed");
+ t.eq(address.countryCode, "NL", "Country code correctly parsed");
+ t.eq(address.place.CountrySubdivision, "noord holland", "CountrySubDivision correctly parsed");
+ t.eq(address.place.Municipality, "amsterdam", "Municipality correctly parsed");
+ t.eq(address.place.MunicipalitySubdivision, "amsterdam", "MunicipalitySubdivision correctly parsed");
+ t.eq(address.postalCode, "1079MB", "Postalcode correctly parsed");
+ t.eq(address.street[0], "president kennedylaan", "Street correctly parsed");
+ t.eq(feature.geometry.x, 122650, "Geometry [x] correctly parsed");
+ t.eq(feature.geometry.y, 483904, "Geometry [y] correctly parsed");
+
+ var responseList = [];
+ responseList.push('<?xml version="1.0" encoding="UTF-8" ?>',
+'<XLS xmlns="http://www.opengis.net/xls" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/xls LocationUtilityService.xsd" version="1.1">',
+' <ResponseHeader/>',
+' <Response version="1.1" requestID="">',
+' <GeocodeResponse>',
+' <GeocodeResponseList numberOfGeocodedAddresses="2">',
+' <GeocodedAddress>',
+' <gml:Point>',
+' <gml:pos>-71.4589837781615 41.8317239069808</gml:pos>',
+' </gml:Point>',
+' <Address countryCode="">',
+' <StreetAddress>',
+' <Street></Street>',
+' <Street/>',
+' </StreetAddress>',
+' <Place type="Municipality"></Place>',
+' <Place type="CountrySubdivision"></Place>',
+' <PostalCode></PostalCode>',
+' </Address>',
+' <GeocodeMatchCode accuracy="100.0"/>',
+' </GeocodedAddress>',
+' <GeocodedAddress>',
+' <gml:Point>',
+' <gml:pos>-71.4087296631643 41.8269575002255</gml:pos>',
+' </gml:Point>',
+' <Address countryCode="">',
+' <StreetAddress>',
+' <Street></Street>',
+' <Street/>',
+' </StreetAddress>',
+' <Place type="Municipality"></Place>',
+' <Place type="CountrySubdivision"></Place>',
+' <PostalCode></PostalCode>',
+' </Address>',
+' <GeocodeMatchCode accuracy="100.0"/>',
+' </GeocodedAddress>',
+' </GeocodeResponseList>',
+' </GeocodeResponse>',
+' </Response>',
+'</XLS>');
+ response = responseList.join("");
+ output = format.read(response);
+ t.eq(output.version, "1.1", "Version correctly parsed");
+ var responseList = output.responseLists[0];
+ t.eq(responseList.numberOfGeocodedAddresses, 2, "2 addresses parsed");
+ t.eq(responseList.features.length, 2, "2 features parsed");
+ t.eq(responseList.features[0].attributes.matchCode.accuracy, 100.0, "Accuracy correctly parsed");
+ }
+
+ function test_write(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.XLS();
+ var address = {
+ countryCode: 'US',
+ street: '1 Freedom Rd',
+ municipality: 'Providence',
+ countrySubdivision: 'RI',
+ postalCode: '02909'
+ };
+ var request = format.write({addresses: [address]});
+
+ var expected = '<xls:XLS xmlns:xls="http://www.opengis.net/xls" version="1.1" xsi:schemaLocation="http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/LocationUtilityService.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><xls:RequestHeader/><xls:Request methodName="GeocodeRequest" requestID="" version="1.1"><xls:GeocodeRequest><xls:Address countryCode="US"><xls:StreetAddress><xls:Street>1 Freedom Rd</xls:Street></xls:StreetAddress><xls:Place type="Municipality">Providence</xls:Place><xls:Place type="CountrySubdivision">RI</xls:Place><xls:PostalCode>02909</xls:PostalCode></xls:Address></xls:GeocodeRequest></xls:Request></xls:XLS>';
+
+ t.xml_eq(request, expected, "XLS geocode request correctly written");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/XML.html b/misc/openlayers/tests/Format/XML.html
new file mode 100644
index 0000000..d139506
--- /dev/null
+++ b/misc/openlayers/tests/Format/XML.html
@@ -0,0 +1,900 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var text =
+ '<?xml version="1.0"?>' +
+ '<ol:root xmlns="http://namespace.default.net" ' +
+ 'xmlns:ol="http://namespace.openlayers.org" ' +
+ 'xmlns:ta="http://namespace.testattribute.net">' +
+ '<ol:child ta:attribute="value1" ' +
+ 'attribute="value2">' +
+ 'junk1' +
+ '<' + '/ol:child>' +
+ '<ol:child>junk2<' + '/ol:child>' +
+ '<ol:child>junk3<' + '/ol:child>' +
+ '<element>junk4<' + '/element>' +
+ '<ol:element>junk5<' + '/ol:element>' +
+ '<ol:p>' +
+ '<ol:a>junk' +
+ '<' + '/ol:a>' +
+ '<ol:b>junk' +
+ '<' + '/ol:b>' +
+ '<ol:a>junk' +
+ '<' + '/ol:a>' +
+ '<' + '/ol:p>' +
+ '<' + '/ol:root>';
+
+ function test_Format_XML_constructor(t) {
+ t.plan(13);
+
+ var options = {'foo': 'bar'};
+ var format = new OpenLayers.Format.XML(options);
+ t.ok(format instanceof OpenLayers.Format.XML,
+ "new OpenLayers.Format.XML returns object" );
+ t.eq(format.foo, "bar", "constructor sets options correctly");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a write function");
+
+ t.ok(!window.ActiveXObject || format.xmldom, "browsers with activeX must have xmldom");
+
+ // test namespaces
+ t.ok(format.namespaces instanceof Object, "format has namespace object");
+ var namespaces = {"foo": "bar"};
+ format = new OpenLayers.Format.XML({namespaces: namespaces});
+ t.eq(format.namespaces, namespaces, "format.namespaces correctly set in constructor");
+
+ // test default prefix
+ t.eq(format.defaultPrefix, null, "defaultPrefix is null by default");
+ format = new OpenLayers.Format.XML({defaultPrefix: "foo"});
+ t.eq(format.defaultPrefix, "foo", "defaultPrefix correctly set in constructor");
+
+ // test readers
+ t.ok(format.readers instanceof Object, "format has readers object");
+ var readers = {"foo": "bar"};
+ format = new OpenLayers.Format.XML({readers: readers});
+ t.eq(format.readers, readers, "format.readers correctly set in constructor");
+
+ // test readers
+ t.ok(format.writers instanceof Object, "format has writers object");
+ var writers = {"foo": "bar"};
+ format = new OpenLayers.Format.XML({writers: writers});
+ t.eq(format.writers, writers, "format.writers correctly set in constructor");
+ }
+
+ function test_destroy(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.XML();
+ format.destroy();
+ t.eq(format.xmldom, null, "xmldom set to null for all browsers");
+ }
+
+ function test_Format_XML_read(t) {
+
+ var format = new OpenLayers.Format.XML();
+ t.plan(format.xmldom ? 10 : 9);
+
+ var doc = format.read(text);
+ t.eq(doc.nodeType, 9,
+ "doc has the correct node type");
+ t.eq(doc.nodeName, "#document",
+ "doc has the correct node name");
+ t.ok(doc.documentElement,
+ "ok to access doc.documentElement");
+ t.xml_eq(doc.documentElement, text,
+ "doc.documentElement correctly read");
+
+ // read can also be called on the prototype directly
+ doc = OpenLayers.Format.XML.prototype.read(text);
+ t.eq(doc.nodeType, 9,
+ "doc has the correct node type");
+ t.eq(doc.nodeName, "#document",
+ "doc has the correct node name");
+ t.ok(doc.documentElement,
+ "ok to access doc.documentElement");
+ t.xml_eq(doc.documentElement, text,
+ "doc.documentElement correctly read");
+
+ // where appropriate, make sure doc is loaded into xmldom property
+ if(format.xmldom) {
+ t.xml_eq(format.xmldom.documentElement, text,
+ "xmldom.documentElement contains equivalent xml");
+ }
+
+ // test equivalence with different namespace alias
+ var pre1 =
+ "<pre1:parent xmlns:pre1='http://namespace'>" +
+ "<pre1:child1>value2</pre1:child1>" +
+ "<pre1:child2 pre1:attr1='foo'>value2</pre1:child2>" +
+ "<pre1:child3 chicken:attr='hot' xmlns:chicken='http://soup'/>" +
+ "</pre1:parent>";
+ var pre2 =
+ "<pre2:parent xmlns:pre2='http://namespace'>" +
+ "<pre2:child1>value2</pre2:child1>" +
+ "<pre2:child2 pre2:attr1='foo'>value2</pre2:child2>" +
+ "<pre2:child3 pea:attr='hot' xmlns:pea='http://soup'/>" +
+ "</pre2:parent>";
+ var doc1 = format.read(pre1);
+ t.xml_eq(doc1.documentElement, pre2, "read correctly sets namespaces");
+
+ }
+
+ function test_Format_XML_write(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text);
+ var out = format.write(doc);
+ out = out.replace(/[\r\n]/g, '');
+ out = out.replace( /<\?.*\?>/, '')
+ var expected = text.replace(/<\?.*\?>/, '')
+ t.eq(expected, out,
+ "correctly writes an XML DOM doc");
+ var out = format.write(
+ format.getElementsByTagNameNS(doc,
+ "http://namespace.openlayers.org","root")[0]);
+ out = out.replace(/[\r\n]/g, '');
+ out = out.replace( /<\?.*\?>/, '')
+ t.eq(out, expected,
+ "correctly writes an XML DOM node");
+ }
+
+ function test_Format_XML_createElementNS(t) {
+ t.plan(5);
+
+ var format = new OpenLayers.Format.XML();
+ var uri = "http://foo.com";
+ var prefix = "foo";
+ var localName = "bar";
+ var qualifiedName = prefix + ":" + localName;
+ var node = format.createElementNS(uri, qualifiedName);
+ t.eq(node.nodeType, 1,
+ "node has correct type");
+ t.eq(node.nodeName, qualifiedName,
+ "node has correct qualified name");
+ t.eq(node.prefix, prefix,
+ "node has correct prefix");
+ t.eq(node.namespaceURI, uri,
+ "node has correct namespace uri");
+
+ var doc = format.read(text);
+ if (doc.importNode) {
+ node = doc.importNode(node, true);
+ }
+ t.ok(doc.documentElement.appendChild(node),
+ "node can be appended to a doc root");
+ }
+
+ function test_createDocumentFragment(t) {
+ t.plan(3);
+
+ var format = new OpenLayers.Format.XML();
+ var uri = "http://foo.com";
+ var prefix = "foo";
+ var localName = "bar";
+ var qualifiedName = prefix + ":" + localName;
+ var parent = format.createElementNS(uri, qualifiedName);
+
+ var fragment = format.createDocumentFragment();
+ t.eq(fragment.nodeType, 11, "fragment type");
+
+ try {
+ fragment.appendChild(format.createTextNode("one"));
+ fragment.appendChild(format.createTextNode("two"));
+ t.eq(fragment.childNodes.length, 2, "fragment has two child nodes");
+ } catch (err) {
+ t.fail("trouble appending text nodes to fragment: " + err.message);
+ }
+
+ try {
+ parent.appendChild(fragment);
+ t.eq(parent.childNodes.length, 2, "parent has two child nodes");
+ } catch (err) {
+ t.fail("trouble appending fragment to parent: " + err.message);
+ }
+ }
+
+ function test_Format_XML_createTextNode(t) {
+ t.plan(10);
+
+ var format = new OpenLayers.Format.XML();
+ var value, node;
+
+ value = "string";
+ node = format.createTextNode(value);
+ t.eq(node.nodeType, 3,
+ "[string] node has correct type");
+ t.eq(node.nodeName, "#text",
+ "[string] node has correct name");
+ t.eq(node.nodeValue, "string",
+ "[string] node has correct value");
+
+ value = 0.42;
+ node = format.createTextNode(value);
+ t.eq(node.nodeType, 3,
+ "[number] node has correct type");
+ t.eq(node.nodeName, "#text",
+ "[number] node has correct name");
+ t.eq(node.nodeValue, "0.42",
+ "[number] node has correct value");
+
+ value = false;
+ node = format.createTextNode(value);
+ t.eq(node.nodeType, 3,
+ "[boolean] node has correct type");
+ t.eq(node.nodeName, "#text",
+ "[boolean] node has correct name");
+ t.eq(node.nodeValue, "false",
+ "[boolean] node has correct value");
+
+ var doc = format.read(text);
+ if (doc.importNode) {
+ node = doc.importNode(node, true);
+ }
+ t.ok(doc.documentElement.appendChild(node),
+ "node can be appended to a doc root");
+ }
+
+ function test_Format_XML_getElementsByTagNameNS(t) {
+ t.plan(5);
+
+ var format = new OpenLayers.Format.XML();
+ var olUri = "http://namespace.openlayers.org";
+ var name = "child";
+ var doc = format.read(text);
+ var nodes = format.getElementsByTagNameNS(doc.documentElement,
+ olUri, name);
+ t.eq(nodes.length, 3,
+ "gets correct number of nodes");
+ var qualifiedName = nodes[0].prefix + ":" + name;
+ t.eq(nodes[0].nodeName, qualifiedName,
+ "first node has correct qualified name");
+
+ var defaultUri = "http://namespace.default.net";
+ name = "element";
+ nodes = format.getElementsByTagNameNS(doc.documentElement,
+ defaultUri, name);
+ t.eq(nodes.length, 1,
+ "gets correct number of nodes in default namespace");
+
+ var pList = format.getElementsByTagNameNS(doc.documentElement,
+ olUri, "p");
+ t.eq(pList.length, 1, "got one ol:p element");
+ var p = pList[0];
+
+ var aList = format.getElementsByTagNameNS(p, olUri, "a");
+ t.eq(aList.length, 2, "got two child ol:a elements");
+
+
+
+ }
+
+ function test_Format_XML_getAttributeNodeNS(t) {
+ t.plan(5);
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text);
+ var olUri = "http://namespace.openlayers.org";
+ var taUri = "http://namespace.testattribute.net";
+ var localNodeName = "child";
+ var localAttrName = "attribute";
+ var nodes = format.getElementsByTagNameNS(doc.documentElement,
+ olUri, localNodeName);
+ var attributeNode = format.getAttributeNodeNS(nodes[0],
+ taUri, localAttrName);
+ var qualifiedName = attributeNode.prefix + ":" + localAttrName;
+
+ t.ok(attributeNode,
+ "returns non-null value");
+ t.eq(attributeNode.nodeType, 2,
+ "attribute node has correct type");
+ t.eq(attributeNode.nodeName, qualifiedName,
+ "attribute node has correct qualified name");
+ t.eq(attributeNode.nodeValue, "value1",
+ "attribute node has correct value");
+
+ var nullAttribute = format.getAttributeNodeNS(nodes[0],
+ taUri, "nothing");
+ t.ok(nullAttribute === null,
+ "returns null for nonexistent attribute");
+ }
+
+ function test_Format_XML_getAttributeNS(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text);
+ var olUri = "http://namespace.openlayers.org";
+ var taUri = "http://namespace.testattribute.net";
+ var localNodeName = "child";
+ var localAttrName = "attribute";
+ var nodes = format.getElementsByTagNameNS(doc.documentElement,
+ olUri, localNodeName);
+ var attributeValue = format.getAttributeNS(nodes[0],
+ taUri, localAttrName);
+ t.eq(attributeValue, "value1",
+ "got correct attribute value");
+
+ var emptyValue = format.getAttributeNS(nodes[0],
+ taUri, "nothing");
+ t.ok(emptyValue === "",
+ "returns empty string for nonexistent attributes");
+ }
+
+ function test_Format_XML_hasAttributeNS(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text);
+ var olUri = "http://namespace.openlayers.org";
+ var taUri = "http://namespace.testattribute.net";
+ var localNodeName = "child";
+ var localAttrName = "attribute";
+ var nodes = format.getElementsByTagNameNS(doc.documentElement,
+ olUri, localNodeName);
+ var found = format.hasAttributeNS(nodes[0], taUri, localAttrName);
+ t.ok(found === true, "returns true for good attribute");
+
+ found = format.hasAttributeNS(nodes[0], taUri, "nothing");
+ t.ok(found === false, "returns false for bad attribute");
+ }
+
+ function test_namespaces(t) {
+ t.plan(2);
+
+ var format = new OpenLayers.Format.XML({
+ namespaces: {
+ "def": "http://example.com/default",
+ "foo": "http://example.com/foo",
+ "bar": "http://example.com/bar"
+ },
+ defaultPrefix: "def"
+ });
+
+ // test that prototype has not been altered
+ t.eq(OpenLayers.Format.XML.prototype.namespaces, null,
+ "setting namespaces at construction does not modify prototype");
+
+ // test that namespaceAlias has been set
+ t.eq(format.namespaceAlias["http://example.com/foo"], "foo",
+ "namespaceAlias mapping has been set");
+
+ }
+
+ function test_setNamespace(t) {
+ t.plan(3);
+
+ var format = new OpenLayers.Format.XML();
+
+ // test that namespaces is an object
+ t.ok(format.namespaces instanceof Object, "empty namespace object set");
+
+ format.setNamespace("foo", "http://example.com/foo");
+ t.eq(format.namespaces["foo"], "http://example.com/foo", "alias -> uri mapping set");
+ t.eq(format.namespaceAlias["http://example.com/foo"], "foo", "uri -> alias mapping set");
+
+ }
+
+ function test_readChildNodes(t) {
+
+ var text = "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<container xmlns='http://example.com/foo'>" +
+ "<marker name='my marker 1'>" +
+ "<position>" +
+ "<lon>-180</lon>" +
+ "<lat>90</lat>" +
+ "</position>" +
+ "<detail>some text for first marker</detail>" +
+ "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/1'/>" +
+ "</marker>" +
+ "<marker name='my marker 2'>" +
+ "<position>" +
+ "<lon>180</lon>" +
+ "<lat>-90</lat>" +
+ "</position>" +
+ "<detail>some text for second marker</detail>" +
+ "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/2'/>" +
+ "</marker>" +
+ "</container>";
+
+ var expect = [
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(-180, 90),
+ {
+ name: 'my marker 1',
+ link: 'http://host/path/1',
+ detail: 'some text for first marker'
+ }
+ ),
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(180, -90),
+ {
+ name: 'my marker 2',
+ link: 'http://host/path/2',
+ detail: 'some text for second marker'
+ }
+ )
+ ];
+
+ var format = new OpenLayers.Format.XML({
+ defaultPrefix: "foo",
+ namespaces: {
+ "foo": "http://example.com/foo",
+ "atom": "http://www.w3.org/2005/Atom"
+ },
+ readers: {
+ "foo": {
+ "container": function(node, obj) {
+ var list = [];
+ this.readChildNodes(node, list);
+ obj.list = list;
+ },
+ "marker": function(node, list) {
+ var feature = new OpenLayers.Feature.Vector();
+ feature.attributes.name = node.getAttribute("name");
+ this.readChildNodes(node, feature);
+ list.push(feature);
+ },
+ "position": function(node, feature) {
+ var obj = {};
+ this.readChildNodes(node, obj);
+ feature.geometry = new OpenLayers.Geometry.Point(obj.x, obj.y);
+ },
+ "lon": function(node, obj) {
+ obj.x = this.getChildValue(node);
+ },
+ "lat": function(node, obj) {
+ obj.y = this.getChildValue(node);
+ },
+ "detail": function(node, feature) {
+ feature.attributes.detail = this.getChildValue(node);
+ }
+ },
+ "atom": {
+ "link": function(node, feature) {
+ feature.attributes.link = node.getAttribute("href");
+ }
+ }
+ }
+ });
+
+ // convert text to document node
+ var doc = format.read(text);
+ // read child nodes to get back some object
+ var obj = format.readChildNodes(doc);
+ // start comparing what we got to what we expect
+ var got = obj.list;
+
+ t.plan(11);
+ t.eq(got.length, expect.length, "correct number of items parsed");
+ t.eq(got[0].geometry.x, expect[0].geometry.x, "correct x coord parsed for marker 1");
+ t.eq(got[0].geometry.y, expect[0].geometry.y, "correct y coord parsed for marker 1");
+ t.eq(got[0].attributes.name, expect[0].attributes.name, "correct name parsed for marker 1");
+ t.eq(got[0].attributes.detail, expect[0].attributes.detail, "correct detail parsed for marker 1");
+ t.eq(got[0].attributes.link, expect[0].attributes.link, "correct link parsed for marker 1");
+ t.eq(got[1].geometry.x, expect[1].geometry.x, "correct x coord parsed for marker 2");
+ t.eq(got[1].geometry.y, expect[1].geometry.y, "correct y coord parsed for marker 2");
+ t.eq(got[1].attributes.name, expect[1].attributes.name, "correct name parsed for marker 2");
+ t.eq(got[1].attributes.detail, expect[1].attributes.detail, "correct detail parsed for marker 2");
+ t.eq(got[1].attributes.link, expect[1].attributes.link, "correct link parsed for marker 2");
+
+ }
+
+ function test_writeNode(t) {
+
+ var features = [
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(-180, 90),
+ {
+ name: 'my marker 1',
+ link: 'http://host/path/1',
+ detail: 'some text for first marker'
+ }
+ ),
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(180, -90),
+ {
+ name: 'my marker 2',
+ link: 'http://host/path/2',
+ detail: 'some text for second marker'
+ }
+ )
+ ];
+
+ var expect = "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<container xmlns='http://example.com/foo'>" +
+ "<marker name='my marker 1'>" +
+ "<position>" +
+ "<lon>-180</lon>" +
+ "<lat>90</lat>" +
+ "</position>" +
+ "<detail>some text for first marker</detail>" +
+ "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/1'/>" +
+ "</marker>" +
+ "<marker name='my marker 2'>" +
+ "<position>" +
+ "<lon>180</lon>" +
+ "<lat>-90</lat>" +
+ "</position>" +
+ "<detail>some text for second marker</detail>" +
+ "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/2'/>" +
+ "</marker>" +
+ "</container>";
+
+ var format = new OpenLayers.Format.XML({
+ defaultPrefix: "foo",
+ namespaces: {
+ "foo": "http://example.com/foo",
+ "atom": "http://www.w3.org/2005/Atom"
+ },
+ writers: {
+ "foo": {
+ "container": function(features) {
+ var node = this.createElementNSPlus("container");
+ var feature;
+ for(var i=0; i<features.length; ++i) {
+ feature = features[i];
+ this.writeNode("marker", features[i], node);
+ }
+ return node;
+ },
+ "marker": function(feature) {
+ var node = this.createElementNSPlus("marker", {
+ attributes: {name: feature.attributes.name}
+ });
+ this.writeNode("position", feature.geometry, node);
+ this.writeNode("detail", feature.attributes.detail, node);
+ this.writeNode("atom:link", feature.attributes.link, node);
+ return node;
+ },
+ "position": function(geometry) {
+ var node = this.createElementNSPlus("position");
+ this.writeNode("lon", geometry.x, node);
+ this.writeNode("lat", geometry.y, node);
+ return node;
+ },
+ "lon": function(x) {
+ return this.createElementNSPlus("lon", {
+ value: x
+ });
+ },
+ "lat": function(y) {
+ return this.createElementNSPlus("lat", {
+ value: y
+ });
+ },
+ "detail": function(text) {
+ return this.createElementNSPlus("detail", {
+ value: text
+ });
+ }
+ },
+ "atom": {
+ "link": function(href) {
+ return this.createElementNSPlus("atom:link", {
+ attributes: {href: href}
+ });
+ }
+ }
+ }
+
+ });
+
+ t.plan(1);
+ // test that we get what we expect from writeNode
+ var got = format.writeNode("container", features);
+ t.xml_eq(got, expect, "features correctly written");
+ }
+
+ function test_createElementNSPlus(t) {
+
+ var format = new OpenLayers.Format.XML({
+ defaultPrefix: "def",
+ namespaces: {
+ "def": "http://example.com/default",
+ "foo": "http://example.com/foo",
+ "bar": "http://example.com/bar"
+ }
+ });
+
+ var cases = [
+ {
+ description: "unprefixed name with default options",
+ node: format.createElementNSPlus("FooNode"),
+ expect: "<def:FooNode xmlns:def='http://example.com/default'/>"
+ }, {
+ description: "def prefixed name with default options",
+ node: format.createElementNSPlus("def:FooNode"),
+ expect: "<def:FooNode xmlns:def='http://example.com/default'/>"
+ }, {
+ description: "foo prefixed name with default options",
+ node: format.createElementNSPlus("foo:FooNode"),
+ expect: "<foo:FooNode xmlns:foo='http://example.com/foo'/>"
+ }, {
+ description: "unprefixed name with uri option",
+ node: format.createElementNSPlus("FooNode", {
+ uri: "http://example.com/elsewhere"
+ }),
+ expect: "<FooNode xmlns='http://example.com/elsewhere'/>"
+ }, {
+ description: "foo prefixed name with uri option (overriding format.namespaces)",
+ node: format.createElementNSPlus("foo:FooNode", {
+ uri: "http://example.com/elsewhere"
+ }),
+ expect: "<foo:FooNode xmlns:foo='http://example.com/elsewhere'/>"
+ }, {
+ description: "foo prefixed name with attributes option",
+ node: format.createElementNSPlus("foo:FooNode", {
+ attributes: {
+ "id": "123",
+ "foo:attr1": "namespaced attribute 1",
+ "bar:attr2": "namespaced attribute 2"
+ }
+ }),
+ expect: "<foo:FooNode xmlns:foo='http://example.com/foo' xmlns:bar='http://example.com/bar' id='123' foo:attr1='namespaced attribute 1' bar:attr2='namespaced attribute 2'/>"
+ }, {
+ description: "foo prefixed name with attributes and value options",
+ node: format.createElementNSPlus("foo:FooNode", {
+ attributes: {"id": "123"},
+ value: "text value"
+ }),
+ expect: "<foo:FooNode xmlns:foo='http://example.com/foo' id='123'>text value<" + "/foo:FooNode>"
+ }, {
+ description: "value of 0 gets appended as a text node",
+ node: format.createElementNSPlus("foo:bar", {value: 0}),
+ expect: "<foo:bar xmlns:foo='http://example.com/foo'>0</foo:bar>"
+ }, {
+ description: "value of 0.42 gets appended as a text node",
+ node: format.createElementNSPlus("foo:bar", {value: 0.42}),
+ expect: "<foo:bar xmlns:foo='http://example.com/foo'>0.42</foo:bar>"
+ }, {
+ description: "value of true gets appended as a text node",
+ node: format.createElementNSPlus("foo:bar", {value: true}),
+ expect: "<foo:bar xmlns:foo='http://example.com/foo'>true</foo:bar>"
+ }, {
+ description: "value of false gets appended as a text node",
+ node: format.createElementNSPlus("foo:bar", {value: false}),
+ expect: "<foo:bar xmlns:foo='http://example.com/foo'>false</foo:bar>"
+ }, {
+ description: "null value does not get appended as a text node",
+ node: format.createElementNSPlus("foo:bar", {value: null}),
+ expect: "<foo:bar xmlns:foo='http://example.com/foo'/>"
+ }, {
+ description: "undefined value does not get appended as a text node",
+ node: format.createElementNSPlus("foo:bar"),
+ expect: "<foo:bar xmlns:foo='http://example.com/foo'/>"
+ }
+ ];
+
+ t.plan(cases.length);
+ var test;
+ for(var i=0; i<cases.length; ++i) {
+ test = cases[i];
+ t.xml_eq(test.node, test.expect, test.description);
+ }
+
+ }
+
+ function test_setAttributes(t) {
+
+ var format = new OpenLayers.Format.XML({
+ defaultPrefix: "def",
+ namespaces: {
+ "def": "http://example.com/default",
+ "foo": "http://example.com/foo",
+ "bar": "http://example.com/bar"
+ }
+ });
+
+ var cases = [
+ {
+ description: "unprefixed attribute",
+ node: format.createElementNSPlus("foo:Node"),
+ attributes: {"id": "123"},
+ expect: "<foo:Node xmlns:foo='http://example.com/foo' id='123'/>"
+ }, {
+ description: "foo prefixed attribute",
+ node: format.createElementNSPlus("foo:Node"),
+ attributes: {"foo:id": "123"},
+ expect: "<foo:Node xmlns:foo='http://example.com/foo' foo:id='123'/>"
+ }, {
+ description: "foo prefixed attribute with def prefixed node",
+ node: format.createElementNSPlus("def:Node"),
+ attributes: {"foo:id": "123"},
+ expect: "<def:Node xmlns:def='http://example.com/default' xmlns:foo='http://example.com/foo' foo:id='123'/>"
+ }, {
+ description: "multiple attributes",
+ node: format.createElementNSPlus("def:Node"),
+ attributes: {"id": "123", "foo": "bar"},
+ expect: "<def:Node xmlns:def='http://example.com/default' id='123' foo='bar'/>"
+ }
+ ];
+
+ t.plan(cases.length);
+ var test;
+ for(var i=0; i<cases.length; ++i) {
+ test = cases[i];
+ format.setAttributes(test.node, test.attributes);
+ t.xml_eq(test.node, test.expect, test.description);
+ }
+
+ }
+
+ function test_keepData(t) {
+ t.plan(2);
+
+ var options = {'keepData': true};
+ var format = new OpenLayers.Format.XML(options);
+ format.read(text);
+
+ t.ok(format.data != null, 'data property is not null after read with keepData=true');
+ t.eq(format.data.documentElement.tagName,'ol:root','keepData keeps the right data');
+ }
+
+ function test_getChildValue(t) {
+
+ t.plan(1);
+
+ var text =
+ "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<root>" +
+ "x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z<foo />&#x79;" +
+ "</root>";
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text).documentElement;
+
+ t.eq(format.getChildValue(doc), "xyzzy", "child value skips comments, concatenates multiple values, reads through entities");
+
+ }
+
+ function test_getChildEl(t) {
+
+ t.plan(3);
+
+ var text =
+ "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<root>" +
+ "<!-- comment -->" +
+ "<a>x</a>" +
+ "<b>x</b>" +
+ "</root>";
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text).documentElement;
+
+ var a = format.getChildEl(doc);
+ t.eq(a.nodeName, "a", "first element found correctly");
+
+ a = format.getChildEl(doc, "a");
+ t.eq(b, null, "first child element matches the given name");
+
+ var b = format.getChildEl(doc, "b");
+ t.eq(b, null, "first child element does not match the given name");
+
+ }
+
+ function test_getNextEl(t) {
+ t.plan(5);
+
+ var text =
+ "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<root>" +
+ "<!-- comment -->" +
+ "<a>x</a>" +
+ "<!-- comment -->" +
+ "<b xmlns='urn:example'>x</b>" +
+ "</root>";
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text).documentElement;
+
+ var a = format.getChildEl(doc);
+
+ var b = format.getNextEl(a);
+ t.eq(b && b.nodeName, "b", "next element correctly found");
+
+ b = format.getNextEl(a, "b");
+ t.eq(b && b.nodeName, "b", "next element correctly found when name supplied");
+
+ b = format.getNextEl(a, "c");
+ t.eq(b, null, "null returned when name does not match next element");
+
+ b = format.getNextEl(a, null, "urn:example");
+ t.eq(b && b.nodeName, "b", "next element correctly found when namespace supplied");
+
+ b = format.getNextEl(a, null, "foo");
+ t.eq(b, null, "null returned when namespace does not match next element");
+
+ }
+
+ function test_isSimpleContent(t) {
+ t.plan(2);
+
+ var text =
+ "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<root>" +
+ "<!-- comment -->" +
+ "<a>x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z<foo />&#x79;</a>" +
+ "<!-- comment -->" +
+ "<b>x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z&#x79;</b>" +
+ "</root>";
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text).documentElement;
+
+ var a = format.getChildEl(doc);
+ var b = format.getNextEl(a);
+ t.ok(!format.isSimpleContent(a), "<a> content is not simple");
+ t.ok(format.isSimpleContent(b), "<b> content is simple");
+
+ }
+
+ function test_lookupNamespaceURI(t) {
+
+ t.plan(8);
+
+ var text =
+ "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<root xmlns:baz='urn:baznamespace'>" +
+ "<!-- comment -->" +
+ "<a><foo /></a>" +
+ "<!-- comment -->" +
+ "<b xmlns='urn:example'><!-- comment --><bar foo='value'/></b>" +
+ "</root>";
+
+ var format = new OpenLayers.Format.XML();
+ var doc = format.read(text).documentElement;
+
+ var a = format.getChildEl(doc);
+ t.eq(format.lookupNamespaceURI(a, "baz"), "urn:baznamespace", "prefix lookup on first child");
+
+ var foo = format.getChildEl(a);
+ t.eq(format.lookupNamespaceURI(foo, "baz"), "urn:baznamespace", "prefix lookup on child of first child");
+
+ var b = format.getNextEl(a);
+ t.eq(format.lookupNamespaceURI(b, null), "urn:example", "default namespace lookup on element");
+
+ var bar = format.getChildEl(b);
+ t.eq(format.lookupNamespaceURI(bar, null), "urn:example", "default namespace lookup on child");
+ t.eq(format.lookupNamespaceURI(bar, "baz"), "urn:baznamespace", "prefix lookup on child with different default");
+
+ // test that the alias behaves properly
+ var lookup = OpenLayers.Format.XML.lookupNamespaceURI;
+ t.eq(lookup(bar, "baz"), "urn:baznamespace", "(alias) prefix lookup on child with different default");
+
+ var attr = bar.attributes[0];
+ // Internet Explorer didn't have the ownerElement property until 8.
+ var supportsOwnerElement = !!attr.ownerElement;
+ if(supportsOwnerElement) {
+ t.eq(format.lookupNamespaceURI(attr, null), "urn:example", "default namespace lookup on attribute");
+ t.eq(format.lookupNamespaceURI(attr, "baz"), "urn:baznamespace", "prefix lookup on attribute with different default");
+ } else {
+ t.debug_print("namespace lookup on attributes not supported in this browser");
+ t.ok(true, "namespace lookup on attributes not supported in this browser");
+ t.ok(true, "namespace lookup on attributes not supported in this browser");
+ }
+
+ }
+
+ function test_getXMLDoc(t) {
+ t.plan(2);
+ var format = new OpenLayers.Format.XML();
+ var doc = format.getXMLDoc();
+ t.ok(doc !== document, "document returned from getXMLDoc is not the page's html doc");
+ var root = format.createElementNS("http://test", "root");
+ // appending CDATA created from a different document
+ var cdata = doc.createCDATASection("<foo></foo>");
+ root.appendChild(cdata);
+ var result = format.write(root);
+ var expect = '<root xmlns="http://test"><![CDATA[<foo></foo>]]></root>';
+ t.eq(result, expect, "document with CDATA section serialized correctly");
+ }
+
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Format/XML/VersionedOGC.html b/misc/openlayers/tests/Format/XML/VersionedOGC.html
new file mode 100644
index 0000000..ca96d63
--- /dev/null
+++ b/misc/openlayers/tests/Format/XML/VersionedOGC.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var snippet = '<foo version="2.0.0"></foo>';
+ var snippet2 = '<foo></foo>';
+
+ function test_Format_Versioned_constructor(t) {
+ t.plan(5);
+
+ var format = new OpenLayers.Format.XML.VersionedOGC({version: "1.0.0"});
+ t.ok(format instanceof OpenLayers.Format.XML.VersionedOGC,
+ "new OpenLayers.Format.XML.VersionedOGC returns object" );
+ t.eq(format.version, "1.0.0", "constructor sets version correctly");
+ t.eq(format.defaultVersion, null, "defaultVersion should be null if not specified");
+ t.eq(typeof format.read, "function", "format has a read function");
+ t.eq(typeof format.write, "function", "format has a read function");
+ }
+
+ function test_getVersion(t) {
+ t.plan(6);
+ var format = new OpenLayers.Format.XML.VersionedOGC();
+ // read
+ var data = new OpenLayers.Format.XML().read(snippet);
+ var root = data.documentElement;
+ var version = format.getVersion(root);
+ t.eq(version, "2.0.0", "Version taken from document");
+ format = new OpenLayers.Format.XML.VersionedOGC({version: "1.0.0"});
+ version = format.getVersion(root);
+ t.eq(version, "1.0.0", "Version taken from parser takes preference");
+ format = new OpenLayers.Format.XML.VersionedOGC({defaultVersion: "3.0.0"});
+ data = new OpenLayers.Format.XML().read(snippet2);
+ root = data.documentElement;
+ version = format.getVersion(root);
+ t.eq(version, "3.0.0", "If nothing else is set, defaultVersion should be returned");
+ // write
+ version = format.getVersion(null, {version: "1.3.0"});
+ t.eq(version, "1.3.0", "Version from options returned");
+ version = format.getVersion(null);
+ t.eq(version, "3.0.0", "defaultVersion returned if no version specified in options and no version on the format");
+ format.version = "2.1.3";
+ version = format.getVersion(null);
+ t.eq(version, "2.1.3", "version returned of the Format if no version specified in options");
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>