49 |
# $Id$ |
# $Id$ |
50 |
|
|
51 |
import xml.dom.minidom |
import xml.dom.minidom |
52 |
|
from xml.dom import Node |
53 |
|
|
54 |
from domutils import getElementsByName, getElementByName |
from domutils import getElementsByName, getElementByName |
55 |
|
|
56 |
|
from Thuban import _ |
57 |
|
|
58 |
class WMSCapabilitiesParser: |
class WMSCapabilitiesParser: |
59 |
""" |
""" |
60 |
Thuban class to parse capabilities supplied as large string. |
Thuban class to parse capabilities supplied as large string. |
71 |
access = None |
access = None |
72 |
formats = None |
formats = None |
73 |
srs_discrepancies = None |
srs_discrepancies = None |
74 |
|
error = None |
75 |
|
|
76 |
|
|
77 |
def __init__(self): |
def __init__(self): |
82 |
# Note that we must not initialise internal variables of the |
# Note that we must not initialise internal variables of the |
83 |
# class in a mutable way or it will be shared among all |
# class in a mutable way or it will be shared among all |
84 |
# instances. None is immutable, [] is not. |
# instances. None is immutable, [] is not. |
85 |
layers = [] |
self.error = [] |
86 |
|
|
87 |
|
|
88 |
def grok(self, data): |
def grok(self, data): |
109 |
# Extract fees information |
# Extract fees information |
110 |
foo = getElementByName(getElementByName(root, 'Service'), 'Fees') |
foo = getElementByName(getElementByName(root, 'Service'), 'Fees') |
111 |
if foo and len(foo.childNodes[0].data) \ |
if foo and len(foo.childNodes[0].data) \ |
112 |
and lower(foo.childNodes[0].data) != 'none': |
and foo.childNodes[0].data.lower() != 'none': |
113 |
self.fees = foo.childNodes[0].data |
self.fees = foo.childNodes[0].data |
114 |
|
|
115 |
# Extract access information |
# Extract access information |
116 |
foo = getElementByName(getElementByName(root, 'Service'), |
foo = getElementByName(getElementByName(root, 'Service'), |
117 |
'AccessConstraints') |
'AccessConstraints') |
118 |
if foo and len(foo.childNodes[0].data) \ |
if foo and len(foo.childNodes[0].data) \ |
119 |
and lower(foo.childNodes[0].data) != 'none': |
and foo.childNodes[0].data.lower() != 'none': |
120 |
self.access = foo.childNodes[0].data |
self.access = foo.childNodes[0].data |
121 |
|
|
122 |
# Extract output format information |
foo = getElementByName(getElementByName( |
123 |
foo = getElementsByName( |
root, 'Capability'), 'Request') |
124 |
getElementByName(getElementByName(getElementByName( |
|
125 |
root, 'Capability'), 'Request'), 'GetMap'), 'Format') |
# Need to distinguish between Map and GetMap for v1.0 and v1.1 |
126 |
self.formats = map((lambda i: i.childNodes[0].data), foo) |
bar = getElementByName(foo, 'GetMap') |
127 |
|
if bar: |
128 |
|
# WMS 1.1 |
129 |
|
foo = getElementsByName(bar, 'Format') |
130 |
|
self.formats = map((lambda i: i.childNodes[0].data), foo) |
131 |
|
else: |
132 |
|
# WMS 1.0 |
133 |
|
foo = getElementByName(getElementByName( |
134 |
|
foo, 'Map'), 'Format') |
135 |
|
for node in foo.childNodes: |
136 |
|
if node.nodeType == Node.ELEMENT_NODE: |
137 |
|
try: |
138 |
|
self.formats.append(node.nodeName) |
139 |
|
except AttributeError: |
140 |
|
self.formats = [node.nodeName] |
141 |
|
|
142 |
# Extract layer names |
# Extract layer names |
143 |
self.layers = [] |
self.layers = [] |
170 |
foo = getElementByName(top, 'Title') |
foo = getElementByName(top, 'Title') |
171 |
if foo and len(foo.childNodes[0].data): |
if foo and len(foo.childNodes[0].data): |
172 |
self.layers[index]['title'] = foo.childNodes[0].data |
self.layers[index]['title'] = foo.childNodes[0].data |
173 |
|
else: |
174 |
|
# A <Title> is required for each layer, <name> is optional |
175 |
|
# See OGC 01-068r3, 7.1.4.5.1 and 7.1.4.5.2 |
176 |
|
self.error.append(_("No title found for layer #%d") % index) |
177 |
|
|
178 |
foo = getElementByName(top, 'Name') |
foo = getElementByName(top, 'Name') |
179 |
if foo and len(foo.childNodes[0].data): |
if foo and len(foo.childNodes[0].data): |
185 |
if srs[0:5] == 'EPSG:': |
if srs[0:5] == 'EPSG:': |
186 |
srs = srs[5:] |
srs = srs[5:] |
187 |
try: |
try: |
188 |
self.layers[index]['srs'].append(srs) |
int(srs) |
189 |
except KeyError: |
try: |
190 |
self.layers[index]['srs'] = [srs] |
self.layers[index]['srs'].append(srs) |
191 |
|
except KeyError: |
192 |
|
self.layers[index]['srs'] = [srs] |
193 |
|
except ValueError: |
194 |
|
if srs[0:4].upper() == 'AUTO' \ |
195 |
|
or srs[0:4].upper() == 'NONE': |
196 |
|
try: |
197 |
|
self.layers[index]['_srs_'].append(srs) |
198 |
|
except KeyError: |
199 |
|
self.layers[index]['_srs_'] = [srs] |
200 |
|
else: |
201 |
|
self.error.append(_("SRS '%s' is not numerical and not" |
202 |
|
" AUTO/NONE in layer '%s'") \ |
203 |
|
% (srs, self.layers[index]['title'])) |
204 |
|
|
205 |
foo = getElementByName(top, 'LatLonBoundingBox') |
foo = getElementByName(top, 'LatLonBoundingBox') |
206 |
if foo is not None: |
if foo is not None: |
473 |
if srs in pivot['bbox']: |
if srs in pivot['bbox']: |
474 |
return pivot['bbox'][srs] |
return pivot['bbox'][srs] |
475 |
|
|
476 |
|
# No matching BBox found, let's see if it was EPSG:4326 |
477 |
|
if srs == '4326': |
478 |
|
return self.getLayerLatLonBBox(name) |
479 |
|
|
480 |
return None |
return None |
481 |
|
|
482 |
|
|
521 |
|
|
522 |
import os |
import os |
523 |
|
|
524 |
|
sample = "test/sample.xml" |
525 |
try: |
try: |
526 |
f = open("test/sample.xml", "r") |
f = open(sample, "r") |
527 |
except IOError: |
except IOError: |
528 |
try: |
try: |
529 |
f = open(os.path.dirname(__file__) + "/test/sample.xml", "r") |
f = open(os.path.dirname(__file__) + "/" + sample, "r") |
530 |
except IOError: |
except IOError: |
531 |
print "Cannot open sample.xml for reading" |
print "Cannot open %s for reading" % sample |
532 |
|
|
533 |
if f is not None: |
if f is not None: |
534 |
sample = f.read(); |
sample = f.read(); |