Changeset 6393 for cows


Ignore:
Timestamp:
25/01/10 10:23:42 (9 years ago)
Author:
pnorton
Message:

First attempt at trying to implement a folder structure for the csml files.

Location:
cows/trunk
Files:
1 added
1 deleted
10 edited
1 copied

Legend:

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

    r5629 r6393  
    4646    """ 
    4747    def __init__(self, CRSs=[], styles=[''], dimensions={}, attribution=None, authorityURLs=[], 
    48                  dataURLs=[], featureListURLs=[], metadataURLs=[], 
     48                 dataURLs=[], featureListURLs=[], metadataURLs=[], children=None, 
    4949                 minScaleDenominator=None, maxScaleDenominator=None, 
    5050                 queryable=False, **kw): 
     
    6262        self.queryable = queryable 
    6363        self.metadataURLs = metadataURLs 
     64         
     65        if children is None:  
     66            self.children = [] 
     67        else: 
     68            self.children = children 
    6469 
    6570class Style(object): 
  • cows/trunk/cows/pylons/templates/wms_capabilities_1_3_0.xml

    r5629 r6393  
    7676 
    7777  <Layer py:def="markupLayer(ds)" queryable="${int(ds.queryable)}"> 
    78     <Name py:content="ds.identifier"/> 
     78   
     79    <py:if test="ds.identifier is not None"> 
     80            <Name py:content="ds.identifier"/> 
     81    </py:if> 
     82     
    7983    <Title py:content="ds.titles[0]"/> 
    8084    <Abstract py:if="len(ds.abstracts)>0" py:content="ds.abstracts[0]"/> 
    81     <CRS py:for="crs in ds.CRSs" py:content="crs"/> 
    82     <?python exBBox = ds.wgs84BoundingBoxes[0] ?> 
    83     <EX_GeographicBoundingBox> 
    84       <westBoundLongitude py:content="exBBox.lowerCorner[0]"/> 
    85       <eastBoundLongitude py:content="exBBox.upperCorner[0]"/> 
    86       <southBoundLatitude py:content="exBBox.lowerCorner[1]"/> 
    87       <northBoundLatitude py:content="exBBox.upperCorner[1]"/> 
    88     </EX_GeographicBoundingBox> 
     85     
     86 
     87    <py:if test="ds.CRSs is not None">     
     88        <CRS py:for="crs in ds.CRSs" py:content="crs"/> 
     89    </py:if> 
     90     
     91    <py:if test="ds.wgs84BoundingBoxes[0] is not None"> 
     92     
     93            <?python exBBox = ds.wgs84BoundingBoxes[0] ?> 
     94            <EX_GeographicBoundingBox> 
     95              <westBoundLongitude py:content="exBBox.lowerCorner[0]"/> 
     96              <eastBoundLongitude py:content="exBBox.upperCorner[0]"/> 
     97              <southBoundLatitude py:content="exBBox.lowerCorner[1]"/> 
     98              <northBoundLatitude py:content="exBBox.upperCorner[1]"/> 
     99            </EX_GeographicBoundingBox> 
     100    </py:if> 
    89101 
    90102    <py:for each="bb in ds.boundingBoxes"> 
     
    105117    <!--!NOTE: this is an ad-hoc implementation not using the ows_common.model classes 
    106118         TODO: fixme --> 
    107     <!-- TODO ScaleHint --> 
     119    <!--!TODO ScaleHint --> 
    108120 
    109121    <Dimension py:for="d_n, d in ds.dimensions.iteritems()" 
     
    114126<!--! nearestValue="${int(d.nearestValue)}" --> 
    115127 
    116      
    117      
    118     <py:choose test="ds.styles"> 
    119  
    120         <py:when test="['']"> 
    121             <Style> 
    122                 <Name>default</Name> 
    123                 <Title>Default</Title> 
    124                 <LegendURL width="${ds.legendSize[0]}" height="${ds.legendSize[1]}"> 
    125                     <Format py:for="f in ds.legendFormats" py:content="f"/> 
    126                     <OnlineResource xlink:type="simple" xlink:href="${url_for(qualified=True, action='index')}?request=GetLegend&amp;layers=${ds.identifier}"/> 
    127                 </LegendURL> 
    128             </Style> 
    129         </py:when> 
    130  
    131         <py:otherwise> 
    132             <py:for each="s in ds.styles" py:if="getattr(ds, 'styles', None) != None"> 
    133                 ${markupStyle(s)} 
    134             </py:for> 
    135         </py:otherwise> 
    136  
    137     </py:choose> 
    138      
    139     <py:if test="len(ds.metadataURLs) > 0"> 
    140         <py:for each="url in ds.metadataURLs"> 
    141             ${markupMetadataURL(url)} 
    142         </py:for> 
    143     </py:if> 
    144  
     128    <!--!NOTE: if there is no identifier then the layer can never be selected 
     129               so don't need to bother with styles or metadata urls --> 
     130    <py:if test="ds.identifier is not None"> 
     131     
     132            <py:choose test="ds.styles"> 
     133         
     134                <py:when test="['']"> 
     135                    <Style> 
     136                        <Name>default</Name> 
     137                        <Title>Default</Title> 
     138                        <LegendURL width="${ds.legendSize[0]}" height="${ds.legendSize[1]}"> 
     139                            <Format py:for="f in ds.legendFormats" py:content="f"/> 
     140                            <OnlineResource xlink:type="simple" xlink:href="${url_for(qualified=True, action='index')}?request=GetLegend&amp;layers=${ds.identifier}"/> 
     141                        </LegendURL> 
     142                    </Style> 
     143                </py:when> 
     144         
     145                <py:otherwise> 
     146                    <py:for each="s in ds.styles" py:if="getattr(ds, 'styles', None) != None"> 
     147                        ${markupStyle(s)} 
     148                    </py:for> 
     149                </py:otherwise> 
     150         
     151            </py:choose> 
     152             
     153            <py:if test="len(ds.metadataURLs) > 0"> 
     154                <py:for each="url in ds.metadataURLs"> 
     155                    ${markupMetadataURL(url)} 
     156                </py:for> 
     157            </py:if> 
     158             
     159    </py:if> 
     160 
     161 
     162    <Layer py:for="c in ds.children" py:replace="markupLayer(c)"></Layer> 
    145163 
    146164  </Layer> 
     
    204222      ?> 
    205223      <Request> 
     224       
    206225    <py:for each="opName in ops" py:if="opName in om.operationDict.keys()"> 
    207226      <span py:content="markupOperation(opName, om.operationDict[opName])" py:strip="True"/> 
    208227    </py:for> 
     228     
    209229    <py:for each="opName in ops" py:if="opName in om.operationDict.keys()"> 
    210230      <?python exceptions = om.operationDict[opName].parameters.get('ExceptionFormat') ?> 
  • cows/trunk/cows/pylons/wms_controller.py

    r6102 r6393  
    6161    owsOperations = (ows_controller.OWSController.owsOperations + 
    6262        ['GetMap', 'GetContext', 'GetLegend', 'GetFeatureInfo', 'GetInfo']) 
     63     
    6364    validVersions = ['1.1.1', '1.3.0'] 
    6465 
     
    115116        log.debug('Loading capabilities contents') 
    116117        c.capabilities.contents = Contents() 
     118                 
    117119        for layerName, layer in self.layers.items(): 
    118             log.debug('LayerName: %s' % layerName) 
    119             log.debug('Loading layer %s' % layerName) 
    120  
    121             wgs84BBox = WGS84BoundingBox(layer.wgs84BBox[:2], 
    122                                          layer.wgs84BBox[2:]) 
    123             # Get CRS/BBOX pairs 
    124             bboxObjs = [] 
    125             for crs in layer.crss: 
    126                 bbox = layer.getBBox(crs) 
    127                 bboxObjs.append(BoundingBox(bbox[:2], bbox[2:], crs=crs)) 
    128             # Get dimensions 
    129             dims = {} 
    130             for dimName, dim in layer.dimensions.items(): 
    131                 dimParam = self._mapDimToParam(dimName) 
    132                 dims[dimParam] = Dimension(valuesUnit=dim.units, 
    133                                           unitSymbol=dim.units, 
    134                                           possibleValues= 
    135                                             PossibleValues.fromAllowedValues(dim.extent)) 
    136             # Does the layer implement GetFeatureInfo? 
    137             if layer.featureInfoFormats: 
    138                 queryable = True 
    139                 featureInfoFormats.union_update(layer.featureInfoFormats) 
    140             else: 
    141                 queryable = False 
    142                  
    143             #URL to WCS - uses named route 'wcsroute' 
    144             #TODO: Allow for a WCS blacklist to opt out of providing dataurls for certain datasets? 
    145             #TODO: How to make this more configurable - what if WCS is not coupled with WMS? 
    146             try: 
    147                 version='1.0.0' #wcs version 
    148                 wcsbaseurl=url_for('wcsroute', fileoruri=c.fileoruri,qualified=True)+'?' 
    149                 dataURLs=[DataURL(format='WCS:CoverageDescription', onlineResource='%sService=WCS&Request=DescribeCoverage&Coverage=%s&Version=%s'%(wcsbaseurl, layerName, version))] 
    150             except GenerationException: 
    151                 log.info("dataURLs not populated: could not generate WCS url with url_for('wcsroute', filedoruri=%s,qualified=True)"%c.fileoruri) 
    152                 dataURLs=[] 
    153                  
    154              
    155              
    156              
    157             if hasattr(layer, 'styles'): 
    158                 styles = layer.styles 
    159             else: 
    160                 styles = [''] 
    161              
    162             if hasattr(layer, 'metadataURLs'): 
    163                 metadataURLs = layer.metadataURLs 
    164             else: 
    165                 metadataURLs = [] 
    166              
    167             # Create the cows object 
    168             ds = WmsDatasetSummary(identifier=layerName, 
    169                                    titles=[layer.title], 
    170                                    CRSs=layer.crss, 
    171                                    wgs84BoundingBoxes=[wgs84BBox], 
    172                                    boundingBoxes=bboxObjs, 
    173                                    abstracts=[layer.abstract], 
    174                                    dimensions=dims, 
    175                                    queryable=queryable, 
    176                                    dataURLs=dataURLs, 
    177                                    styles=styles, 
    178                                    metadataURLs=metadataURLs) 
    179  
    180             # Stuff that should go in the capabilities tree eventually 
    181             ds.legendSize = layer.legendSize 
    182             ds.legendFormats = ['image/png'] 
    183  
     120 
     121            ds = self._buildWMSDatasetSummary(layer, featureInfoFormats) 
     122             
    184123            c.capabilities.contents.datasetSummaries.append(ds) 
     124         
     125         
     126        log.debug('Setting dataset name') 
    185127         
    186128        #LayerMapper may optionally implement a datasetName attribute which  
     
    191133                except AttributeError: 
    192134                    pass 
    193                  
     135         
     136        # if there is still no serviceIdentification, use the fileoruri 
     137        if c.capabilities.serviceIdentification.titles[0] is None: 
     138            fileoruri = request.environ['pylons.routes_dict']['fileoruri'] 
     139            c.capabilities.serviceIdentification.titles=[fileoruri] 
    194140                 
    195141        # Add this operation here after we have found all formats 
     
    197143                                    formats = list(featureInfoFormats)) 
    198144 
     145 
     146    def _buildWMSDatasetSummary(self, layer, featureInfoFormats): 
     147         
     148        if hasattr(layer, 'wgs84BBox'): 
     149            wgs84BBox = WGS84BoundingBox(layer.wgs84BBox[:2], 
     150                                         layer.wgs84BBox[2:]) 
     151        else: 
     152            wgs84BBox = None 
     153             
     154        # Get CRS/BBOX pairs 
     155        bboxObjs = [] 
     156         
     157        if hasattr(layer, 'crss') and layer.crss is not None: 
     158            for crs in layer.crss: 
     159                bbox = layer.getBBox(crs) 
     160                bboxObjs.append(BoundingBox(bbox[:2], bbox[2:], crs=crs)) 
     161                 
     162        # Get dimensions 
     163        dims = {} 
     164         
     165        if hasattr(layer, 'dimensions') and layer.dimensions is not None: 
     166            for dimName, dim in layer.dimensions.items(): 
     167                dimParam = self._mapDimToParam(dimName) 
     168                dims[dimParam] = Dimension(valuesUnit=dim.units, unitSymbol=dim.units, 
     169                                          possibleValues= 
     170                                            PossibleValues.fromAllowedValues(dim.extent)) 
     171             
     172             
     173        # Does the layer implement GetFeatureInfo? 
     174        if layer.featureInfoFormats: 
     175            queryable = True 
     176            featureInfoFormats.union_update(layer.featureInfoFormats) 
     177        else: 
     178            queryable = False 
     179             
     180        if layer.name != None: 
     181            #URL to WCS - uses named route 'wcsroute' 
     182            #TODO: Allow for a WCS blacklist to opt out of providing dataurls for certain datasets? 
     183            #TODO: How to make this more configurable - what if WCS is not coupled with WMS? 
     184            try: 
     185                version='1.0.0' #wcs version 
     186                wcsbaseurl=url_for('wcsroute', fileoruri=c.fileoruri,qualified=True)+'?' 
     187                dataURLs=[DataURL(format='WCS:CoverageDescription', onlineResource='%sService=WCS&Request=DescribeCoverage&Coverage=%s&Version=%s'%(wcsbaseurl, layer.name, version))] 
     188            except GenerationException: 
     189                log.info("dataURLs not populated: could not generate WCS url with url_for('wcsroute', filedoruri=%s,qualified=True)"%c.fileoruri) 
     190                dataURLs=[] 
     191        else: 
     192            dataURLs = [] 
     193         
     194         
     195        if hasattr(layer, 'styles'): 
     196            styles = layer.styles 
     197        else: 
     198            styles = [''] 
     199         
     200        if hasattr(layer, 'metadataURLs'): 
     201            metadataURLs = layer.metadataURLs 
     202        else: 
     203            metadataURLs = [] 
     204         
     205        children = [] 
     206         
     207        if hasattr(layer, 'childLayers'): 
     208            children = [self._buildWMSDatasetSummary(l, featureInfoFormats) \ 
     209                                                     for l in layer.childLayers] 
     210         
     211        # Create the cows object 
     212        ds = WmsDatasetSummary(identifier=layer.name, 
     213                               titles=[layer.title], 
     214                               CRSs=layer.crss, 
     215                               wgs84BoundingBoxes=[wgs84BBox], 
     216                               boundingBoxes=bboxObjs, 
     217                               abstracts=[layer.abstract], 
     218                               dimensions=dims, 
     219                               queryable=queryable, 
     220                               dataURLs=dataURLs, 
     221                               styles=styles, 
     222                               children=children, 
     223                               metadataURLs=metadataURLs) 
     224 
     225        # Stuff that should go in the capabilities tree eventually 
     226        ds.legendSize = layer.legendSize 
     227        ds.legendFormats = ['image/png']         
     228 
     229        return ds 
     230 
    199231    def _getLayerParamInfo(self, paramName='layers'): 
    200232        """ 
     
    211243        # This plays nicer with mapClient. 
    212244        if ',' in layerName: 
    213             #layerName = layerName.split(',')[0] 
    214245            raise InvalidParameterValue( 
    215246                'Multi-layer GetLegend requests are not supported', 'layers') 
    216         try: 
     247             
     248        layerObj = self._getLayerFromMap(layerName) 
     249         
     250        return layerName, layerObj 
     251     
     252    def _getLayerParam(self, paramName='layers'): 
     253        """ 
     254        Retrieve the layers parameters. 
     255 
     256        @param paramName: Overrides the query string parameter name to 
     257            look for.  This is useful for implementing GetFeatureInfo. 
     258 
     259        """ 
     260        layerNames = self.getOwsParam(paramName) 
     261         
     262        layerNames = layerNames.split(',') 
     263         
     264        layerObjects = [ self._getLayerFromMap(name) for name in layerNames] 
     265         
     266        return layerObjects 
     267     
     268    def _getLayerFromMap(self, layerName): 
     269        """ 
     270        Searches the layer map for the named layer, if no matching layer 
     271        is found an InvalidParameterValue is raised. 
     272        """ 
     273         
     274        layerObj = None 
     275         
     276        if layerName in self.layers: 
    217277            layerObj = self.layers[layerName] 
    218         except KeyError: 
    219             raise InvalidParameterValue('Layer %s not found' % layerName, 
    220                                         paramName) 
    221  
    222         return layerName, layerObj 
    223  
    224     def _getLayerParam(self, paramName='layers'): 
    225         """ 
    226         Retrieve the layers parameter enforcing the rule of only 
    227         selecting one layer. 
    228  
    229         @param paramName: Overrides the query string parameter name to 
    230             look for.  This is usefull for implementing GetFeatureInfo. 
    231  
    232         """ 
    233         layers = {} 
    234         layerNames = self.getOwsParam(paramName) 
    235          
    236         # Select the first layer if several are requested. 
    237         # This plays nicer with mapClient. 
    238         layerNames = layerNames.split(',') 
    239          
    240         layerObjects = [] 
    241          
    242         for layerName in layerNames: 
    243             try: 
    244                 layerObj = self.layers[layerName] 
    245                 layerObjects.append(layerObj) 
    246             except KeyError: 
    247                 raise InvalidParameterValue('Layer %s not found, layerNames = %s' % (layerName, 
    248                                         self.layers.keys())) 
    249  
    250         return layerObjects 
     278        else: 
     279             
     280            fileoruri = request.environ['pylons.routes_dict']['fileoruri'] 
     281            log.debug("fileoruri = %s" % (fileoruri,)) 
     282            if layerName.find(fileoruri + "_") == 0: 
     283                 
     284                reducedName = layerName[len(fileoruri + "_") :] 
     285                layerObj = self._searchLayerChildren(self.layers.values(), reducedName) 
     286         
     287        if layerObj is None: 
     288            raise InvalidParameterValue('Layer %s not found, layerNames = %s'  
     289                                        % (layerName, self.layers.keys())) 
     290         
     291        return layerObj 
     292     
     293    def _searchLayerChildren(self, layerList, name): 
     294        layerObj = None 
     295         
     296        log.debug("looking for name %s in layers %s" % (name, [l.title for l in layerList] ,)) 
     297         
     298        for l in layerList: 
     299            # does this layer match? 
     300            if l.title == name: 
     301                layerObj = l 
     302                break 
     303             
     304            # does this layer have a child that matches? 
     305            if name.find(l.title + "_") == 0: 
     306                 
     307                reducedName = name[len(l.title + "_"):] 
     308                 
     309                found = self._searchLayerChildren(l.childLayers, reducedName) 
     310                 
     311                if found is not None: 
     312                    layerObj = found 
     313                    break 
     314 
     315        log.debug("found layerObj = %s" % ( layerObj,)) 
     316        return layerObj 
     317 
    251318 
    252319    def _getFormatParam(self): 
  • cows/trunk/cows/service/imps/csmlbackend/csmlcommon.py

    r5756 r6393  
    124124            status,x=ndgRetrieve(uriN, cf, discovery=0) 
    125125            d=csml.parser.Dataset() 
    126             d.parse(x)                          
     126            d.parse(x) 
     127                        
    127128        return d 
    128129     
    129     def list(self): 
     130    def list(self, folder=None): 
    130131        """ 
    131132        Generator that lists available CSML documents. 
     
    140141            return 
    141142         
    142         for dirpath, dirnames, filenames in os.walk(self.csml_dir): 
    143             for filename in filenames: 
    144                 file_id, ext = os.path.splitext(filename) 
    145                 if ext in ('.xml', '.csml'): 
    146                     # Remove common path bit 
    147                     relpath = dirpath[len(self.csml_dir):] 
    148                     yield os.path.join(relpath, file_id) 
     143        path = self.csml_dir 
     144         
     145        if folder != None: 
     146            path = os.path.join(path, folder) 
     147         
     148        for fp in os.listdir(path): 
     149             
     150            if os.path.isdir(os.path.join(path,fp)): 
     151                if folder != None: 
     152                    # return 'folder/folder' 
     153                    yield os.path.join(folder, fp) 
     154                else: 
     155                    # return 'folder' 
     156                    yield fp 
     157                 
     158            if os.path.splitext(fp)[1] in ['.csml', '.xml']: 
     159                if folder != None: 
     160                    # return 'folder/file' without the .csml 
     161                    yield os.path.join(folder, os.path.splitext(fp)[0]) 
     162                else: 
     163                    # return 'file' without the .csml 
     164                    yield os.path.splitext(fp)[0] 
     165         
     166#        for dirpath, dirnames, filenames in os.walk(self.csml_dir): 
     167#            for filename in filenames: 
     168#                file_id, ext = os.path.splitext(filename) 
     169#                if ext in ('.xml', '.csml'): 
     170#                    # Remove common path bit 
     171#                    relpath = dirpath[len(self.csml_dir):] 
     172#                     
     173#                    if len(relpath) > 0 and relpath[0] == '/': 
     174#                        relpath = relpath[1:] 
     175#                     
     176#                    yield os.path.join(relpath, file_id) 
    149177                     
    150178    def listwfsonly(self): 
     
    161189            else: 
    162190                return 
    163                  
    164                  
     191     
     192    def isGroup(self, fc): 
     193        return os.path.isdir(os.path.join(self.csml_dir, fc)) 
    165194 
    166195# 
  • cows/trunk/cows/service/imps/csmlbackend/wcs_csmllayer.py

    r5916 r6393  
    109109        except AttributeError: 
    110110            self.datasetName = 'CSML WCS Service' 
     111             
    111112        layermap={} 
    112113        self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue() 
     114         
    113115        for feature in csml.csmllibs.csmlextra.listify(ds.featureCollection.featureMembers): 
    114116            title, abstract, timepositions, timelimits, units, crss, axisDescriptions=self.getInfo(feature) 
    115117            layermap[feature.id]=CSMLCoverage([title],[abstract], timepositions, timelimits, units, crss, axisDescriptions, feature) 
     118             
    116119        if len(layermap) > 0: 
    117120            self.layermapcache[fileoruri]=layermap 
  • cows/trunk/cows/service/imps/csmlbackend/wms_csmllayer.py

    r6102 r6393  
    9292          
    9393        ds = self.connector.getCsmlDoc(fileoruri) 
     94         
    9495        layermap={} 
     96         
    9597        self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue() 
     98         
    9699        for feature in csml.csmllibs.csmlextra.listify(ds.featureCollection.featureMembers): 
     100             
    97101            title, abstract, dimensions, units, crss=self.getInfo(feature) 
     102             
    98103            layermap[feature.id]=CSMLwmsLayer(title,abstract, dimensions, units, crss, feature, 
    99104                                              name=feature.id) 
  • cows/trunk/cows/service/imps/data_reader_geoplot_backend/__init__.py

    r5676 r6393  
     1 
     2from cows.service.imps.csmlbackend.csmlcommon import CSMLConnector 
     3 
     4_globalCSMLConnector = None 
     5 
     6def getGlobalCSMLConnector(): 
     7    global _globalCSMLConnector 
     8     
     9    if _globalCSMLConnector is None: 
     10        _globalCSMLConnector = CSMLConnector() 
     11     
     12    return _globalCSMLConnector 
  • cows/trunk/cows/service/imps/data_reader_geoplot_backend/csml_data_reader.py

    r6102 r6393  
    44import csml 
    55import cdms2 as cdms 
    6 from copy import copy 
    76 
    87from cows.service.imps.csmlbackend.config import config 
    9 from cows.service.imps.csmlbackend.csmlcommon import CSMLConnector 
    10 from cows.service.imps.csmlbackend.wms_csmllayer import CSMLwmsDimension 
     8from cows.service.imps.data_reader_geoplot_backend import getGlobalCSMLConnector 
     9 
    1110import numpy 
    1211import logging 
    1312 
    1413log = logging.getLogger(__name__) 
    15  
    16 # 
    17 # Global CSML connector instance 
    18 # 
    19 globalCSMLConnector = CSMLConnector() 
    20  
    21  
     14     
    2215class CSMLDataReader(object): 
     16    """ 
     17    Creates an object that can read cdms variable and other data from a csml  
     18    file. 
     19    """ 
    2320     
    2421    def __init__(self, fileoruri): 
    25         self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue() 
    26         self.connector = globalCSMLConnector 
     22        """ 
     23        Creates a data reader, the fileoruri provided indicates which csml file 
     24        should be used. 
     25        """ 
     26 
     27        self.connector = getGlobalCSMLConnector() 
    2728        self.fileoruri = fileoruri 
    2829        self.ds = self.connector.getCsmlDoc(fileoruri) 
    2930        self.varcache = {}  
    30          
    31  
    32      
    33     def getWMSLayerInfo(self): 
    34          
    35         for feature in csml.csmllibs.csmlextra.listify(self.ds.featureCollection.featureMembers): 
    36             log.debug("feature.id = %s" % (feature.id,)) 
    37             title, abstract, dimensions, units, crss=self._getWMSInfo(feature) 
    38             bb = self._getBBox(feature) 
    39             name = feature.id 
    40              
    41             yield (name, title, abstract, dimensions, units, crss, bb)  
    42  
    43      
    44     def _getFeatureTitleAndAbstract(self, feature): 
    45         ''' given a csml feature, return basic info about the layer/feature/coverage 
    46         @return:   title, abstract''' 
    47  
    48         try: 
    49             title=feature.name.CONTENT 
    50         except: 
    51             title='' 
    52              
    53         try: 
    54             abstract=feature.description.CONTENT 
    55         except: 
    56             abstract=title 
    57          
    58         return title, abstract     
    59  
    60     def _getBBox(self, feature): 
    61         try:  
    62             bb = feature.getCSMLBoundingBox().getBox() 
    63         except: 
    64             #default to global 
    65             bb=[-180,-90,180,90] 
    66         return bb         
    67  
    68     def _getWMSInfo(self, feature): 
    69         ''' given a csml feature, return info about the layer/feature 
    70         @return:   title, abstract, dimensions, units, crss ''' 
    71  
    72         title, abstract = self._getFeatureTitleAndAbstract(feature) 
    73         units=feature.getDomainUnits()   
    74         dimensions={} 
    75         tmpunits=copy(units) 
    76         tmpunits.reverse() 
    77         domain = feature.getDomain() 
    78          
    79         for dim in feature.getAxisLabels(): 
    80             nextdim=CSMLwmsDimension(domain, dim, tmpunits.pop()) 
    81              
    82             if dim not in ['latitude', 'longitude']: 
    83                 dimensions[dim]=nextdim 
    84                  
    85         crs=feature.getNativeCRS() 
    86         crss=[self._crscat.getCRS(crs).twoD] 
    87          
    88         if 'EPSG:4326' in crss: 
    89             crss.append('CRS:84') 
    90             crss.append('WGS84') 
    91                      
    92         #the units to return are the units of measure. 
    93         try: 
    94             units=feature.value.rangeSet.valueArray.valueComponent.uom 
    95         except: 
    96             units='unknown units' 
    97              
    98         return title, abstract, dimensions, units, crss 
    99  
    100     def _getFeature(self, id): 
    101         for feature in csml.csmllibs.csmlextra.listify(self.ds.featureCollection.featureMembers): 
    102             if feature.id == id: 
    103                 return feature 
    104              
    105         raise Exception("Feature with id %s not found" % (id,)) 
    106   
    10731 
    10832    def getNetcdfVar(self, featureId,  dimValues): 
    10933        "Opens up the csml and retrieves the variable described by the dimensions" 
    11034         
    111  
    11235        log.debug("featureId = %s, dimValues = %s" % (featureId, dimValues)) 
    11336         
     
    183106        return variable 
    184107     
     108 
     109    def _getFeature(self, id): 
     110        for feature in csml.csmllibs.csmlextra.listify(self.ds.featureCollection.featureMembers): 
     111            if feature.id == id: 
     112                return feature 
     113             
     114        raise Exception("Feature with id %s not found" % (id,)) 
     115 
    185116         
    186117    def _convertDimValues(self, dimValues): 
     
    204135     
    205136    def getConfigAxisXMLFile(self): 
    206          
     137        """ 
     138        Returns a path to the axis config XML file by reading it from the csml 
     139        file. 
     140        """ 
     141     
    207142        xmlPath = None 
    208143        for m in self._getMetadataElements(): 
    209             log.debug("m.text = %s" % (m.text,)) 
    210144             
    211145            if m.text is not None and len(m.text) > 0: 
     
    215149                    xmlPath = metadataValue.split('=')[1] 
    216150         
    217         log.debug("xmlPath = %s" % (xmlPath,)) 
    218151        return xmlPath 
    219152     
     
    233166 
    234167        return metadataElements 
    235          
    236     @staticmethod 
    237     def isDataPresent(fileoruri): 
    238         global globalCSMLConnector 
    239          
    240         log.debug("globalCSMLConnector.list() = %s" % ([x for x in globalCSMLConnector.list()],)) 
    241         for file in globalCSMLConnector.list(): 
    242             log.debug("file = %s" % (file,)) 
    243             if file == fileoruri: 
    244                 return True 
    245              
    246         return False 
    247168     
    248      
  • cows/trunk/cows/service/imps/data_reader_geoplot_backend/data_reader_geoplot_layer_mapper.py

    r6102 r6393  
    1212from cows.service.imps.data_reader_geoplot_backend.data_reader_geoplot_wms_layer import DRGeoplotWmsLayer 
    1313 
    14 from cows.service.imps.data_reader_geoplot_backend.data_readers.csml_data_reader import CSMLDataReader 
     14from cows.service.imps.data_reader_geoplot_backend.csml_layer_builder import CSMLLayerBuilder 
    1515 
    1616log = logging.getLogger(__name__) 
     
    2020    def __init__(self): 
    2121        self.layermapcache={} 
    22         self.readerClasses = [CSMLDataReader] 
     22        self.builderClasses = [CSMLLayerBuilder] 
    2323    
    2424    def map(self, **kwargs): 
     
    4141         
    4242 
     43        log.debug("loading layermap for fileoruri = %s" % (fileoruri,)) 
    4344        layermap={} 
    4445         
    45         reader = self._getReader(fileoruri) 
     46        builder = self._getBuilder(fileoruri) 
    4647         
    47         try: 
    48             self.datasetName = reader.ds.name.CONTENT 
    49         except AttributeError: 
    50             self.datasetName = 'CSML/Geoplot WMS Service' 
    51              
    52         log.debug("fileoruri = %s, self.datasetName = %s" % (fileoruri, self.datasetName)); 
     48        self.datasetName = builder.getDSName(fileoruri) 
    5349         
    54         for name, title, abstract, dimensions, units, crss, bb in \ 
    55                                      reader.getWMSLayerInfo(): 
    56              
    57             layermap[name] = DRGeoplotWmsLayer(name, title, abstract, dimensions, units, crss, bb, reader) 
    58              
    59              
     50        for layer in builder.buildRootLayers(fileoruri): 
     51            layermap[layer.title] = layer 
     52         
    6053        if len(layermap) > 0: 
    61             self.layermapcache[fileoruri]={'layermap':layermap, 
    62                                            'dsName':self.datasetName} 
     54            self.layermapcache[fileoruri]={'layermap':layermap, 'dsName':self.datasetName} 
    6355            return layermap 
    6456        else: 
    6557            raise ValueError 
    6658         
    67     def _getReader(self, fileoruri): 
     59    def _getBuilder(self, fileoruri): 
    6860        """ 
    6961        Searches the reader classes to find one that contains the data for  
     
    7264        """ 
    7365         
    74         log.debug("CSMLDataReader.isDataPresent(fileoruri) = %s" % (CSMLDataReader.isDataPresent(fileoruri),)) 
    75         reader = None 
     66        builder = None 
    7667         
    77         for klass in self.readerClasses: 
     68        for klass in self.builderClasses: 
    7869            if klass.isDataPresent(fileoruri): 
    79                 reader = klass(fileoruri) 
     70                builder = klass() 
    8071                break 
    8172         
    82         if reader == None: 
     73        if builder == None: 
    8374            raise Exception("No reader found for fileoruri = %s" % (fileoruri,)) 
    8475         
    85         return reader 
     76        return builder 
  • cows/trunk/cows/service/imps/data_reader_geoplot_backend/data_reader_geoplot_wms_layer.py

    r6123 r6393  
    3939    EnableXMLAxisConfig = False 
    4040     
    41     def __init__(self, name, title, abstract, dimensions, units, crss,  
    42                  boundingBox, dataReader): 
     41    def __init__(self, title, name=None, abstract=None, dimensions=None,  
     42                       units=None, crss=None, boundingBox=None,  
     43                       dataReader=None, childLayers=None): 
     44         
     45        self.name = name 
    4346        self.featureInfoFormats=None #NotImplemented 
    4447        self.title=title 
     
    4952        self.legendSize=(630,120) 
    5053         
     54        if childLayers is None: 
     55            self.childLayers = [] 
     56        else: 
     57            self.childLayers = childLayers 
     58         
    5159        # dummy values, will need to be set when the data is opened 
    5260        self._minval = None 
    5361        self._maxval = None  
    54          
    55         self.name = name 
    5662        self.dataReader = dataReader 
    5763         
    58         self.styles = self._buildStyles() 
    59         self.metadataURLs = self._buildMetadataURL() 
    60          
    61         bb = boundingBox 
    62              
    63         #convert 0 - 360 to -180, 180 as per common WMS convention 
    64         if abs(bb[2]-bb[0]) >= 359 and abs(bb[2]-bb[0]) < 361: 
    65             bb[0], bb[2]=-180, 180 
    66              
    67         self.wgs84BBox = bb 
     64        if name is not None: 
     65            self.styles = self._buildStyles() 
     66            self.metadataURLs = self._buildMetadataURL() 
     67         
     68        if boundingBox != None: 
     69            bb = boundingBox 
     70                 
     71            #convert 0 - 360 to -180, 180 as per common WMS convention 
     72            if abs(bb[2]-bb[0]) >= 359 and abs(bb[2]-bb[0]) < 361: 
     73                bb[0], bb[2]=-180, 180 
     74                 
     75            self.wgs84BBox = bb 
     76             
     77            try: 
     78                self.wgs84BBox = self.getBBox('EPSG:4326') 
     79            except: 
     80                raise ValueError("Layer must provide a bounding box in EPSG:4326 " 
     81                                 "coordinates for compatibility with WMS-1.3.0") 
     82             
     83             
    6884        self.featureInfoFormats = ['text/html'] 
    6985         
    70         try: 
    71             self.wgs84BBox = self.getBBox('EPSG:4326') 
    72         except: 
    73             raise ValueError("Layer must provide a bounding box in EPSG:4326 " 
    74                              "coordinates for compatibility with WMS-1.3.0") 
    75              
    7686        self.featureinfofilecache={} #used for caching netcdf file in getFeatureInfo 
    77      
     87         
    7888    def getBBox(self, crs): 
    7989        """ 
     
    113123         
    114124        st = time.time() 
    115         netcdfVar = self.dataReader.getNetcdfVar(self.name, dimValues) 
     125        netcdfVar = self.dataReader.getNetcdfVar(self.title, dimValues) 
    116126        log.debug("got netcdf in %ss" % (time.time() - st,)) 
    117127         
     
    211221#        netcdf = f(self.title)  #netcdf here is a cdms transient variable 
    212222         
    213         netcdf = self.dataReader.getNetcdfVar(self.name, dimValues) 
     223        netcdf = self.dataReader.getNetcdfVar(self.title, dimValues) 
    214224        
    215225        #Now grab the netCDF object for the point specified. 
     
    258268            height = self.legendSize[1] 
    259269                 
    260         variable = self.dataReader.getNetcdfVar(self.name, dimValues) 
     270        variable = self.dataReader.getNetcdfVar(self.title, dimValues) 
    261271         
    262272        klass = self._getSlabClass(style) 
  • cows/trunk/setup.cfg

    r5059 r6393  
    11[egg_info] 
    2 tag_svn_revision = false 
     2tag_svn_revision = true 
    33 
    44[nosetests] 
Note: See TracChangeset for help on using the changeset viewer.