Changeset 4278 for cows


Ignore:
Timestamp:
03/10/08 13:41:37 (11 years ago)
Author:
domlowe
Message:

More integration of WFS into cows. Layers now represent feature types, not instances.

Location:
cows/trunk/cows
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cows/trunk/cows/model/wfs.py

    r4274 r4278  
    1313    def __init__(self, **kw): 
    1414        super(WfsFeatureSummary, self).__init__(**kw) 
    15  
    16 #TODO    
    17 #Name 
    18 #Abstract 
    19 #Title 
    20 #ows:Keywords, Keyword 
    21 #DefaultSRS 
    22 #OutputFormats, Format 
    23 #ows:WGS84BoundingBox 
     15        #TODO: flesh out feature summary 
     16        #Name 
     17        #Abstract 
     18        #Title 
     19        #ows:Keywords, Keyword 
     20        #DefaultSRS 
     21        #OutputFormats, Format 
     22        #ows:WGS84BoundingBox 
     23         
     24         
     25         
     26         
     27         
  • cows/trunk/cows/pylons/wfs_controller.py

    r4274 r4278  
    3232    """ 
    3333    layerMapper = None 
    34     #layers = {}     
    35     _pilImageFormats = { 
    36         'image/png': 'PNG', 
    37         'image/jpg': 'JPEG', 
    38         'image/gif': 'GIF', 
    39         'image/tiff': 'TIFF' 
    40         } 
    4134    _layerSlabCache = {} 
    4235 
     
    6053 
    6154        """ 
    62         #self.updateSequence = "hello" 
    6355        print "loading layers" 
    64         #print self.layers 
    65         self.layers = self.layerMapper.map(**kwargs) 
     56        self.layers, self.featureinstances = self.layerMapper.map(**kwargs) 
    6657     
    6758        #------------------------------------------------------------------------- 
     
    10192         
    10293        #create dictionary of form {featuretype: [layer, layer, ...], {featuretype2: [layer, layer, ...]} 
    103         for layerName, layer in self.layers.items(): 
    104             log.info(dir(layer)) 
    105             if type(layer._feature) not in ftlist: 
    106                 ftlist[type(layer._feature)] = [layer] 
    107             else: 
    108                 ftlist[type(layer._feature)].append(layer) 
    109         log.info('FeatureTypeList: %s'%ftlist) 
    110          
     94#        for layerName, layer in self.layers.items(): 
     95#            log.info(dir(layer)) 
     96#            if type(layer._feature) not in ftlist: 
     97#                ftlist[type(layer._feature)] = [layer] 
     98#            else: 
     99#                ftlist[type(layer._feature)].append(layer) 
     100#        log.info('FeatureTypeList: %s'%ftlist) 
     101#         
    111102         
    112103        for layerName, layer in self.layers.items(): 
    113104            log.info('Loading layer %s' % layerName) 
    114             log.info('feature type %s'%layer._feature) 
     105#            log.info('feature type %s'%layer._feature) 
    115106 
    116107            wgs84BBox = WGS84BoundingBox(layer.wgs84BBox[:2], 
    117108                                         layer.wgs84BBox[2:]) 
     109#            wgs84BBox = WGS84BoundingBox(['10','20'],['20','40']) 
    118110             
    119111            ds = WfsFeatureSummary(identifier=layerName, 
  • cows/trunk/cows/service/imps/csmlbackend/csmlcommon.py

    r4272 r4278  
    4545 
    4646 
    47  
    48  
    4947class CSMLConnector(object): 
    5048    """ Contains common methods for CSML backend used across all WXS services """     
     
    8684            d.parse(x)                          
    8785        return d 
     86     
     87class BboxAggregator(object): 
     88    """ class to handle aggregations of bounding boxes (in the same crs)""" 
     89    def __init__(self, initialbbox): 
     90        """  
     91        @ivar wgs84bbox: bounding box tuple (llx, lly, urx, ury) """ 
     92        self.bbox=initialbbox 
     93         
     94    def aggregate(self, newbbox): 
     95        """ 
     96        @ivar newbbox: bounding box tuple (llx, lly, urx, ury) to compare against current bbox.  
     97        @return: aggregated bbox tuple, (llx, lly, urx, ury) 
     98        """ 
     99        log.debug('Comparing new bbox %s with old bbox %s'%(newbbox, self.bbox)) 
     100        #compare new box with old. 
     101        if newbbox[0] < self.bbox[0]: 
     102            self.bbox[0]=newbbox[0] 
     103        if newbbox[1] < self.bbox[1]: 
     104            self.bbox[1]=newbbox[1] 
     105        if newbbox[2] > self.bbox[2]: 
     106            self.bbox[2]=newbbox[2] 
     107        if newbbox[3] > self.bbox[3]: 
     108            self.bbox[3]=newbbox[3] 
     109        return self.bbox 
  • cows/trunk/cows/service/imps/csmlbackend/wfs_csmllayer.py

    r4274 r4278  
    44""" 
    55 
    6 from cows.service.imps.csmlbackend.csmlcommon import CSMLLayerMapper, CSMLConnector 
     6from cows.service.imps.csmlbackend.csmlcommon import CSMLLayerMapper, CSMLConnector, BboxAggregator 
    77from cows.service.wfs_iface import IwfsLayer 
    88import csml 
     
    1414    """ 
    1515    Map keyword arguments to a collection of layers. 
    16     Supports the retrieval of sets of layers according to arbitary 
     16    Supports the retrieval of sets of layers according to arbitrary 
    1717    keyword/value pairs. 
    1818    Implements  ILayerMapper  
     19     
     20    WFS differs from WMS/WCS in that the 'layers' are feature types, not instances. 
     21    So the CSMLwfsLayerMapper map method returns both a map of feature types and a map 
     22    of feature instances as both are needed for the GetFeature method to work. 
    1923     
    2024    """ 
    2125    def __init__(self): 
    2226        super(CSMLwfsLayerMapper, self).__init__() 
     27        self.featureinstancecache={} 
    2328     
    2429 
     
    3439        if fileoruri in self.layermapcache.keys(): 
    3540            #we've accessed this layer map before, get it from the cache dictionary 
    36             return self.layermapcache[fileoruri] 
     41            return self.layermapcache[fileoruri], self.featureinstancecache[fileoruri] 
    3742          
    3843        ds = self.connector.get_csml_doc(fileoruri) 
    39         layermap={} 
     44         
     45        #The WFS differs from WMS & WCS in that the contents layer is a list of  
     46        #feature *types* not *instances*. However a record of instances is also  
     47        #needed to fulfil GetFeature requests: 
     48        featureinstances={} #feature instances         
     49        layermap={} #feature types        
     50        bboxAggregators={}#for aggregations of bounding boxes. 
     51               
     52        #FIXME: remove feature instances? 
    4053        for feature in csml.csmllibs.csmlextra.listify(ds.featureCollection.featureMembers): 
    4154            title, abstract=self._getInfo(feature) 
    42             layermap[feature.id]=CSMLwfsLayer(title,abstract, feature) 
     55            featureinstances[feature.id]=CSMLFeatureInstance(title, abstract, feature)       
     56            #TODO: convert layermap to hold TYPES 
     57         
     58        for id, instance in featureinstances.iteritems(): 
     59            print 'this is a feature %s'%type(instance._feature) 
     60            ftype='csml:' + instance.featuretype 
     61            if ftype not in layermap.keys(): 
     62                layermap[ftype]=CSMLwfsLayer(ftype, instance.wgs84BBox) 
     63                #instantiate an aggregator to compare future bounding boxes with. 
     64                bboxAggregators[ftype]= BboxAggregator(instance.wgs84BBox)                
     65            else: 
     66                #the featuretype has already been stored in the dictionary. 
     67                #but, the bounding box may need changing to accommodate this new feature instance. 
     68                log.debug('Checking bbox for feature id: %s and title: %s'%(instance._feature.id, instance.title)) 
     69                aggregator=bboxAggregators[ftype] 
     70                aggregator.aggregate(instance.wgs84BBox) 
     71                layermap[ftype]=CSMLwfsLayer(ftype, aggregator.bbox) 
     72               
     73 
    4374        if len(layermap) > 0: 
     75            #cache results 
    4476            self.layermapcache[fileoruri]=layermap 
    45             return layermap 
     77            self.featureinstancecache[fileoruri]=featureinstances 
     78            return layermap, featureinstances 
    4679        else: 
    4780            raise ValueError 
    4881 
    49  
    50 class CSMLwfsLayer(IwfsLayer): 
    51     """ representing a WFS Feature (termed layer here). Implements IwfsLayer 
    52     @ivar title: The layer title.  As seen in the Capabilities document. 
    53     @ivar abstract:  Abstract as seen in the Capabilities document. 
    54     """ 
     82class CSMLFeatureInstance(object): 
    5583    def __init__(self, title, abstract, feature): 
     84        """ representing a CSML Feature Instance  
     85        @ivar title: The title of the feature instance 
     86        @ivar abstract: The abstract of the feature instance 
     87        @ivar feature: the csml feature instance object  
     88         """ 
    5689        self.title=title 
    5790        self.abstract=abstract 
    5891        self._feature=feature 
     92        self.featuretype=self._feature.__class__.__name__ 
    5993        bb= self._feature.getCSMLBoundingBox().getBox() 
    6094        #convert 0 - 360 to -180, 180 as per common WMS convention 
     
    6296            bb[0], bb[2]=-180, 180 
    6397        self.wgs84BBox = bb 
     98         
     99       
     100class CSMLwfsLayer(IwfsLayer): 
     101    """ representing a WFS FeatureType (termed layer here). Implements IwfsLayer 
     102    @ivar featuretype: The namespaced name of the feature type, e.g. csml:PointSeriesFeature 
     103     
     104    """ 
     105    def __init__(self, featuretype, wgs84bb): 
     106        self.type=featuretype 
     107        #Have to hard code some definitions for CSML feature types to  
     108        #use in the capabilities document as they don't exist anywhere else. 
     109        #Hardcoding is okay as this is a CSML specific interface, so will only ever deal 
     110        #with CSML feature types. 
     111        self.wgs84BBox=wgs84bb         
     112        if self.type=='csml:GridSeriesFeature': 
     113            self.title='GridSeriesFeature as defined in Climate Science Modelling Language.' 
     114            self.abstract='The CSML GridSeriesFeature is used to represent 4D gridded data such as atmospheric model output.' 
     115        elif self.type=='csml:PointSeriesFeature': 
     116            self.title='PointSeriesFeature as defined in Climate Science Modelling Language.' 
     117            self.abstract='The CSML PointSeriesFeature represents a time series of measurements at a single point in space.' 
     118        #TODO: definitions for all feature types. 
     119         
     120         
     121 
  • cows/trunk/cows/service/imps/csmlbackend/wms_csmllayer.py

    r4274 r4278  
    2727    """ 
    2828    Map keyword arguments to a collection of layers. 
    29     Supports the retrieval of sets of layers according to arbitary 
     29    Supports the retrieval of sets of layers according to arbitrary 
    3030    keyword/value pairs. 
    3131    Implements  ILayerMapper  
     
    292292    @ivar bbox: The bounding box as a 4-tuple. 
    293293    """ 
    294      
     294 
    295295    def __init__(self, netcdf, layer, crs, dimValues, renderOpts, bbox): 
    296296        self._netcdf=netcdf 
Note: See TracChangeset for help on using the changeset viewer.