/[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 2133 by joey, Wed Mar 24 19:31:54 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 385  class WMSCapabilitiesParser: Line 372  class WMSCapabilitiesParser:
372          - Layers may optionally add to the global SRS list, or to the          - Layers may optionally add to the global SRS list, or to the
373            list inherited from a parent layer.            list inherited from a parent layer.
374    
375            - A server which has the ability to transform data to
376              different SRSes may choose not to provide an explicit
377              BoundingBox for every possible SRS available for each Layer.
378              Thus the list of <SRS> elements are authoritative.
379    
380          This implementation returns the list of SRS for the given          This implementation returns the list of SRS for the given
381          layer, calculated by looking at BoundingBoxes defined in the          layer, calculated by looking at BoundingBoxes defined in the
382          named layer and all layers higher in the hierarchy up to the          named layer and all layers higher in the hierarchy up to the
# Line 400  class WMSCapabilitiesParser: Line 392  class WMSCapabilitiesParser:
392    
393          result = []          result = []
394          while pivot != -1:          while pivot != -1:
395              if 'bbox' in self.layers[pivot]:              if 'srs' in self.layers[pivot]:
396                  for srs in self.layers[pivot]['bbox'].keys():                  for srs in self.layers[pivot]['srs']:
397                      if srs not in result:                      if srs not in result:
398                          result.append(srs)                          result.append(srs)
399              pivot = self.layers[pivot]['parent']              pivot = self.layers[pivot]['parent']
# Line 481  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 525  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.2133  
changed lines
  Added in v.2173

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26