Changeset 981

Show
Ignore:
Timestamp:
12/09/07 14:11:33
Author:
seang
Message:

Support nested layers and SRS lists (#138)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • OWSLib/trunk/owslib/wms.py

    r621 r981  
    164164        self.service = self._root.find('Service/Name').text 
    165165        self.title = self._root.find('Service/Title').text 
    166         self.abstract = self._root.find('Service/Abstract').text 
     166        abstract = self._root.find('Service/Abstract') 
     167        if abstract is not None: 
     168                self.abstract = self._root.find('Service/Abstract').text 
     169        else: 
     170                self.abstract = None 
    167171        self.link = self._root.find('Service/OnlineResource').attrib.get('{http://www.w3.org/1999/xlink}href', '') 
    168172         
     
    178182        # contents: our assumption is that services use a top-level layer 
    179183        # as a metadata organizer, nothing more. 
    180         self.contents = [] 
    181         top = self._root.find('Capability/Layer') 
    182         for elem in self._root.findall('Capability/Layer/Layer'): 
    183             self.contents.append(ContentMetadata(elem, top)) 
     184        caps = self._root.find('Capability') 
     185        self.layers = [] 
     186       for elem in caps.findall('Layer'): 
     187               self.layers.append(ContentMetadata(elem)) 
    184188 
    185189        # keywords 
     
    187191         
    188192        # contact person 
    189         self.provider = ContactMetadata(self._root.find('Service/ContactInformation')) 
    190          
     193        contact = self._root.find('Service/ContactInformation') 
     194        if contact is not None: 
     195            self.provider = ContactMetadata(contact) 
     196        else: 
     197            self.provider = None 
     198 
     199    @property 
     200    def contents(self): 
     201        """backwards compatible flat list of contents""" 
     202        return list(self._rcontents(self)) 
     203    def _rcontents(self, layer): 
     204        for l in layer.layers: 
     205            yield l 
     206            for l in self._rcontents(l): 
     207                yield l 
     208             
    191209    def getContentByName(self, name): 
    192210        """Return a named content item.""" 
     
    212230 
    213231class ContentMetadata: 
    214     """Abstraction for WMS metadata. 
    215      
    216     Implements IMetadata. 
    217     """ 
    218  
    219     def __init__(self, elem, parent): 
    220         """Initialize.""" 
    221         self.name = elem.find('Name').text 
    222         self.title = elem.find('Title').text 
    223         # bboxes 
    224         self.boundingBox = None 
    225         b = elem.find('BoundingBox') 
    226         if b is not None: 
    227             self.boundingBox = (float(b.attrib['minx']),float(b.attrib['miny']), 
    228                     float(b.attrib['maxx']), float(b.attrib['maxy']), 
    229                     b.attrib['SRS']) 
    230         else: 
    231             b = parent.find('BoundingBox') 
    232             if b is not None: 
    233                 self.boundingBox = ( 
    234                         float(b.attrib['minx']), float(b.attrib['miny']), 
    235                         float(b.attrib['maxx']), float(b.attrib['maxy']), 
    236                         b.attrib['SRS']) 
    237         self.boundingBoxWGS84 = None 
    238         b = elem.find('LatLonBoundingBox') 
    239         if b is not None: 
    240             self.boundingBoxWGS84 = ( 
    241                     float(b.attrib['minx']),float(b.attrib['miny']), 
    242                     float(b.attrib['maxx']), float(b.attrib['maxy']), 
    243                     ) 
    244         else: 
    245             b = parent.find('LatLonBoundingBox') 
    246             if b is not None: 
    247                 self.boundingBoxWGS84 = ( 
    248                         float(b.attrib['minx']), float(b.attrib['miny']), 
    249                         float(b.attrib['maxx']), float(b.attrib['maxy']), 
    250                         ) 
    251         # crs options 
    252         self.crsOptions = [srs.text for srs in parent.findall('SRS')] 
    253  
    254         # styles 
    255         self.styles = dict([(s.find('Name').text,  
    256                              {'title': s.find('Title').text}) \ 
    257                              for s in elem.findall('Style')] 
    258                              ) 
    259  
     232        """ 
     233        Abstraction for WMS metadata. 
     234 
     235        Implements IMetadata. 
     236        """ 
     237        def __init__(self, elem, parent=None): 
     238                self.parent = parent 
     239                if elem.tag != 'Layer': 
     240                        raise ValueError('%s should be a Layer' % (elem,)) 
     241                for key in ('Name', 'Title', 'Attribution'): 
     242                        val = elem.find(key) 
     243                        if val is not None: 
     244                                setattr(self, key.lower(), val.text.strip()) 
     245                        else: 
     246                                setattr(self, key.lower(), None) 
     247 
     248                # bboxes 
     249                b = elem.find('BoundingBox') 
     250                if b is not None: 
     251                        self.boundingBox = ( 
     252                                float(b.attrib['minx']), 
     253                                float(b.attrib['miny']), 
     254                                float(b.attrib['maxx']), 
     255                                float(b.attrib['maxy']), 
     256                                b.attrib['SRS'], 
     257                        ) 
     258                elif self.parent: 
     259                        self.boundingBox = self.parent.boundingBox 
     260                else: 
     261                        self.boundingBox = None 
     262 
     263                b = elem.find('LatLonBoundingBox') 
     264                if b is not None: 
     265                        self.boundingBoxWGS84 = ( 
     266                                float(b.attrib['minx']), 
     267                                float(b.attrib['miny']), 
     268                                float(b.attrib['maxx']), 
     269                                float(b.attrib['maxy']), 
     270                        ) 
     271                elif self.parent: 
     272                        self.boundingBoxWGS84 = self.parent.boundingBoxWGS84 
     273                else: 
     274                        self.boundingBoxWGS84 = None 
     275 
     276                # crs options 
     277                self.crsOptions = [] 
     278                if elem.find('SRS') is not None: 
     279                        ## some servers found in the wild use a single SRS 
     280                        ## tag containing a whitespace separated list of SRIDs 
     281                        ## instead of several SRS tags. hence the inner loop 
     282                        for srslist in map(lambda x: x.text, elem.findall('SRS')): 
     283                                for srs in srslist.split(): 
     284                                        self.crsOptions.append(srs) 
     285                elif self.parent: 
     286                        self.crsOptions = self.parent.crsOptions 
     287                else: 
     288                        raise ValueError('%s no SRS available!?' % (elem,)) 
     289 
     290                # styles 
     291                self.styles = {} 
     292                for s in elem.findall('Style'): 
     293                        name = s.find('Name') 
     294                        title = s.find('Title') 
     295                        if name is None or title is None: 
     296                                raise ValueError('%s missing name or title' % (s,)) 
     297                        self.styles[name.text] = { 'title' : title.text } 
     298 
     299                self.layers = [] 
     300                for child in elem.findall('Layer'): 
     301                        self.layers.append(ContentMetadata(child, self)) 
     302 
     303        def __str__(self): 
     304                return 'Layer Name: %s Title: %s' % (self.name, self.title) 
    260305 
    261306class OperationMetadata: