source: DPPP/kml/csml2kml/python/csml2kml/csml2kml/WMSCapabilities.py @ 3499

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/DPPP/kml/csml2kml/python/csml2kml/csml2kml/WMSCapabilities.py@3499
Revision 3499, 6.5 KB checked in by mkochan, 12 years ago (diff)

Started writing the WMSCapabilities.BottomWMSLayer.toKML() method. Added (as far empty) class WMSCapabilities.View.

Line 
1from pylab import dates     # a very good date/time module from matplotviz -- allows years < 1970
2
3wmsXmlNamespace = 'http://www.opengis.net/wms'
4
5def wmsLayerFactory(layerElement):
6    '''
7    [DOC]
8    '''
9    name = layerElement.find('{%s}Name' % wmsXmlNamespace).text
10    title = layerElement.find('{%s}Title' % wmsXmlNamespace).text
11    abstract = layerElement.find('{%s}Abstract' % wmsXmlNamespace).text
12    childElements = layerElement.findall('{%s}Layer' % wmsXmlNamespace)
13    childWmsLayers = []
14    for childElement in childElements:
15        childWmsLayer = wmsLayerFactory(childElement)
16        childWmsLayers.append(childWmsLayer)
17    if childElements != []:
18        return WMSLayer(name, title, abstract, childWmsLayers)
19    else:
20        dimensionElements = layerElement.findall('{%s}Dimension' % wmsXmlNamespace)
21        for dimensionElement in dimensionElements:
22            if dimensionElement.get('name') == 'time':
23                times = map( dates.dateutil.parser.parse, dimensionElement.text.split(',') )
24        return BottomWMSLayer(name, title, abstract, times)
25
26class WMSLayer:
27    '''
28    [DOC]
29    '''
30
31    def __init__(self, name, title, abstract, children):
32        self.name = name
33        self.title = title
34        self.abstract = abstract
35        self.children = children
36
37    def parseXML(self, layerElement):
38        raise NotImplementedError('Use the wmsLayerFactory() function instead.')
39
40    def __repr__(self):
41        return str(vars(self))
42
43class BottomWMSLayer(WMSLayer):
44
45    '''[DOC]'''
46   
47    def __init__(self, name, title, abstract, times):
48
49        self.name = name
50        self.title = title
51        self.abstract = abstract
52        # but no self.children
53        self.times = times
54
55    def _parseName(self):
56        (modelName, scenarioName, rest) = self.name.split(':')
57        timespanDesignator = rest.split('/')[0]
58
59        if timespanDesignator == 'clim_20' or timespanDesignator == 'change_20':
60            sampleTimespan = 20
61        elif timespanDesignator == 'clim_30' or timespanDesignator == 'change_30':
62            sampleTimespan = 30
63        else:
64            raise ValueError('Sample timespan designation is incorrect')
65
66        return (modelName, scenarioName, sampleTimespan)
67
68    def getModelName(self):
69        return self._parseName()[0]
70
71    def getScenarioName(self):
72        return self._parseName()[1]
73
74    def getSampleTimespan(self):
75        return self._parseName()[2]
76
77    def toKML(self, views):
78        '''
79        @param views: A list of View objects, which define how we are going to look at the data.
80        @return: a KML.KMLFolder object representing a <kml:Folder> element with lots of <kml:GroundOverlay> elements,
81        each standing for a different time segment.
82        [NOTE] Should replace timeStep with a timedate object?
83        [NOTE] Please! Use dates.datetime all around here -- the self.times are of such type!
84        [NOTE] Let us have this function one the class View is defined:
85                 (startDatetime, endDatetime) = view.getLogicalTimespan(datetime)
86        '''
87
88        def buildWMSRequest(timeStep):
89            ''' Build a WMS request '''
90
91            # We will be using configuration for WMS request
92            c = self.config.find('CSMLGridSeriesFeatureWMSRequest')
93
94            # Set request configuration parameters
95            url = c.find('URL').text
96            serviceVersion = c.find('ServiceVersion').text
97            imageFormat = c.find('ImageFormat').text
98            imageWidth = c.find('ImageWidth').text
99            imageHeight = c.find('ImageHeight').text
100            crs = c.find('CRS').text
101
102            # If timeStep contains a time part, make sure that the "Z" for "Zulu" is appended, as required by WMS
103            if re.search("T\d+\:\d+:\d+(\.\d+)$", timeStep):
104                timeStep = timeStep + 'Z'
105
106            bBox = '-180,-90,180,90'
107           
108            wmsRequest = '%s?request=GetMap&amp;SERVICE=%s&amp;FORMAT=%s&amp;LAYERS=%s&amp;BBOX=%s&amp;WIDTH=%s&amp;HEIGHT=%s&amp;CRS=%s&TIME=%s' % (url, serviceVersion, imageFormat, layerName, bBox, imageWidth, imageHeight, crs, timeStep)
109
110            return wmsRequest
111       
112        # ------------
113
114        for view in views:
115            ...
116            kmlFolder = # representation of time points using this view
117           
118class View:
119    '''
120    Determines how data can be viewed. That is, in practice, how it can be converted into KML so it can be viewed
121    in Google Earth. In particular, it defines logical transforms of time-points into time-spans.
122    '''
123    pass
124
125class WMSCapabilities:
126
127    '''[DOC]'''
128
129    def __init__(self):
130        self.topWmsLayer = None
131
132    def parseXML(self, wmsCapabilitiesElement):
133        topLayerElement = wmsCapabilitiesElement.find('{%s}Capability/{%s}Layer' % (wmsXmlNamespace, wmsXmlNamespace))
134        self.topWmsLayer = wmsLayerFactory(topLayerElement)
135
136    def __repr__(self):
137        if self.topWmsLayer:
138            return '--- WMSCapabilities object with top layer as follows): ' + repr(self.topWmsLayer) + ' ---'
139        else:
140            return '--- WMSCapabilities object with no top layer ---'
141
142class WMSLayersConvertor:
143   
144    def __init__(self, topWmsLayer, config, baseKmlOutputDirectory):
145        self.topWmsLayer = topWmsLayer
146        self.config = config
147        self.baseKmlOutputDirectory = baseKmlOutputDirectory
148        self.maxDirDepth = 10
149        # [a:D,r:DEBUG] self.maxDirDepth = self.config(...)
150       
151    def convert(self):
152
153        def _convertToKML(wmsLayer):
154            return kmlElement
155       
156        def _convertToDirectory(wmsLayer, parentDir, currentLevel):
157           
158            if currentLevel < self.maxDirDepth:
159                currentDir = parentDir + '/' + wmsLayer.name
160                ###os.mkdir(currentDir)
161                print 'Created directory "%s"' % currentDir
162                if not isinstance(wmsLayer, BottomWMSLayer):
163                    for child in wmsLayer.children:
164                        _convertToDirectory(child, currentDir, currentLevel+1)
165            elif currentLevel == self.maxDirDepth:
166                # Create a KML document with no styles
167                ###kmlDocument = KMLDocument(wmsLayer.name, [])   # [?] dir name??
168                ###kmlDocument.elements.append(_convertToKML(wmsLayer))
169                filename = parentDir + '/' + wmsLayer.name + '.kml'
170                ###kmlDocument.save(filename)
171                print 'Saved file "%s"' % filename
172            else:
173                pass
174
175        #### topWmsLayer = wmsLayerFactory(topLayerElement)
176        _convertToDirectory(self.topWmsLayer, self.baseKmlOutputDirectory, 0)
Note: See TracBrowser for help on using the repository browser.