Skip to content

Commit

Permalink
Finished behavioral testing of interpolated layer and fixed some bugs…
Browse files Browse the repository at this point in the history
… discovered
  • Loading branch information
carolinux committed Feb 28, 2015
1 parent ed78b52 commit b623c70
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 23 deletions.
2 changes: 1 addition & 1 deletion conf.py
Expand Up @@ -15,7 +15,7 @@
NO_INTERPOLATION:False,}
NO_ID_TEXT = "None - every geometry is a position of the same moving object in time"

SAVE_DELIMITER=';' #TODO(v1.6) Replace hardcoded ; with this constant
SAVE_DELIMITER=';'



14 changes: 10 additions & 4 deletions layer_settings.py
Expand Up @@ -8,6 +8,12 @@
import conf
import time_util

def textToBool(text):
if text.lower()=="false":
return False
if text.lower()=="true":
return True
raise Exception("Invalid boolean string {}".format(text))

class LayerSettings:
def __init__(self):
Expand All @@ -25,19 +31,19 @@ def __init__(self):
self.subsetStr = ''

def getSettingsFromSaveStr(saveStr):
l = saveStr.split(';')
l = saveStr.split(conf.SAVE_DELIMITER)
result = LayerSettings()
result.layerId = l[0]
result.layer = QgsMapLayerRegistry.instance().mapLayer(result.layerId) # get the layer
result.startTimeAttribute=l[2]
result.subsetStr = l[1]
result.endTimeAttribute=l[3]
result.isEnabled=bool(l[4])
result.isEnabled=textToBool(l[4])
result.timeFormat=l[5]
try:
result.offset= int(l[6])
result.idAttribute= l[8]
result.interpolationEnabled = bool(l[7])
result.idAttribute= l[7]
result.interpolationEnabled = textToBool(l[8])
except IndexError: # for backwards compatibility
pass # this will use default values
return result
Expand Down
11 changes: 11 additions & 0 deletions qgis_utils.py
Expand Up @@ -17,12 +17,23 @@ def getLayerAttributes(layerId):
return None


def doesLayerNameExist(name):
return getIdFromLayerName(name) is not None

def getIdFromLayerName(layerName):
# Important: If multiple layers with same name exist, it will return the first one it finds
for (id, layer) in QgsMapLayerRegistry.instance().mapLayers().iteritems():
if unicode(layer.name())==layerName:
return id
return None

def getLayerFromLayerName(layerName):
# Important: If multiple layers with same name exist, it will return the first one it finds
for (id, layer) in QgsMapLayerRegistry.instance().mapLayers().iteritems():
if unicode(layer.name())==layerName:
return layer
return None

def getNameFromLayerId(layerId):
layer = QgsMapLayerRegistry.instance().mapLayers()[layerId]
return unicode(layer.name())
Expand Down
16 changes: 16 additions & 0 deletions test/test_layer_settings.py
@@ -0,0 +1,16 @@
__author__ = 'carolinux'

import unittest
from TimeManager import layer_settings


INTERP_SAVESTRING="timespans20150228135607432;;ARRIVAL;ARRIVAL;True;%Y-%m-%d %H:%M:%S;0;;True"
NOINTERP_SAVESTRING="tweets20150228140256944;;T;T;True;%Y-%m-%d %H:%M:%S;0;;False"

class TestLayerSettings(unittest.TestCase):

def test_import_savestring(self):
ls = layer_settings.getSettingsFromSaveStr(INTERP_SAVESTRING)
assert(ls.interpolationEnabled)
ls = layer_settings.getSettingsFromSaveStr(NOINTERP_SAVESTRING)
assert(not ls.interpolationEnabled)
16 changes: 14 additions & 2 deletions test/within_qgis_script.py
Expand Up @@ -26,6 +26,11 @@
def new_project():
iface.newProject()

def load_project(fn):
QgsProject.instance().setFileName(fn)
QgsProject.instance().read()
iface.projectRead.emit()

def get_all_items(combobox):
"""Get all text items of a QtComboBox"""
return [combobox.itemText(i) for i in range(combobox.count())]
Expand Down Expand Up @@ -95,9 +100,10 @@ def addUnmanagedLayerToTm(gui, column,interpolate=False, name=None):
sleep(0.4)
if name is not None:
# dont add the first layer, but the one specified by the name
#FIXME (v1.6): This has timing problems
gui.addLayerDialog.comboBoxLayers.setCurrentIndex(
get_index_of(gui.addLayerDialog.comboBoxLayers,name))
sleep(0.1)
sleep(0.4)

options.pushButtonAdd.clicked.emit(1)
sleep(0.3)
Expand Down Expand Up @@ -197,7 +203,13 @@ def set_time_frame_type(gui,typ):
addUnmanagedLayerToTm(gui, "T",name="tweets")
assert(ls.getSettingsFromLayer(tlm.getTimeLayerList()[0]).interpolationEnabled == True)
assert(len(get_all_layer_names())==3)
# TODO: save project, reload, see if everything is as expected
tmp_file = get_temp_file().name
tmp_file="/tmp/foo.qgs"
save_project_to_file(tmp_file)
new_project()
load_project(tmp_file)
assert(len(get_all_layer_names())==3)




Expand Down
11 changes: 4 additions & 7 deletions timelayermanager.py
Expand Up @@ -251,11 +251,9 @@ def getSaveString(self):
except:
return (None,None)

saveString = datetime_to_str(self.getProjectTimeExtents()[0], tdfmt) + ';'
saveString += datetime_to_str(self.getProjectTimeExtents()[1], tdfmt) + ';'

saveString += datetime_to_str(self.getCurrentTimePosition(), tdfmt) + ';'
##self.debug("save string:"+saveString)
saveString = conf.SAVE_DELIMITER.join([datetime_to_str(self.getProjectTimeExtents()[0],tdfmt),
datetime_to_str(self.getProjectTimeExtents()[1], tdfmt),
datetime_to_str(self.getCurrentTimePosition())])
for timeLayer in self.getTimeLayerList():
saveListLayers.append(timeLayer.getSaveString())

Expand All @@ -265,7 +263,7 @@ def restoreFromSaveString(self, saveString):
"""restore settings from loaded project file"""
tdfmt = SAVE_STRING_FORMAT
if saveString:
saveString = str(saveString).split(';')
saveString = str(saveString).split(conf.SAVE_DELIMITER)
try:
timeExtents = (str_to_datetime(saveString[0], tdfmt),
str_to_datetime(saveString[1], tdfmt))
Expand All @@ -284,4 +282,3 @@ def restoreFromSaveString(self, saveString):
pos = str_to_datetime(saveString[2], tdfmt)
##self.debug("tlmanager: set current time position to:"+str(pos))
self.setCurrentTimePosition(pos)
return saveString[3]
2 changes: 1 addition & 1 deletion timemanagercontrol.py
Expand Up @@ -472,6 +472,7 @@ def restoreSettingTimeLayerManager(self,value):
def restoreTimeLayers(self, layerInfos):
"""restore all time layers"""
if layerInfos:
QgsMessageLog.logMessage("layerinfos:"+str(layerInfos))
if len(layerInfos)>0:
self.guiControl.enableAnimationExport()
for l in layerInfos: # for every layer entry
Expand Down Expand Up @@ -510,7 +511,6 @@ def saveOptions(self):
self.setAnimationOptions(animationFrameLength,playBackwards,loopAnimation)
self.guiControl.exportEmpty = not \
self.guiControl.optionsDialog.checkBoxDontExportEmpty.isChecked()
QgsMessageLog.logMessage("")
self.guiControl.showLabel = self.guiControl.optionsDialog.checkBoxLabel.isChecked()
self.guiControl.refreshMapCanvas('saveOptions')
self.guiControl.dock.pushButtonExportVideo.setEnabled(True)
Expand Down
3 changes: 2 additions & 1 deletion timerasterlayer.py
Expand Up @@ -10,6 +10,7 @@
from qgis.core import *
from timelayer import *
from time_util import SUPPORTED_FORMATS, DEFAULT_FORMAT, strToDatetimeWithFormatHint, getFormatOfDatetimeValue
import conf

class TimeRasterLayer(TimeLayer):
def __init__(self, settings, iface=None):
Expand Down Expand Up @@ -85,7 +86,7 @@ def hasTimeRestriction(self):

def getSaveString(self):
"""get string to save in project file"""
delimiter = ';'
delimiter = conf.SAVE_DELIMITER
saveString = self.getLayerId() + delimiter
saveString += '' + delimiter
saveString += self.fromTimeAttribute + delimiter
Expand Down
19 changes: 12 additions & 7 deletions timevectorinterpolatedlayer.py
Expand Up @@ -18,10 +18,6 @@
#TODO: Just points types? What about lines or polygon move?
#TODO: What about toTimeAttribute and interpolation? Right now it's ignored

# Testing
#TODO(v1.6): Scenario where 2 layers (one with interpolation and one without) are added and
# restored

# Cleaning up
#TODO(v1.6) delete logging msgs when done testing

Expand All @@ -30,6 +26,17 @@ class TimeVectorInterpolatedLayer(TimeVectorLayer):
def isInterpolationEnabled(self):
return True

def getMemLayer(self):
"""When restoring a project, the layer will already exist, so we shouldn't
create a new one"""
name = "interpolated_points_for_{}".format(self.layer.id())
if not qgs.doesLayerNameExist(name): #FIXME this will not work if the user renames the memory layer
memLayer = QgsVectorLayer("Point?crs=epsg:4326&index=yes",name, "memory")
else:
memLayer = qgs.getLayerFromLayerName(name)
return memLayer


def __init__(self,settings, iface):
TimeVectorLayer.__init__(self,settings,iface=iface)
try:
Expand All @@ -43,9 +50,7 @@ def __init__(self,settings, iface):
raise Exception("Want point geometry!")
self.idAttribute = settings.idAttribute

self.memLayer = QgsVectorLayer("Point?crs=epsg:4326&index=yes",
"interpolated_points_for_{}".format(
self.layer.name()), "memory")
self.memLayer = self.getMemLayer()

# adjust memLayer to have same crs and same color as original layer, only half transparent
self.memLayer.setCrs(self.layer.crs())
Expand Down

0 comments on commit b623c70

Please sign in to comment.