From dd72c3076b0cc94d405584166bd3ee60f0a88e3c Mon Sep 17 00:00:00 2001 From: carolinux Date: Thu, 9 Jul 2015 22:21:27 +0300 Subject: [PATCH] Added experimental WMTS support #132 --- raster/wmstlayer.py | 40 ++++++++++++++++++++++++++-------------- time_util.py | 4 +++- timelayerfactory.py | 3 +++ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/raster/wmstlayer.py b/raster/wmstlayer.py index b2de2e1..72972aa 100644 --- a/raster/wmstlayer.py +++ b/raster/wmstlayer.py @@ -14,9 +14,9 @@ class WMSTRasterLayer(TimeRasterLayer): def __init__(self, settings, iface=None): TimeLayer.__init__(self,settings.layer, settings.isEnabled) - self.fromTimeAttribute = "From WMST time attribute" - self.toTimeAttribute = self.fromTimeAttribute - self.timeFormat = "%Y-%m-%dT%H:%M:%SZ" + self.fromTimeAttribute = settings.startTimeAttribute + self.toTimeAttribute = settings.endTimeAttribute + self.timeFormat = self.determine_format(settings.startTimeAttribute, settings.timeFormat) self.offset = int(settings.offset) self.originalUri = self.layer.dataProvider().dataSourceUri() try: @@ -24,34 +24,46 @@ def __init__(self, settings, iface=None): except NotATimeAttributeError, e: raise InvalidTimeLayerError(e) + def _get_wmts_layer_name(): + return self.layer.subLayers(0) + def _get_time_extents_from_uri(self): - # url = http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?&SERVICE=WMS&REQUEST=GetCapabilities - pass + # TODO get url from original uri + url = "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?&SERVICE=WMS&REQUEST=GetCapabilities" + # TODO get extents from the xml somehow + import urllib2 + raw_xml = urllib2.urlopen(url).read() + name = self._get_wmts_layer_name() + return None,None def getTimeExtents(self): - p = self.layer.dataProvider() - - startTime = # ??? how to get minimum and maximum time from wmst? - endTime = # ??? + startTime, endTime =time_util.str_to_datetime(self.fromTimeAttribute, self.timeFormat),\ + time_util.str_to_datetime(self.toTimeAttribute, self.timeFormat) startTime += timedelta(seconds=self.offset) endTime += timedelta(seconds=self.offset) return (startTime,endTime) + def addUrlMark(self): + if "?" in self.originalUri: + return "&" + else: + return "?" + def setTimeRestriction(self,timePosition,timeFrame): """Constructs the query, including the original subset""" if not self.timeEnabled: self.deleteTimeRestriction() return startTime = timePosition + timedelta(seconds=self.offset) - endTime = timePosition + timeFrame + timedelta(seconds=self.offset) # end time is ignored here, what else to do? - # the ? could be a problem - self.layer.dataProvider().setDataSourceUri(IGNORE_PREFIX+\ - self.originalUri+"?&TIME%3D{}".format(time_util.datetime_to_str(startTime,self.timeFormat))) + endTime = timePosition + timeFrame + timedelta(seconds=self.offset) + self.layer.dataProvider().setDataSourceUri(self.IGNORE_PREFIX+\ + self.originalUri + self.addUrlMark() + "TIME={}/{}"\ + .format(time_util.datetime_to_str(startTime,self.timeFormat),time_util.datetime_to_str(endTime,self.timeFormat))) self.layer.dataProvider().reloadData() def deleteTimeRestriction(self): """The layer is removed from Time Manager and is therefore always shown""" self.layer.dataProvider().setDataSourceUri(self.originalUri) self.layer.dataProvider().reloadData() - #self.layer.triggerRepaint() + self.layer.triggerRepaint() diff --git a/time_util.py b/time_util.py index 333d512..6f22b40 100644 --- a/time_util.py +++ b/time_util.py @@ -118,6 +118,7 @@ def generate_all_timezones(fmt): "%Y-%m-%d %H:%M", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%SZ", +"%Y-%m-%dT%HZ", "%Y-%m-%d", "%Y/%m/%d %H:%M:%S.%f", "%Y/%m/%d %H:%M:%S", @@ -137,8 +138,9 @@ def generate_all_timezones(fmt): DMY_SUPPORTED_FORMATS = map(lambda x: _str_switch(x,"%Y","%d"), YMD_SUPPORTED_FORMATS) MDY_SUPPORTED_FORMATS = map(lambda x: _str_switch(x,"%m","%d"), DMY_SUPPORTED_FORMATS) +OTHER_FORMATS = ["%Y-%m"] -SUPPORTED_FORMATS = list(YMD_SUPPORTED_FORMATS + MDY_SUPPORTED_FORMATS + DMY_SUPPORTED_FORMATS) +SUPPORTED_FORMATS = list(YMD_SUPPORTED_FORMATS + MDY_SUPPORTED_FORMATS + DMY_SUPPORTED_FORMATS + OTHER_FORMATS) def is_date_object(val): return isinstance(val, datetime) or isinstance(val, bcdate_util.BCDate) diff --git a/timelayerfactory.py b/timelayerfactory.py index 4a8b0db..0cb2bed 100644 --- a/timelayerfactory.py +++ b/timelayerfactory.py @@ -6,6 +6,7 @@ from timerasterlayer import TimeRasterLayer from timevectorinterpolatedlayer import TimeVectorInterpolatedLayer from raster.cdflayer import CDFRasterLayer +from raster.wmstlayer import WMSTRasterLayer import time_util @@ -21,6 +22,8 @@ def get_timelayer_class_from_settings(cls, settings): elif type(layer) == QgsVectorLayer and interpolate: return TimeVectorInterpolatedLayer elif type(layer) == QgsRasterLayer: + if "Web Map Service" in layer.dataProvider().description(): + return WMSTRasterLayer if isNetCDF: return CDFRasterLayer else: