source: TI02-CSML/trunk/Scanner/csmllibs/csmlfeaturetypes.py @ 1403

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/Scanner/csmllibs/csmlfeaturetypes.py@1403
Revision 1403, 22.2 KB checked in by domlowe, 13 years ago (diff)

removed need to keep passing extracttype around

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/usr/bin/env python
2#**************************************************************************************
3#csmlfeaturetypes.py
4#For creating CSML featuretypes
5#v0.5 split off 11th November 2005
6#Dominic Lowe, BADC
7#**************************************************************************************
8
9import csmllibs
10import sys
11
12class featureBuilder:
13    def __init__(self, dataset_element, gml_FeatureCollection_element, ffmap,fileExtractDictionary, timedim, timestorage,spatialstorage,valuestorage):
14        self.ds_element=dataset_element
15        self.gml_FeatureCollection_element = gml_FeatureCollection_element
16        self.ffmap = ffmap
17        self.fileExtractDictionary = fileExtractDictionary
18        self.timedim = timedim
19        self.timestorage=timestorage
20        self.spatialstorage=spatialstorage
21        self.valuestorage=valuestorage
22               
23        #empty list to hold featureMembers
24        self.fms =[]
25       
26        #at the moment, only one featuretype per CSML Dataset is supported.
27        #get the featuretype of the first representative file in the ffmap object
28        self.featuretype=  self.ffmap.getRepresentativeFiles()[0].getFeatureType()
29        if self.featuretype == 'GridSeries':
30            print 'creating grids'
31            self.createCSMLGridSeriesFeatures()
32        elif self.featuretype == 'PointSeries':       
33            self.createCSMLPointSeriesFeatures()
34       
35        #after the features have been generated append all featureMembers to the feature collection
36        self.gml_FeatureCollection_element.members=self.fms
37       
38    def createCSMLGridSeriesFeatures(self):
39        #This function assumes that the variables (features) are shared across identically structured files
40        #should be supplied with a featurefilemap object (see csmlfiles for FileMapMaker)
41       
42        representativeFiles=self.ffmap.getRepresentativeFiles()
43        #fileid=0  #prefix used to distinguish variable names for similar variables from different files
44        #don't use this - same variables should not be in same data granule.
45        for repfile in representativeFiles:
46            #fileid=fileid+1
47            listOfFiles=[]
48            repfilename=repfile.getRepresentativeFileName()
49            listOfFiles.append(repfilename)
50            relfiles = repfile.getRelatedFiles()
51            for f in relfiles:
52                fname = f.getRelatedFileName()
53                listOfFiles.append(fname)
54               
55            #THIS IS THE REALLY SLOW FUNCTION CALL!!!!!#########################
56            OrderedFileTimeList,caltype,units = csmllibs.csmltime.getFileTimeList(listOfFiles,self.timedim)
57            #build strings to hold times/filenames for current gridseriesfeature
58            #cal type returns the type of calendar used
59            timeString =''
60            filesinDir = ''
61            for j in range (0, len(OrderedFileTimeList)):
62                t= OrderedFileTimeList[j][0]
63                f = OrderedFileTimeList[j][1]
64                timeString = timeString + ' ' + str(t)
65                filesinDir = filesinDir + ' ' + f
66                #Open representative file and create feature members:
67            DI = csmllibs.csmldataiface.DataInterface()
68            DI=DI.getUnknownInterfaceType(repfilename)
69            DI.openFile(repfilename)
70            allVarNames=DI.getListofVariables()
71            numFeatures=len(allVarNames)
72            #Create a GridSeriesFeature for each variable:
73            for i in range(0, numFeatures):
74                DI.setVariable(allVarNames[i])
75                dimNames=DI.getVariableAxes()
76                if len(dimNames) <= 2:
77                    #it's an axis or bounds not a feature, try next variable
78                    continue
79               
80                GridSeriesFeature_element=csmllibs.Parser.GridSeriesFeature()
81                #GridSeriesFeature_element.id=str(fileid)+'__'+str(allVarNames[i])
82                GridSeriesFeature_element.id=str(allVarNames[i])
83                #description: need to get the attribute called long_name (?? TODO - is this CF compliant??)
84                #use Ag's getbestname from nappy package?
85                desc=DI.getVariableAttribute('long_name')
86                try:
87                    desc=DI.getVariableAttribute('long_name')
88                except AttributeError:
89                    desc = "missing name"
90                   
91                desc=desc.replace('&','&amp;')
92                GridSeriesFeature_element.description=csmllibs.Parser.Description(desc)
93
94                #***********************************************************************
95                #GridSeriesDomain:
96                #***********************************************************************
97                gsDomain=csmllibs.Parser.GridSeriesDomain()
98                #***********************************************************************
99                # domainReference element
100                #***********************************************************************
101                #
102                tpl=csmllibs.Parser.TimePositionList()
103                if self.timestorage =='inline':
104                    tpl.timePositions=timeString
105                    tpl.frame='%s:%s'%(caltype,units)
106                else:
107                    # do something to create a single extract for the times (from the representative file).
108                    tpl.timePositions = csmllibs.csmlfileextracts.createSingleExtract(self.extractType, repfilename, self.timedim, len(timeString.split())) 
109                    tpl.frame='%s:%s'%(caltype,units)
110                   
111                gsDomain.domainReference=tpl
112                grid=csmllibs.Parser.Grid()
113               
114                #***********************************************************************
115                #coverageFunction
116                mr =csmllibs.Parser.MappingRule(csmllibs.csmlextra.getMappingRule(len(dimNames)))
117           
118                GridSeriesFeature_element.coverageFunction=mr
119
120               #***********************************************************************
121              # gml:rangeSet element
122              #***********************************************************************
123                arrSz = DI.getArraySizeOfVar()
124             
125                try:
126                    strUom = DI.getVariableAttribute('units')
127                except AttributeError:
128    #                if units attribute doesn't exist:
129                        strUom ="dimensionless or units not determined"
130
131                rs=csmllibs.Parser.RangeSet()
132                if self.valuestorage=='inline':
133                    #To do, store the rangeset inline - use Datablock class???
134                    pass 
135                else:
136                    #store the rangeSet as an aggregatedArray
137                    aa=csmllibs.Parser.AggregatedArray()
138                    aa.arraySize=[]
139                    aa.arraySize.append(arrSz)
140                    aa.uom=strUom
141                    aa.aggType='new' #can it be anything else?
142                    aa.aggIndex='1'
143                    #FileExtract (fe) element will be NetCDF/GRIB/PPExtract element (As defined earlier in ExtractType)
144                    self.extractType= DI.extractType
145                    if self.extractType=='NetCDFExtract':
146                        fe = csmllibs.Parser.NetCDFExtract()
147                    if self.extractType=='NASAAmesExtract':
148                        fe = csmllibs.Parser.NASAAmesExtract()
149                    if self.extractType=='GRIBExtract':
150                        fe = csmllibs.Parser.GRIBExtract()
151                    if self.extractType=='PPExtract':
152                        fe = csmllibs.Parser.PPExtract()
153                    varSize=DI.getShapeOfVar()
154                    fe.arraySize=varSize
155                    fe.fileName=filesinDir
156                    fe.variableName=allVarNames[i]
157                    aa.component=[fe]
158                    rs.aggregatedArray=aa
159                GridSeriesFeature_element.rangeSet=rs
160                ######################################################
161
162
163#                 #***********************************************************************
164#                 # domainComplement element (and sub-elements)
165#                 #***********************************************************************
166                grid.srsName='urn:EPSG:GeographicCRS:4326'
167                numSpDims=len(varSize) -1 
168                grid.srsDimension=str(numSpDims)
169                grid.dimension=str(numSpDims)
170                ge =csmllibs.Parser.GridEnvelope(low=DI.getLowLimits(), high=DI.getHighLimits())
171                grid.limits=ge
172
173               
174                #add an axisName element(s) for  each spatial dimension.
175                # and an ordinate element
176                axes=[]
177                for i in range (1, len(dimNames)):
178                    #axisNames
179                    axisname ='dim'+str(i)
180                    axes.append(axisname)
181                   
182                   
183                    #ordinates
184                    grid.ordinates=[]
185                    for i in range (1, len(dimNames)):
186                        ord=csmllibs.Parser.GridOrdinateDescription()
187                        ord.gridAxesSpanned='dim' + str(i)
188                        ord.sequenceRule=csmllibs.csmlextra.getSeqRule(len(dimNames))
189                        dimName=dimNames[len(dimNames)-i]
190                        ord.definesAxis=dimName
191                        #look up file extract name in dictionary
192                         #(axisid stored in dictionary = current filename + variable name)
193                        axisid=repfilename+dimName
194                        if self.spatialstorage=='fileextract':
195                            #refer to extract
196                            ord.axisValues='#'+self.fileExtractDictionary[axisid]
197                        else:
198                            #store inline
199                             DI.setAxis(dimName)
200                             ord.axisValues=csmllibs.csmlextra.cleanString(str(DI.getDataForAxis()))
201                        grid.ordinates.append(ord)
202                    grid.axisNames=axes
203                gsDomain.domainComplement=grid
204                GridSeriesFeature_element.domain=gsDomain
205                self.fms.append(GridSeriesFeature_element)
206            DI.closeFile()
207       
208
209#########################################################################
210
211
212    def createCSMLProfileFeature(csmldoc, dataset_element, gml_FeatureCollection_element,  ffmap, timedim):
213            representativeFiles=ffmap.getRepresentativeFiles()
214            listOfFiles=[]
215            for repfile in representativeFiles:
216                    repfilename=repfile.getRepresentativeFileName()
217                    listOfFiles.append(repfilename)
218                    relfiles = repfile.getRelatedFiles()
219                    for f in relfiles:
220                            #hopefully there are no related files at the moment!
221                            fname = f.getRelatedFileName()
222                            listOfFiles.append(fname)
223                    #print listOfFiles
224                   
225            for file in listOfFiles:
226                    DI = csmllibs.csmldataiface.DataInterface()
227                    DI=DI.getUnknownInterfaceType(file)
228                    print'opening file'
229                    DI.openFile(file)
230                    print 'getting variables'
231                    allVarNames=DI.getListofVariables()
232                    print 'getting feature count'
233                    numFeatures=len(allVarNames)       
234                   
235                    print "FEATURES"
236                    print "***********"
237                    for i in range (0, len(allVarNames)):
238                            print allVarNames[i]
239                           
240                    for i in range (0, numFeatures):
241                            gml_featureMember_element=csmldoc.createElement("gml:featureMember")
242                            ProfileFeature_element=csmldoc.createElement("ProfileFeature")
243                            ProfileFeature_element.setAttribute('gml:id',str(allVarNames[i]))
244                            gml_description_element = csmldoc.createElement("gml:description")
245                            gml_featureMember_element.appendChild(ProfileFeature_element)
246                            #***********************************************************************
247                            #PointSeriesDomain:
248                            #***********************************************************************
249                            ProfileDomain_element=csmldoc.createElement("ProfileDomain")
250                           
251                           
252                            #***********************************************************************
253                            # domainReference element (and sub-elements)               
254                            #***********************************************************************
255                            domainReference_element=csmldoc.createElement("domainReference")
256                            #orientedPosition_element=csmldoc.createElement("OrientedPosition")
257                            #locations_element=csmldoc.createElement("locations")
258                            #times_element=csmldoc.createElement("times")
259                            #trajectory_element.appendChild(locations_element)
260                            #trajectory_element.appendChild(times_element)
261                            #domainReference_element.appendChild(orientedPosition_element)
262                           
263                            #gml_timePositionList_element = csmldoc.createElement("gml:TimePositionList")
264                            #gml_timePositionList_element.appendChild(csmldoc.createTextNode(timeString))
265                            #domainReference_element.appendChild(gml_timePositionList_element)
266                            ProfileDomain_element.appendChild(domainReference_element)
267                            #***********************************************************************
268                            domainComplement_element=csmldoc.createElement("domainComplement")
269                            ProfileDomain_element.appendChild(domainComplement_element)
270                           
271                            #***********************************************************************
272                            # gml:rangeSet_element
273                            #***********************************************************************
274                           
275                            gml_rangeSet_element=csmldoc.createElement("gml:rangeSet") 
276                           
277                            #***********************************************************************
278                            # gml:coverageFunction element (and sub-element MappingRule)               
279                            #***********************************************************************
280                            gml_coverageFunction_element=csmldoc.createElement("gml:coverageFunction")
281                            MappingRule_element=csmldoc.createElement("MappingRule")
282                            #MappingRule_element.setAttribute('scanOrder',csmllibs.csmlextra.getMappingRule(len(dimNames)))
283                            MappingRule_element.setAttribute('scanOrder','tba')
284                            gml_coverageFunction_element.appendChild(MappingRule_element)
285                           
286                           
287                            gml_featureMember_element.appendChild(ProfileDomain_element)
288                            gml_featureMember_element.appendChild(gml_rangeSet_element)
289                            gml_featureMember_element.appendChild(gml_coverageFunction_element)
290                            gml_FeatureCollection_element.appendChild(gml_featureMember_element)       
291                           
292            return 
293                           
294       
295   
296    def createCSMLPointSeriesFeatures(self):           
297            representativeFiles=self.ffmap.getRepresentativeFiles()
298            listOfFiles=[]
299            for repfile in representativeFiles:
300                    repfilename=repfile.getRepresentativeFileName()
301                    listOfFiles.append(repfilename)
302                    relfiles = repfile.getRelatedFiles()
303                    for f in relfiles:
304                            #hopefully there are no related files at the moment!
305                            fname = f.getRelatedFileName()
306                            listOfFiles.append(fname)
307                    file=repfilename
308                    DI = csmllibs.csmldataiface.DataInterface()
309                    DI=DI.getUnknownInterfaceType(file)
310                    DI.openFile(file)
311                    allVarNames=DI.getListofVariables()
312                    numFeatures=len(allVarNames)       
313                    try:
314                            DI.setAxis(self.timedim)
315                            times=DI.getDataForAxis()
316                    except:                     
317                            times = DI.getTimes()
318                            #times = ['time axis not determined']
319                                           
320                    print "numFeatures" + str(numFeatures)
321                    for i in range (0, numFeatures):
322                            PointSeriesFeature_element=csmllibs.Parser.PointSeriesFeature()
323                            if str(allVarNames[i]).upper() in ['ERROR FLAG', 'ERROR']: #might need to extend this list
324                                break
325                            PointSeriesFeature_element.id=str(allVarNames[i])
326                            try:
327                                desc=DI.getVariableAttribute('long_name')
328#                                 print desc
329                            except AttributeError:
330                                desc = "missing name"
331                            PointSeriesFeature_element.description=csmllibs.Parser.Description(desc)
332
333                            #***********************************************************************
334                            #PointSeriesDomain:
335                            #***********************************************************************
336                            psDomain=csmllibs.Parser.PointSeriesDomain()
337                                                 
338                            print len(times)
339                            print len(listOfFiles)
340                            print len(times) * len(listOfFiles)
341                            #***********************************************************************
342                            # domainReference element
343                            #***********************************************************************
344                            t=csmllibs.Parser.Trajectory()
345                            t.srsName='urn:EPSG:geographicCRS:4326' #TO Do
346                            t.locations =csmllibs.Parser.DirectPositionList(vals='1 1')
347                            if len(times) > 200:
348                                pass
349                                #create a file extract link for long lists
350                                filenames=csmllibs.csmlextra.cleanString(str(listOfFiles))
351#                                 print 'times: ' + str(allVarNames[i])
352#                                 print len(times)
353#                                 print len(listOfFiles)
354#                                 arraySize=len(times) * len(listOfFiles)
355#                                 fextract=csmllibs.csmlfileextracts.createSingleExtract(self.extractType,filenames,self.timedim,arraySize)
356#                                 tplist = csmllibs.Parser.TimePositionList(timePositions=fextract)
357#                                 t.times=tplist                               
358                            else:
359                                #encode short lists inline:
360                                t.times=csmllibs.Parser.TimePositionList('#RefSysX',str(times))
361                                 
362                            psDomain.domainReference=t
363                           
364                            #***********************************************************************
365                            # gml:rangeSet_element
366                            #***********************************************************************
367                            DI.setVariable(allVarNames[i])
368                            try:
369                                    strUom = DI.getVariableAttribute('units')
370                            except AttributeError:
371                                    #if units attribute doesn't exist:
372                                    strUom ="dimensionless or units not determined"
373                           
374                            try:                       
375                                    measuredvalues = DI.getDataForVar()
376                            except:
377                                    measuredvalues = ' could not get values '
378                           
379                            rs=csmllibs.Parser.RangeSet()
380                            if len(measuredvalues) > 200:
381                                #create a file extract link for long lists
382                                arraySize=len(measuredvalues)*len(listOfFiles) 
383                                #TODO this needs to be able to handle inline, use VALUESTORAGE to determine which to use:
384                                fextract=csmllibs.csmlfileextracts.createSingleExtract(self.extractType,filenames,allVarNames[i],arraySize)
385                                qlist = csmllibs.Parser.MeasureOrNullList(val=fextract)
386                                rs.quantityList=qlist
387                            else:
388                                #encode short lists inline
389                                rs.quantityList=csmllibs.Parser.MeasureOrNullList(uom=strUom, val=str(measuredvalues)[1:-1])                         
390
391                            PointSeriesFeature_element.rangeSet=rs
392                            #***********************************************************************
393                            # gml:coverageFunction element (and sub-element MappingRule)               
394                            #***********************************************************************
395                           
396                            #need to do parameter element
397                           
398
399                            PointSeriesFeature_element.domain=psDomain
400                            self.fms.append(PointSeriesFeature_element)
401                    DI.closeFile()
402
403
404       
Note: See TracBrowser for help on using the repository browser.