source: TI02-CSML/trunk/csml/csml2Moles/TEST.py @ 1860

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/csml/csml2Moles/TEST.py@2047
Revision 1860, 10.0 KB checked in by domlowe, 13 years ago (diff)

test code to try adding elements to already existing moles doc

Line 
1#!/usr/bin/env python
2
3import sys
4import csml.parser
5import cElementTree
6import elementtree.ElementTree as etree
7import datetime
8import molesReadWrite as MRW
9
10'''call using: python csml2moles.py badc.nerc.ac.uk molesdocABC example.xml example2.xml example3.xml'''
11
12
13#this is a fix to the  ElementTree namespace problem that namespaces are usually represented as ns0, ns1, ns2 etc.
14etree._namespace_map.update({
15        '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'})
16
17def _strToDate(ymd):
18    '''given a string in form '2006-01-01' returns a datetime object'''
19    return datetime.date(*map(int, ymd.split('-')))
20
21def _getEnvelopefromDataset(ds):
22    '''gets the bounding box from the feature collection'''
23    envelope= ds.featureCollection.boundedBy
24    return envelope
25
26def _parsefile(f):
27    tree = cElementTree.ElementTree(file=f)
28    dataset = csml.parser.Dataset()
29    dataset.fromXML(tree.getroot())
30    return dataset
31   
32
33class StandardName(object):
34    def __init__(self, somename):
35        '''given some name, attempt to resolve it into a standard name type structure. by stripping out any URLs etc'''
36        #types of names:
37        #myrandomvar
38        #http://some.namespace/localparams#somevar  #conventions?
39        #http://some.namespace/something#somevar  # standard name
40        #from these extract text (description), termid and vocabid where possible.       
41        #for starters split at '#'
42        #this can't be finalised till we agree on a convention.
43
44        sections=somename.split('#')
45        self.text=''
46        if len(sections)==2:
47            self.vocab=sections[0]
48            self.term=sections[1]
49        else:
50            self.term=somename
51            self.vocab=''
52
53class EnvelopeAggregator(object):
54    def __init__(self,envelope):
55        '''start with aggregated envelope equal to the initialising envelope
56        envelope must be of type csml.parser.EnvelopeWithTimePeriod'''
57        self.envelope=envelope
58        self.minX=self.envelope.lowerCorner.vals.split()[0]
59        self.minY=self.envelope.lowerCorner.vals.split()[1]
60        self.maxX=self.envelope.upperCorner.vals.split()[0]
61        self.maxY=self.envelope.upperCorner.vals.split()[1]
62        self.t1= _strToDate(self.envelope.timePosition)
63        self.t2= _strToDate(self.envelope.timePosition)
64 
65    def _compareLowerCorners(self,lowerCorner):
66        minX,minY=lowerCorner.vals.split()[0],lowerCorner.vals.split()[1]
67        if float(minX) < float(self.minX):
68            self.envelope.lowerCorner.vals=str(minX +' '+ self.minY)
69            self.minX=minX
70        if float(minY) < float(self.minY):
71            self.envelope.lowerCorner.vals=str(self.minX +' '+ minY)
72            self.minY=minY
73           
74    def _compareUpperCorners(self,upperCorner):
75        maxX,maxY=upperCorner.vals.split()[0],upperCorner.vals.split()[1]
76        if float(maxX) > float(self.maxX):
77            self.envelope.upperCorner.vals=str(maxX +' '+ self.maxY)
78            self.maxX=maxX
79        if float(maxY) > float(self.maxY):
80            self.envelope.upperCorner.vals=str(self.maxX +' '+ maxY)
81            self.maxY=maxY
82           
83    def _compareLowerTimes(self,timepos):
84        t=_strToDate(timepos)
85        if t<self.t1:
86            self.t1=t
87       
88    def _compareUpperTimes(self,timepos):
89        t=_strToDate(timepos)
90        if t>self.t2:
91            self.t2=t
92   
93    def compareEnvelope(self,envtocheck):
94        '''compares new envelope, and if necessary changes the aggregated envelope.'''
95        if envtocheck.srsName!=self.envelope.srsName:
96            print 'Can currently only perform aggregation within the same spatio-temporal reference system.'
97            sys.exit()
98        else: 
99            self._compareLowerCorners(envtocheck.lowerCorner)
100            self._compareUpperCorners(envtocheck.upperCorner)
101            self._compareLowerTimes(envtocheck.timePosition)
102            self._compareUpperTimes(envtocheck.timePosition2)
103   
104    def getAggregatedEnvelope(self):
105        self.envelope.timePosition=str(self.t1)  #convert from datetime types
106        self.envelope.timePosition2=str(self.t2)
107        return self.envelope
108
109
110def addNewElement(parentobject, childname, child):
111    if hasattr(parentobject, childname):
112        currentattribute=getattr(parentobject,childname)
113        if getattr(parentobject,childname) is list:
114            currentattribute.append(child)
115           
116        else: 
117            newlist=[currentattribute]
118            newlist.append(child)
119            setattr(parentobject,childname, newlist)
120    else:
121        setattr(parentobject,childname, child)
122
123
124def main(args=None):
125   
126    '''Get command line arguments, should be an ID scheme for the moles document and paths to csml files
127    i,e, python  csml2moles.py badc.nerc.ac.uk document123 csmlfile1.xml csmlfile2.xml csmlfile3.xml
128    main() will aggregate the spatial and temporal bounding box across all the featureCollections.
129    Currently only one featureCollection per csml file is supported
130   
131    TODO: This should be extended to handle directories of files
132    TODO: CSML files may be stored in exist '''
133    mNS='http://ndg.nerc.ac.uk/moles'
134    repository = sys.argv[1]
135    identifier= sys.argv[2]
136
137    if args:
138        sys.argv =args
139    csmlfilelist= sys.argv[3:]
140
141    # MOLES skeleton document:
142    M=MRW.MolesDoc()
143   
144    #set up coverage envelope aggragator with envelope from first file:
145    dataset=_parsefile(csmlfilelist[0])
146    env=_getEnvelopefromDataset(dataset)
147    aggregator=EnvelopeAggregator(env)
148 
149   
150    #set up lists to hold stuff
151    schemeIdentifiers=[]
152    repositoryIdentifiers=[]
153    localIdentifiers=[]
154    parameterSummaries=[]
155   
156    #for each file:
157    for f in csmlfilelist:
158        #parse file:
159        dataset=_parsefile(f)
160        #compare envelope:
161        aggregator.compareEnvelope(_getEnvelopefromDataset(dataset))
162        #get other things:
163        schemeIdentifiers.append('NDG-A0')
164        repositoryIdentifiers.append('badc.nerc.ac.uk')
165        localIdentifiers.append(f)
166        #create parameter summaries:
167        #print dir(dataset.featureCollection)
168       
169        for feature in dataset.featureCollection.members:
170            if hasattr(feature.parameter, 'href'):
171                sn=StandardName(feature.parameter.href)
172                if hasattr(feature, 'description'):
173                    sn.text=feature.description
174            VTID=M.dgValidTermID( ParentListID=sn.vocab, TermID=sn.term)
175           
176            SPM=M.dgStdParameterMeasured(dgValidTerm= sn.text, dgValidTermID=VTID)
177            RDP=M.dgRangeDataParameter(HighValue='', LowValue='')
178            PS  = M.dgParameterSummary(dgRangeDataParameter=RDP, dgStdParameterMeasured=SPM)
179            parameterSummaries.append(PS)
180    #get aggregated envelope:
181    finalEnvelope=aggregator.getAggregatedEnvelope()
182    limitN=finalEnvelope.upperCorner.vals.split()[0]
183    limitS=finalEnvelope.lowerCorner.vals.split()[0]
184    limitE=finalEnvelope.upperCorner.vals.split()[1]
185    limitW=finalEnvelope.lowerCorner.vals.split()[1]
186    #get other aggregations:
187   
188
189   
190    ''' The MOLES document:
191    create your moles doc by setting attributes of "M.className"
192    the classNames used must be declared in molesWriter.MolesDoc.classList'''
193   
194    #MetaData ID
195    dgMID=M.dgMetadataID(schemeIdentifier='NDG-B0', repositoryIdentifier=repository, localIdentifier=identifier)
196   
197    #create data granules
198    datagranules=[]
199    for i, file in enumerate(csmlfilelist):
200        DMid=M.dataModelID(schemeIdentifier=schemeIdentifiers[i], repositoryIdentifier=repositoryIdentifiers[i],localIdentifier= localIdentifiers[i])
201        DG  = M.dgDataGranule(dataModelID=DMid)
202        datagranules.append(DG)
203
204    #create coverage
205    dgBB=M.dgBoundingBox(LimitNorth = limitN, LimitSouth=limitS,LimitEast=limitE, LimitWest=limitW)
206    dgSc=M.dgSpatialCoverage(dgBoundingBox=dgBB)
207    dgTc=M.dgTemporalCoverage(mNS)
208    dgST=M.dgSpatioTemporalCoverage(dgSpatialCoverage = dgSc, dgTemporalCoverage=dgTc)
209    dgCv=M.dgCoverage(dgSpatioTemporalCoverage=dgST)
210   
211    #create data summary:
212    DS = M.dgDataSummary(dgCoverage=dgCv, dgParameterSummary=parameterSummaries)
213    #create data entity:
214    dgDE= M.dgDataEntity(dgDataGranule=datagranules, dgDataSummary=DS)
215   
216    #create metadata description:
217    mdID=M.metadataDescriptionID(schemeIdentifier='1',repositoryIdentifier='2', localIdentifier='3')
218    dgMD=M.dgMetadataDescription(metadataDescriptionID=mdID)
219    #create metadata record
220    strValidTerm='climatologyMeteorologyAtmosphere'
221    strParentID='ISO 19115 - Geographic Information Metadata Topic Category Code List'
222    strTermID='004'
223    dgVTID=M.dgValidTermID(ParentListID=strParentID, TermID=strTermID)
224    dgSK=M.dgStructuredKeyword(dgValidTerm=strValidTerm, dgValidTermID=dgVTID)
225   
226    dgMR=M.dgMetadataRecord(dgMetadataID=dgMID, dgDataEntity=dgDE, dgMetadataDescription=dgMD, dgStructuredKeyword=dgSK)
227    dgMeta=MRW.dgMetadata(dgMetadataRecord=dgMR)
228
229
230    #produce XML  and save to file
231    molestree=dgMeta.toXML()
232    moles=csml.parser_extra.PrettyPrint(molestree)
233    print '\n \n \n BEFORE PARSING'
234    #print moles
235    f=open('molesout.xml','w')
236    f.write(moles)
237    f.close()
238
239   
240    #produce XML again (round trip)
241    tree=cElementTree.ElementTree(file='molesout.xml')
242    dgMeta=MRW.dgMetadata()
243    dgMeta.fromXML(tree.getroot())
244   
245    #now try and add another structured keyword:
246    strValidTerm='2nd kword climatologyMeteorologyAtmosphere'
247    strParentID='2 ISO 19115 - Geographic Information Metadata Topic Category Code List'
248    strTermID='2004'
249    dgVTID=M.dgValidTermID(ParentListID=strParentID, TermID=strTermID)
250    dgSK=M.dgStructuredKeyword(dgValidTerm=strValidTerm, dgValidTermID=dgVTID)
251   
252    addNewElement(dgMeta.dgMetadataRecord, 'dgStructuredKeyword', dgSK)
253
254
255    molestree=dgMeta.toXML()
256    moles=csml.parser_extra.PrettyPrint(molestree)
257    print '\n \n \n AFTER PARSING'
258    print moles   
259    print dgMeta.dgMetadataRecord.dgStructuredKeyword
260   
261if __name__=='__main__':
262    main()
Note: See TracBrowser for help on using the repository browser.