/[thuban]/branches/WIP-pyshapelib-bramz/Extensions/wms/parser.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Extensions/wms/parser.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2144 by joey, Tue Mar 30 17:25:20 2004 UTC revision 2173 by joey, Tue Apr 13 19:28:05 2004 UTC
# Line 49  __version__ = "$Revision$" Line 49  __version__ = "$Revision$"
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.
# Line 68  class WMSCapabilitiesParser: Line 71  class WMSCapabilitiesParser:
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):
# Line 78  class WMSCapabilitiesParser: Line 82  class WMSCapabilitiesParser:
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):
# Line 89  class WMSCapabilitiesParser: Line 93  class WMSCapabilitiesParser:
93          Information should only be retrieved with the respective          Information should only be retrieved with the respective
94          get*() methods.          get*() methods.
95          """          """
96          root = xml.dom.minidom.parseString(data).documentElement          xml_dom = xml.dom.minidom.parseString(data)
97            root = xml_dom.documentElement
98    
99          # Extract the title          # Extract the title
100          foo = getElementByName(getElementByName(root, 'Service'), 'Title')          foo = getElementByName(getElementByName(root, 'Service'), 'Title')
# Line 104  class WMSCapabilitiesParser: Line 109  class WMSCapabilitiesParser:
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 = []
144          self.peekLayers(getElementByName(getElementByName(          self.peekLayers(getElementByName(getElementByName(
145              root, 'Capability'), 'Layer'), -1)              root, 'Capability'), 'Layer'), -1)
146    
147            xml_dom.unlink()
148    
149    
150      def peekLayers(self, top, parent):      def peekLayers(self, top, parent):
151          """          """
# Line 149  class WMSCapabilitiesParser: Line 170  class WMSCapabilitiesParser:
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):
# Line 160  class WMSCapabilitiesParser: Line 185  class WMSCapabilitiesParser:
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:
# Line 183  class WMSCapabilitiesParser: Line 221  class WMSCapabilitiesParser:
221                  self.layers[index]['bbox'][srs][corner] \                  self.layers[index]['bbox'][srs][corner] \
222                      = foo.attributes.get(corner).nodeValue                      = foo.attributes.get(corner).nodeValue
223                            
         # Check for integrity  
         self.checkLayerSRS(index)  
   
224          # Traverse subsidiary layers          # Traverse subsidiary layers
225          sublayer = getElementsByName(top, 'Layer')          sublayer = getElementsByName(top, 'Layer')
226          for l in sublayer:          for l in sublayer:
227              self.peekLayers(l, index)              self.peekLayers(l, index)
228    
229    
     def checkLayerSRS(self, index):  
         """  
         Checks the integrity of the underlying XML data.  
   
         This is done by comparing the <SRS> elements with the  
         calculated list from the BoundingBox elements.  
   
         index -- position in the layers array to check  
         """  
   
         pivot = index  
         calculated = []  
         while pivot != -1:  
             if 'bbox' in self.layers[pivot]:  
                 for srs in self.layers[pivot]['bbox'].keys():  
                     if srs not in calculated:  
                         calculated.append(srs)  
             pivot = self.layers[pivot]['parent']  
   
         pivot = index  
         specified = []  
         while pivot != -1:  
             if 'srs' in self.layers[pivot]:  
                 for srs in self.layers[pivot]['srs']:  
                     if srs not in specified:  
                         specified.append(srs)  
             pivot = self.layers[pivot]['parent']  
   
         equal = True  
         # Check for same number of elements  
         if len(calculated) != len(specified):  
             equal = False  
   
         # Loop through all elements for existance  
         for elm in calculated:  
             if elm not in specified:  
                 equal = False  
   
         if not equal:  
             if self.srs_discrepancies is None:  
                 self.srs_discrepancies = []  
             if 'name' in self.layers[index]:  
                 id = "name:%s" % self.layers[index]['name']  
             else:  
                 id = "title:%s" % self.layers[index]['title']  
             self.srs_discrepancies.append(id)  
   
   
230      def getTitle(self):      def getTitle(self):
231          """          """
232          Returns the main title of the WMS object.          Returns the main title of the WMS object.
# Line 486  class WMSCapabilitiesParser: Line 473  class WMSCapabilitiesParser:
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    
# Line 530  if __name__ == "__main__": Line 521  if __name__ == "__main__":
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();

Legend:
Removed from v.2144  
changed lines
  Added in v.2173

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26