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

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

coverage aggregation and basic data granule creation working

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 EnvelopeAggregator(object):
31    def __init__(self,envelope):
32        '''start with aggregated envelope equal to the initialising envelope
33        envelope must be of type csml.parser.EnvelopeWithTimePeriod'''
34        self.envelope=envelope
35        self.minX=self.envelope.lowerCorner.vals.split()[0]
36        self.minY=self.envelope.lowerCorner.vals.split()[1]
37        self.maxX=self.envelope.upperCorner.vals.split()[0]
38        self.maxY=self.envelope.upperCorner.vals.split()[1]
39        self.t1= _strToDate(self.envelope.timePosition)
40        self.t2= _strToDate(self.envelope.timePosition)
41 
42    def _compareLowerCorners(self,lowerCorner):
43        minX,minY=lowerCorner.vals.split()[0],lowerCorner.vals.split()[1]
44        if float(minX) < float(self.minX):
45            self.envelope.lowerCorner.vals=str(minX +' '+ self.minY)
46            self.minX=minX
47        if float(minY) < float(self.minY):
48            self.envelope.lowerCorner.vals=str(self.minX +' '+ minY)
49            self.minY=minY
50           
51    def _compareUpperCorners(self,upperCorner):
52        maxX,maxY=upperCorner.vals.split()[0],upperCorner.vals.split()[1]
53        if float(maxX) > float(self.maxX):
54            self.envelope.upperCorner.vals=str(maxX +' '+ self.maxY)
55            self.maxX=maxX
56        if float(maxY) > float(self.maxY):
57            self.envelope.upperCorner.vals=str(self.maxX +' '+ maxY)
58            self.maxY=maxY
59           
60    def _compareLowerTimes(self,timepos):
61        t=_strToDate(timepos)
62        if t<self.t1:
63            self.t1=t
64       
65    def _compareUpperTimes(self,timepos):
66        t=_strToDate(timepos)
67        if t>self.t2:
68            self.t2=t
69   
70    def compareEnvelope(self,envtocheck):
71        '''compares new envelope, and if necessary changes the aggregated envelope.'''
72        if envtocheck.srsName!=self.envelope.srsName:
73            print 'Can currently only perform aggregation within the same spatio-temporal reference system.'
74            sys.exit()
75        else: 
76            self._compareLowerCorners(envtocheck.lowerCorner)
77            self._compareUpperCorners(envtocheck.upperCorner)
78            self._compareLowerTimes(envtocheck.timePosition)
79            self._compareUpperTimes(envtocheck.timePosition2)
80   
81    def getAggregatedEnvelope(self):
82        self.envelope.timePosition=str(self.t1)  #convert from datetime types
83        self.envelope.timePosition2=str(self.t2)
84        return self.envelope
85
86
87def main(args=None):
88    '''Get command line arguments, should be paths to csml files
89    e.g. python csml2moles.py csmlfile1.xml csmlfile2.xml csmlfile3.xml
90    main() will aggregate the spatial and temporal bounding box across all the featureCollections.
91    Currently only one featureCollection per csml file is supported '''
92    if args:
93        sys.argv =args
94    csmlfilelist= sys.argv[1:]
95
96    #set up coverage envelope aggragator with envelope from first file:
97    dataset=_parsefile(csmlfilelist[0])
98    env=_getEnvelopefromDataset(dataset)
99    aggregator=EnvelopeAggregator(env)
100 
101   
102    #set up lists to hold stuff
103    schemeIdentifiers=[]
104    repositoryIdentifiers=[]
105    localIdentifiers=[]
106   
107    #for each file:
108    for f in csmlfilelist:
109        #parse file:
110        dataset=_parsefile(f)
111        #compare envelope:
112        aggregator.compareEnvelope(_getEnvelopefromDataset(dataset))
113        #get other things:
114        schemeIdentifiers.append('NDG-A0')
115        repositoryIdentifiers.append('badc.nerc.ac.uk')
116        localIdentifiers.append(f)
117    #get aggregated envelope:
118    finalEnvelope=aggregator.getAggregatedEnvelope()
119    limitN=finalEnvelope.upperCorner.vals.split()[0]
120    limitS=finalEnvelope.lowerCorner.vals.split()[0]
121    limitE=finalEnvelope.upperCorner.vals.split()[1]
122    limitW=finalEnvelope.lowerCorner.vals.split()[1]
123    #get other aggregations:
124   
125    #write MOLES skeleton document:
126    M=MW.MolesDoc()
127    M._createClasses()
128   
129    ''' The MOLES document:
130    create your moles doc by setting attributes of "M.className"
131    the classNames used must be declared in molesWriter.MolesDoc.classList'''
132   
133    #MetaData ID (need to decide on how to define this)
134    dgMID=M.dgMetadataID(schemeIdentifier='NDG-B0', repositoryIdentifier='badc.nerc.ac.uk', localIdentifier='COAPEC_HadCM3_500Yr')
135   
136    #create data granules
137    datagranules=[]
138    for i, file in enumerate(csmlfilelist):
139        DMid=M.dataModelID(schemeIdentifier=schemeIdentifiers[i], repositoryIdentifier=repositoryIdentifiers[i],localIdentifier= localIdentifiers[i])
140        DG  = M.dgDataGranule(dataModelID=DMid)
141        datagranules.append(DG)
142   
143    #create Data Entity   
144    dgDE= M.dgDataEntity(dgDataGranule=datagranules)
145   
146    #create coverage
147    dgBB=M.dgBoundingBox(LimitNorth = limitN, LimitSouth=limitS,LimitEast=limitE, LimitWest=limitW)
148    dgSc=M.dgSpatialCoverage(dgBoundingBox=dgBB)
149    dgTc=M.dgTemporalCoverage()
150    dgST=M.dgSpatioTemporalCoverage(dgSpatialCoverage = dgSc, dgTemporalCoverage=dgTc)
151    dgCv=M.dgCoverage(dgSpatioTemporalCoverage=dgST)
152   
153    #create metadata record
154    dgMR=M.dgMetadataRecord(dgMetadataID=dgMID, dgDataEntity=dgDE, dgCoverage=dgCv)
155    dgMeta=MW.dgMetadata(dgMetadataRecord=dgMR)
156
157    #produce XML
158    molestree=dgMeta.toXML()
159    #print it out.
160    moles=csml.parser_extra.PrettyPrint(molestree)
161    print moles
162   
163   
164    print finalEnvelope.lowerCorner.vals
165    print finalEnvelope.upperCorner.vals
166    print finalEnvelope.timePosition
167    print finalEnvelope.timePosition2
168   
169if __name__=='__main__':
170    main()
Note: See TracBrowser for help on using the repository browser.