source: TI02-CSML/trunk/csml2MolesStuff/csml2moles.py @ 1621

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/csml2MolesStuff/csml2moles.py@1621
Revision 1621, 7.5 KB checked in by domlowe, 13 years ago (diff)

added stub standard name class

Line 
1#!/usr/bin/env python
2
3import sys
4import csml.parser
5import cElementTree
6import elementtree.ElementTree as etree
7import datetime
8import molesWriter as MW
9#this is a fix to the  ElementTree namespace problem that namespaces are usually represented as ns0, ns1, ns2 etc.
10etree._namespace_map.update({
11        'http://www.opengis.net/om': 'om',  'http://www.opengis.net/gml': 'gml','http://ndg.nerc.ac.uk/csml' : 'csml', 'http://www.w3.org/1999/xlink':'xlink'})
12
13
14def _strToDate(ymd):
15    '''given a string in form '2006-01-01' returns a datetime object'''
16    return datetime.date(*map(int, ymd.split('-')))
17
18def _getEnvelopefromDataset(ds):
19    '''gets the bounding box from the feature collection'''
20    envelope= ds.featureCollection.boundedBy
21    return envelope
22
23def _parsefile(f):
24    tree = cElementTree.ElementTree(file=f)
25    dataset = csml.parser.Dataset()
26    dataset.fromXML(tree.getroot())
27    return dataset
28   
29
30class StandardName(object):
31    def __init__(self, somename):
32        '''given some name, attempt to resolve it into a standard name type structure. by stripping out any URLs etc'''
33        #types of names:
34        #myrandomvar
35        #http://some.namespace/localparams#somevar  #conventions?
36        #http://some.namespace/something#somevar  # standard name
37        #from these extract text (description), termid and vocabid where possible.       
38        self.text=''
39        self.term=somename
40        self.vocab=''
41
42class EnvelopeAggregator(object):
43    def __init__(self,envelope):
44        '''start with aggregated envelope equal to the initialising envelope
45        envelope must be of type csml.parser.EnvelopeWithTimePeriod'''
46        self.envelope=envelope
47        self.minX=self.envelope.lowerCorner.vals.split()[0]
48        self.minY=self.envelope.lowerCorner.vals.split()[1]
49        self.maxX=self.envelope.upperCorner.vals.split()[0]
50        self.maxY=self.envelope.upperCorner.vals.split()[1]
51        self.t1= _strToDate(self.envelope.timePosition)
52        self.t2= _strToDate(self.envelope.timePosition)
53 
54    def _compareLowerCorners(self,lowerCorner):
55        minX,minY=lowerCorner.vals.split()[0],lowerCorner.vals.split()[1]
56        if float(minX) < float(self.minX):
57            self.envelope.lowerCorner.vals=str(minX +' '+ self.minY)
58            self.minX=minX
59        if float(minY) < float(self.minY):
60            self.envelope.lowerCorner.vals=str(self.minX +' '+ minY)
61            self.minY=minY
62           
63    def _compareUpperCorners(self,upperCorner):
64        maxX,maxY=upperCorner.vals.split()[0],upperCorner.vals.split()[1]
65        if float(maxX) > float(self.maxX):
66            self.envelope.upperCorner.vals=str(maxX +' '+ self.maxY)
67            self.maxX=maxX
68        if float(maxY) > float(self.maxY):
69            self.envelope.upperCorner.vals=str(self.maxX +' '+ maxY)
70            self.maxY=maxY
71           
72    def _compareLowerTimes(self,timepos):
73        t=_strToDate(timepos)
74        if t<self.t1:
75            self.t1=t
76       
77    def _compareUpperTimes(self,timepos):
78        t=_strToDate(timepos)
79        if t>self.t2:
80            self.t2=t
81   
82    def compareEnvelope(self,envtocheck):
83        '''compares new envelope, and if necessary changes the aggregated envelope.'''
84        if envtocheck.srsName!=self.envelope.srsName:
85            print 'Can currently only perform aggregation within the same spatio-temporal reference system.'
86            sys.exit()
87        else: 
88            self._compareLowerCorners(envtocheck.lowerCorner)
89            self._compareUpperCorners(envtocheck.upperCorner)
90            self._compareLowerTimes(envtocheck.timePosition)
91            self._compareUpperTimes(envtocheck.timePosition2)
92   
93    def getAggregatedEnvelope(self):
94        self.envelope.timePosition=str(self.t1)  #convert from datetime types
95        self.envelope.timePosition2=str(self.t2)
96        return self.envelope
97
98
99def main(args=None):
100    '''Get command line arguments, should be an ID scheme for the moles document and paths to csml files
101    i,e, python  csml2moles.py badc.nerc.ac.uk document123 csmlfile1.xml csmlfile2.xml csmlfile3.xml
102    main() will aggregate the spatial and temporal bounding box across all the featureCollections.
103    Currently only one featureCollection per csml file is supported
104   
105    TODO: This should be extended to handle directories of files
106    TODO: CSML files may be stored in exist '''
107    repository = sys.argv[1]
108    identifier= sys.argv[2]
109
110    if args:
111        sys.argv =args
112    csmlfilelist= sys.argv[3:]
113
114    # MOLES skeleton document:
115    M=MW.MolesDoc()
116    M._createClasses()
117   
118    #set up coverage envelope aggragator with envelope from first file:
119    dataset=_parsefile(csmlfilelist[0])
120    env=_getEnvelopefromDataset(dataset)
121    aggregator=EnvelopeAggregator(env)
122 
123   
124    #set up lists to hold stuff
125    schemeIdentifiers=[]
126    repositoryIdentifiers=[]
127    localIdentifiers=[]
128    parameterSummaries=[]
129   
130    #for each file:
131    for f in csmlfilelist:
132        #parse file:
133        dataset=_parsefile(f)
134        #compare envelope:
135        aggregator.compareEnvelope(_getEnvelopefromDataset(dataset))
136        #get other things:
137        schemeIdentifiers.append('NDG-A0')
138        repositoryIdentifiers.append('badc.nerc.ac.uk')
139        localIdentifiers.append(f)
140        #create parameter summaries:
141        #print dir(dataset.featureCollection)
142       
143        for feature in dataset.featureCollection.members:
144            if hasattr(feature.parameter, 'href'):
145                sn=StandardName(feature.parameter.href)
146            SPM=M.dgStdParameterMeasured(dgValidTerm= sn.text)
147            RDP=M.dgRangeDataParameter(HighValue='', LowValue='')
148            PS  = M.dgParameterSummary(dgRangeDataParameter=RDP, dgStdParameterMeasured=SPM)
149            parameterSummaries.append(PS)
150    #get aggregated envelope:
151    finalEnvelope=aggregator.getAggregatedEnvelope()
152    limitN=finalEnvelope.upperCorner.vals.split()[0]
153    limitS=finalEnvelope.lowerCorner.vals.split()[0]
154    limitE=finalEnvelope.upperCorner.vals.split()[1]
155    limitW=finalEnvelope.lowerCorner.vals.split()[1]
156    #get other aggregations:
157   
158
159   
160    ''' The MOLES document:
161    create your moles doc by setting attributes of "M.className"
162    the classNames used must be declared in molesWriter.MolesDoc.classList'''
163   
164    #MetaData ID
165    dgMID=M.dgMetadataID(schemeIdentifier='NDG-B0', repositoryIdentifier=repository, localIdentifier=identifier)
166   
167    #create data granules
168    datagranules=[]
169    for i, file in enumerate(csmlfilelist):
170        DMid=M.dataModelID(schemeIdentifier=schemeIdentifiers[i], repositoryIdentifier=repositoryIdentifiers[i],localIdentifier= localIdentifiers[i])
171        DG  = M.dgDataGranule(dataModelID=DMid)
172        datagranules.append(DG)
173
174    #create coverage
175    dgBB=M.dgBoundingBox(LimitNorth = limitN, LimitSouth=limitS,LimitEast=limitE, LimitWest=limitW)
176    dgSc=M.dgSpatialCoverage(dgBoundingBox=dgBB)
177    dgTc=M.dgTemporalCoverage()
178    dgST=M.dgSpatioTemporalCoverage(dgSpatialCoverage = dgSc, dgTemporalCoverage=dgTc)
179    dgCv=M.dgCoverage(dgSpatioTemporalCoverage=dgST)
180   
181    #create data summary:
182    DS = M.dgDataSummary(dgCoverage=dgCv, dgParameterSummary=parameterSummaries)
183   
184    #create data entity:
185    dgDE= M.dgDataEntity(dgDataGranule=datagranules, dgDataSummary=DS)
186   
187    #create metadata record
188    dgMR=M.dgMetadataRecord(dgMetadataID=dgMID, dgDataEntity=dgDE)
189    dgMeta=MW.dgMetadata(dgMetadataRecord=dgMR)
190
191    #produce XML
192    molestree=dgMeta.toXML()
193    #print it out.
194    moles=csml.parser_extra.PrettyPrint(molestree)
195    print moles
196   
197if __name__=='__main__':
198    main()
Note: See TracBrowser for help on using the repository browser.