Changes between Version 1 and Version 2 of UsingTheParserToCreateCSMLV2


Ignore:
Timestamp:
25/01/07 13:28:23 (12 years ago)
Author:
domlowe
Comment:

Documented how to create csml using v2 parser.

Legend:

Unmodified
Added
Removed
Modified
  • UsingTheParserToCreateCSMLV2

    v1 v2  
    11 = How to create CSML V2 using the CSML Parser classes = 
    22 
    3 As you will know if you read the [wiki:CSMLV2ParserHowTo other parser how to], the CSML parser creates a python representation of a CSML document, using python classes to represent XML data types. 
     3As you will know if you read the [wiki:CSMLV2ParserHowTo other parser how to] (which hasn't been written yet, but the old one is [wiki:CSMLParserHowTo here], the CSML parser creates a python representation of a CSML document, using python classes to represent XML data types. 
    44 
    55Each parser class has a fromXML() and a toXML() method. The fromXML method takes an XML document (or fragment) and populates the attributes of the python object, the toXML method takes the attributes and structure of the python object and creates an XML !ElementTree fragment. 
     
    154154}}} 
    155155 
    156 So the FeatureCollection (and ReferenceSystemDefinitions etc) are attributes of the Dataset. (Remember when we call the toXML() method on the Dataset, this also calls the toXML() methods of the FeatureCollection, ReferenceSystemDefinitions etc.) 
    157  
    158 Anyway, so the if the aim is to get a fully populated Dataset object, we need to create some feature objects to put in the FeatureCollection. Below we are creating a !PointSeriesFeature: 
     156So the feature collection is as an attribute of the Dataset. (Remember when we call the toXML() method on the Dataset, this also calls the toXML() methods of the !CSMLFeatureCollection, !ReferenceSystemDefinitions etc.) 
     157 
     158If the aim is to get a fully populated Dataset object, we need to create some feature objects to put in the !CSMLFeatureCollection. Below we are creating a !PointSeriesFeature, and building up the constituent parts. 
    159159 
    160160{{{ 
     
    163163# #first we need an empty list to hold the featureMembers 
    164164fms =[] 
    165   
    166  
    167 ##### now create a PointSeriesFeature: ##### 
    168 ##### see how you build up the domain and rangeSet #### 
     165#### create a PointSeriesFeature: ##### 
    169166ptsf=csml.parser.PointSeriesFeature() 
     167 
     168#set the id attribute 
    170169ptsf.id='testbed270401' 
    171 ptsf.description=csml.parser.Description('Station BLUEBIRD') 
    172 ptsd=csml.parser.PointSeriesDomain() 
    173 t=csml.parser.Trajectory() 
    174 t.srsName='urn:EPSG:geographicCRS:4326' 
    175 t.locations=csml.parser.DirectPositionList(vals='0.1 1.5 25') 
    176 t.times=csml.parser.TimePositionList('#pred20060427001','-18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60') 
    177 ptsd.domainReference=t 
    178 ptsf.domain=ptsd 
     170#set the description 
     171#note, as description is an xml element not an attribute it is of type csString: 
     172ptsf.description=csml.parser.csString('Station BLUEBIRD') 
     173 
     174#create a PointSeriesCoverage 
     175ptscvg=csml.parser.PointSeriesCoverage() 
     176 
     177#create a TimeSeriesDomain (appropriate domain for a PointSeriesFeature 
     178ptsd=csml.parser.TimeSeriesDomain() 
     179#create (and populate) a TimePositionList. Using keyword arguements for conciseness. 
     180ptsd.time=csml.parser.TimePositionList(frame='#pred20060427001',CONTENT='-18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60') 
     181     
     182#create a RangeSet 
    179183rs=csml.parser.RangeSet() 
    180 rs.quantityList=csml.parser.MeasureOrNullList('MLUnits.xml#m', '0.27 0.25 0.25 0.23 0.22 0.22 0.21 0.17 0.17 0.14 0.14 0.12 0.10 0.08 0.08 0.08 0.11 0.13 0.11 0.11 0.13 0.10 0.06 0.06 0.06 0.01 -0.03 -0.06 -0.09 -0.11 -0.11 -0.13 -0.16 -0.18 -0.17 -0.16 -0.18 -0.16 -0.12 -0.09 -0.08 -0.07 -0.06 -0.05 -0.04 -0.03 -0.03 -0.04 -0.02 -0.01 -0.02 -0.02 -0.02 -0.03 -0.03 -0.02 -0.01 -0.01 -0.02 -0.02 -0.03 -0.04 -0.04 -0.05 -0.04 -0.05 -0.08 -0.09 -0.11 -0.12 -0.12 -0.12 -0.12 -0.12 -0.13 -0.14 -0.15') 
    181 ptsf.rangeSet=rs 
     184#set the quantityList attribute of the RangeSet to be a MeasureOrNullList containing the values for the rangeSet 
     185rs.quantityList=csml.parser.MeasureOrNullList(uom='MLUnits.xml#m',CONTENT='0.27 0.25 0.25 0.23 0.22 0.22 0.21 0.17 0.17 0.14 0.14 0.12 0.10 0.08 0.08 0.08 0.11 0.13 0.11 0.11 0.13 0.10 0.06 0.06 0.06 0.01 -0.03 -0.06 -0.09 -0.11 -0.11 -0.13 -0.16 -0.18 -0.17 -0.16 -0.18 -0.16 -0.12 -0.09 -0.08 -0.07 -0.06 -0.05 -0.04 -0.03 -0.03 -0.04 -0.02 -0.01 -0.02 -0.02 -0.02 -0.03 -0.03 -0.02 -0.01 -0.01 -0.02 -0.02 -0.03 -0.04 -0.04 -0.05 -0.04 -0.05 -0.08 -0.09 -0.11 -0.12 -0.12 -0.12 -0.12 -0.12 -0.13 -0.14 -0.15') 
     186 
     187#Add the domain and rangeSet as attributes of the coverage 
     188ptscvg.pointSeriesDomain=ptsd 
     189ptscvg.rangeSet=rs 
     190 
     191#set the coverage to be the 'value' of the feature 
     192ptsf.value=ptscvg 
     193 
     194#the parameter of the feature is of type Phenomenon, here href creates "xlink:href=..." 
     195param=csml.parser.Phenomenon(href='CFStandardNames.xml#temperature') 
     196 
     197#set the parameter of the feature to be the parameter just defined 
     198ptsf.parameter=param 
     199}}} 
     200 
     201Now add this feature to the list of features (which will later become the contents of the !CSMLFeatureCollection). 
     202 
     203{{{ 
     204#!python 
     205#append the feature to the list of featureMembers 
    182206fms.append(ptsf) 
    183  
    184207}}} 
    185208 
    186209Okay, so you can create as many features as you like and add them to the fms[] (feature members) list. 
    187 The process for creating file extracts e.g. NetCDFExtract() is very similar. Just instantiate a NetCDFExtract class, and set its attributes (id, variableName, fileName) to the values you want. 
    188 You can then reference the (gml)id of this class from your features.  
    189  
    190 Anyway that was an aside. Now we have a feature or features we need to create a !FeatureCollection object to contain them. This !FeatureCollection object should also contain some bounding box information: 
    191  
    192 {{{ 
    193 #!python 
    194 # #instantiate FeatureCollection object: 
    195 fc=csml.parser.FeatureCollection(members=fms) 
    196 etp = csml.parser.EnvelopeWithTimePeriod() 
    197 etp.lowerCorner=csml.parser.DirectPosition('42 12',uomLabels='deg deg',axisLabels='lat lon') 
    198 etp.upperCorner=csml.parser.DirectPosition('42 26',uomLabels='deg deg',axisLabels='lat lon') 
    199 etp.timePosition='2006-04-26T06:00:00+01' 
    200 etp.timePosition2='2006-04-29T012:00:00+01' 
    201 fc.boundedBy=etp 
    202 }}} 
    203  
    204  
    205 And here is an (empty) example of a !ReferenceSystemDefinition object. Note that !UnitDefinitions and !PhenomenonDefinitions are all handled pretty much the same way. 
    206  
    207  
    208 {{{ 
    209 #!python 
    210 # ###############Reference System Definitions ####################### 
    211 #empty list to hold definitionMembers 
    212 dm=[] 
    213 tc=csml.parser.TimeCoordinateSystem() 
    214 dm.append(tc) 
    215 rsd=csml.parser.ReferenceSystemDefinitions(definitionMembers=dm) 
    216 }}} 
    217  
    218  
    219  
    220 Now we can define some MetaDataProperty(ies)  of the top-level (or root) Dataset object: 
    221 {{{ 
    222 !python 
    223  
    224 #MetaDataProperty Object of <Dataset> 
    225 #list to hold multiple metaDataProperty elements 
    226 mds = [] 
    227  
    228 md = csml.parser.MetaDataProperty() 
    229 md.text=['Data (c) 2006 CCLRC // www.cclrc.ac.uk'] 
    230 mds.append(md) 
    231  
    232 md = csml.parser.MetaDataProperty() 
    233 md.text=['Test for CCLRC'] 
    234 mds.append(md) 
    235 #etc... 
    236 }}} 
    237  
    238  
    239 And now as shown above, we tie everything together by assigning your featureCollection and your definitions and you fileextracts (not shown) to be attributes of the Dataset object: 
    240 {{{ 
    241 #!python 
    242 ########### The Dataset  ############## 
     210 
     211The process for creating file extracts e.g. NetCDFExtract() is very similar. Just instantiate a NetCDFExtract class, and set its attributes (id, variableName, fileName) to the values you want. The file extracts are kept inside a !CSMLStorageDescriptor, which is like a !FeatureCollection. 
     212 
     213Anyway that was an aside. Now we have a feature or features we need to create a !CSMLFeatureCollection object to contain them. 
     214 
     215{{{ 
     216#!python 
     217#instantiate a FeatureCollection object (and add all featureMembers) 
     218fc=csml.parser.CSMLFeatureCollection(featureMembers=fms) 
     219}}} 
     220 
     221 
     222Now we can create the Dataset object: 
     223{{{ 
     224#!python 
    243225#Create an Empty Dataset 
    244226ds = csml.parser.Dataset() 
    245 #Set objects as attributes of dataset 
    246 #NOTE: you can equally write this in the form: ds.id = 'Test001'  as used above. 
    247 setattr(ds,'id','Test001') 
    248 setattr(ds, 'metaDataProperty', mds) 
    249 setattr(ds,'description',csml.parser.Description('This is a test Water level. Period 26/04/06 06h -> 29/04/06 12h')) 
    250 setattr(ds, 'referenceSystemDefinitions', rsd) 
    251 setattr(ds, 'featureCollection',fc) 
    252 ######################################## 
    253 }}} 
    254  
    255  
    256 To generate your CSML file you now need to call the toXML() method of the dataset, and then also run a couple of functions that pretty print the result and fix up ElementTree namespaces. 
    257  
    258 {{{ 
    259 #!python 
     227#set the xml attribute 'id' 
     228ds.id='Test001' 
     229 
     230#set the description element  
     231ds.description=csml.parser.csString('This is a test Water level.Period 26/04/06 06h -> 29/04/06 12h') 
     232 
     233#set the metaDataProperty(s) 
     234#if there is only one metaDataProperty you can just do: 
     235#ds.metaDataProperty=csml.parser.csString('Data (c) 2007 CCLRC // www.cclrc.ac.uk') 
     236 
     237#but if there are several you need to put them in a list: 
     238mdplist=[] 
     239mdp1=csml.parser.csString('Data (c) 2007 CCLRC // www.cclrc.ac.uk') 
     240mdp2=csml.parser.csString('Another CCLRC MetaDataProperty') 
     241mdplist.append(mdp1) 
     242mdplist.append(mdp2) 
     243ds.metaDataProperty=mdplist 
     244}}} 
     245 
     246Note the difference between setting an stringlike XML attribute (id) and a stringlike child element (description). The child element must be a parser object not just a string. As there is no Description() type in the parser it uses the generic csml.parser.csString() which is used for simple elements like gml:description.  
     247 
     248And also note that the metaDataProperty behaviour requires that you create a list if you want multiple metaDataProperties. 
     249 
     250 
     251And now as shown earlier, we tie everything together by assigning your feature collection to be an attribute of the Dataset object: 
     252{{{ 
     253#!python 
     254#now add the featureCollection to the dataset 
     255ds.featureCollection=fc 
     256#finished creating all the python objects! 
     257}}} 
     258 
     259 
     260To generate your XML document you now need to call the toXML() method of the dataset, and then also run a couple of functions that pretty print the result and fix up ElementTree namespaces. 
     261 
     262{{{ 
     263#!python 
     264####### Generating XML ################# 
     265             
    260266#call the toXML method of the Dataset object: 
    261267csmldoc = ds.toXML() 
     
    264270strCSML=csml.parser_extra.removeInlineNS(strCSML) 
    265271print strCSML 
    266 #(you could save this to file instead) 
     272 
     273#(you could save strCSML to a file at this point) 
     274 
    267275}}} 
    268276 
     
    270278That's it. So to recap, all we have done is: 
    271279 
    272  * Created some parser objects - a Dataset, a !FeatureCollection, some Features etc. 
    273  * Set the values of their attributes. 
     280 * Created some parser objects - a Dataset, a !CSMLFeatureCollection, some Features (well, one feature) etc. 
     281 * Set the values of their attributes (and the values of the attributes attributes if the attribute is itself a parser object). 
    274282 * Set these objects to be attributes of the root level Dataset object. 
    275283 * Called the toXML method of the Dataset object.