/[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 2439 by joey, Thu Dec 9 10:37:44 2004 UTC
# Line 40  class WMSCapabilitiesParser: Line 40  class WMSCapabilitiesParser:
40      getLayerBBox(layer, srs)      getLayerBBox(layer, srs)
41    
42      isQueryable(layer)      isQueryable(layer)
   
     get_srs_discrepancies()  
43  """  """
44    
45  __version__ = "$Revision$"  __version__ = "$Revision$"
# Line 49  __version__ = "$Revision$" Line 47  __version__ = "$Revision$"
47  # $Id$  # $Id$
48    
49  import xml.dom.minidom  import xml.dom.minidom
50    from xml.dom import Node
51    
52  from domutils import getElementsByName, getElementByName  from domutils import getElementsByName, getElementByName
53    
54    from Thuban import _
55    
56  class WMSCapabilitiesParser:  class WMSCapabilitiesParser:
57      """      """
58      Thuban class to parse capabilities supplied as large string.      Thuban class to parse capabilities supplied as large string.
# Line 67  class WMSCapabilitiesParser: Line 68  class WMSCapabilitiesParser:
68      fees = None      fees = None
69      access = None      access = None
70      formats = None      formats = None
71      srs_discrepancies = None      error = None
72    
73    
74      def __init__(self):      def __init__(self):
# Line 78  class WMSCapabilitiesParser: Line 79  class WMSCapabilitiesParser:
79          # Note that we must not initialise internal variables of the          # Note that we must not initialise internal variables of the
80          # class in a mutable way or it will be shared among all          # class in a mutable way or it will be shared among all
81          # instances.  None is immutable, [] is not.          # instances.  None is immutable, [] is not.
82          layers = []          self.error = []
83    
84    
85      def grok(self, data):      def grok(self, data):
# Line 89  class WMSCapabilitiesParser: Line 90  class WMSCapabilitiesParser:
90          Information should only be retrieved with the respective          Information should only be retrieved with the respective
91          get*() methods.          get*() methods.
92          """          """
93          root = xml.dom.minidom.parseString(data).documentElement          xml_dom = xml.dom.minidom.parseString(data)
94            root = xml_dom.documentElement
95    
96          # Extract the title          # Extract the title
97          foo = getElementByName(getElementByName(root, 'Service'), 'Title')          foo = getElementByName(getElementByName(root, 'Service'), 'Title')
# Line 104  class WMSCapabilitiesParser: Line 106  class WMSCapabilitiesParser:
106          # Extract fees information          # Extract fees information
107          foo = getElementByName(getElementByName(root, 'Service'), 'Fees')          foo = getElementByName(getElementByName(root, 'Service'), 'Fees')
108          if foo and len(foo.childNodes[0].data) \          if foo and len(foo.childNodes[0].data) \
109                 and lower(foo.childNodes[0].data) != 'none':                 and foo.childNodes[0].data.lower() != 'none':
110              self.fees = foo.childNodes[0].data              self.fees = foo.childNodes[0].data
111                    
112          # Extract access information          # Extract access information
113          foo = getElementByName(getElementByName(root, 'Service'),          foo = getElementByName(getElementByName(root, 'Service'),
114                                 'AccessConstraints')                                 'AccessConstraints')
115          if foo and len(foo.childNodes[0].data) \          if foo and len(foo.childNodes[0].data) \
116                 and lower(foo.childNodes[0].data) != 'none':                 and foo.childNodes[0].data.lower() != 'none':
117              self.access = foo.childNodes[0].data              self.access = foo.childNodes[0].data
118                    
119          # Extract output format information          foo = getElementByName(getElementByName(
120          foo = getElementsByName(              root, 'Capability'), 'Request')
121              getElementByName(getElementByName(getElementByName(  
122              root, 'Capability'), 'Request'), 'GetMap'), 'Format')          # Need to distinguish between Map and GetMap for v1.0 and v1.1
123          self.formats = map((lambda i: i.childNodes[0].data), foo)          bar = getElementByName(foo, 'GetMap')
124            if bar:
125                # WMS 1.1
126                foo = getElementsByName(bar, 'Format')
127                self.formats = map((lambda i: i.childNodes[0].data), foo)
128            else:
129                # WMS 1.0
130                foo = getElementByName(getElementByName(
131                    foo, 'Map'), 'Format')
132                for node in foo.childNodes:
133                    if node.nodeType == Node.ELEMENT_NODE:
134                        try:
135                            self.formats.append(node.nodeName)
136                        except AttributeError:
137                            self.formats = [node.nodeName]
138    
139          # Extract layer names          # Extract layer names
140          self.layers = []          self.layers = []
141          self.peekLayers(getElementByName(getElementByName(          self.peekLayers(getElementByName(getElementByName(
142              root, 'Capability'), 'Layer'), -1)              root, 'Capability'), 'Layer'), -1)
143    
144            xml_dom.unlink()
145    
146    
147      def peekLayers(self, top, parent):      def peekLayers(self, top, parent):
148          """          """
# Line 149  class WMSCapabilitiesParser: Line 167  class WMSCapabilitiesParser:
167          foo = getElementByName(top, 'Title')          foo = getElementByName(top, 'Title')
168          if foo and len(foo.childNodes[0].data):          if foo and len(foo.childNodes[0].data):
169              self.layers[index]['title'] = foo.childNodes[0].data              self.layers[index]['title'] = foo.childNodes[0].data
170            else:
171                # A <Title> is required for each layer, <name> is optional
172                # See OGC 01-068r3, 7.1.4.5.1 and 7.1.4.5.2
173                self.error.append(_("No title found for layer #%d") % index)
174    
175          foo = getElementByName(top, 'Name')          foo = getElementByName(top, 'Name')
176          if foo and len(foo.childNodes[0].data):          if foo and len(foo.childNodes[0].data):
# Line 160  class WMSCapabilitiesParser: Line 182  class WMSCapabilitiesParser:
182                  if srs[0:5] == 'EPSG:':                  if srs[0:5] == 'EPSG:':
183                      srs = srs[5:]                      srs = srs[5:]
184                  try:                  try:
185                      self.layers[index]['srs'].append(srs)                      int(srs)
186                  except KeyError:                      try:
187                      self.layers[index]['srs'] = [srs]                          self.layers[index]['srs'].append(srs)
188                        except KeyError:
189                            self.layers[index]['srs'] = [srs]
190                    except ValueError:
191                        if srs[0:4].upper() == 'AUTO' \
192                               or srs[0:4].upper() == 'NONE':
193                            try:
194                                self.layers[index]['_srs_'].append(srs)
195                            except KeyError:
196                                self.layers[index]['_srs_'] = [srs]
197                        else:
198                            self.error.append(_("SRS '%s' is not numerical and not"
199                                                " AUTO/NONE in layer '%s'") \
200                                              % (srs, self.layers[index]['title']))
201    
202          foo = getElementByName(top, 'LatLonBoundingBox')          foo = getElementByName(top, 'LatLonBoundingBox')
203          if foo is not None:          if foo is not None:
# Line 183  class WMSCapabilitiesParser: Line 218  class WMSCapabilitiesParser:
218                  self.layers[index]['bbox'][srs][corner] \                  self.layers[index]['bbox'][srs][corner] \
219                      = foo.attributes.get(corner).nodeValue                      = foo.attributes.get(corner).nodeValue
220                            
         # Check for integrity  
         self.checkLayerSRS(index)  
   
221          # Traverse subsidiary layers          # Traverse subsidiary layers
222          sublayer = getElementsByName(top, 'Layer')          sublayer = getElementsByName(top, 'Layer')
223          for l in sublayer:          for l in sublayer:
224              self.peekLayers(l, index)              self.peekLayers(l, index)
225    
226    
     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)  
   
   
227      def getTitle(self):      def getTitle(self):
228          """          """
229          Returns the main title of the WMS object.          Returns the main title of the WMS object.
# Line 486  class WMSCapabilitiesParser: Line 470  class WMSCapabilitiesParser:
470                              if srs in pivot['bbox']:                              if srs in pivot['bbox']:
471                                  return pivot['bbox'][srs]                                  return pivot['bbox'][srs]
472    
473            # No matching BBox found, let's see if it was EPSG:4326
474            if srs == '4326':
475                return self.getLayerLatLonBBox(name)
476    
477          return None          return None
478    
479    
# Line 516  class WMSCapabilitiesParser: Line 504  class WMSCapabilitiesParser:
504          return 0          return 0
505    
506    
     def get_srs_discrepancies(self):  
         """  
         Returns a list of layer identifications where the denoted SRS  
         values differ from the calculated ones through BoundingBox  
         elements.  
         """  
         return self.srs_discrepancies  
   
507    
508  if __name__ == "__main__":  if __name__ == "__main__":
509      print "This module cannot be executed standalone."      print "This module cannot be executed standalone."
510    
511      import os      import os
512    
513        sample = "test/sample.xml"
514      try:      try:
515          f = open("test/sample.xml", "r")          f = open(sample, "r")
516      except IOError:      except IOError:
517          try:          try:
518              f = open(os.path.dirname(__file__) + "/test/sample.xml", "r")              f = open(os.path.dirname(__file__) + "/" + sample, "r")
519          except IOError:          except IOError:
520              print "Cannot open sample.xml for reading"              print "Cannot open %s for reading" % sample
521    
522      if f is not None:      if f is not None:
523          sample = f.read();          sample = f.read();

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26