Commit 8855a694 authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files

refactoring


MapView.removeSensor() - fixed dict.pop key error
timeseries.py:
- QgsTasks report progress on time difference
- QgsTasks run cleanup
Signed-off-by: Benjamin Jakimow's avatarBenjamin Jakimow <benjamin.jakimow@geo.hu-berlin.de>
parent 7507aa97
......@@ -43,6 +43,7 @@ import fnmatch
import site
import re
import pathlib
from qgis.core import QgsApplication, Qgis
from qgis.PyQt.QtGui import QIcon
......@@ -60,15 +61,17 @@ PATH_ABOUT = DIR_REPO / 'ABOUT.html'
DIR_QGIS_RESOURCES = DIR_REPO / 'qgisresources'
URL_QGIS_RESOURCES = r'https://bitbucket.org/jakimowb/qgispluginsupport/downloads/qgisresources.zip'
def debugLog(msg: str):
if DEBUG:
print('DEBUG:' + msg, flush=True)
# import QPS modules
# skip imports when on RTD, as we can not install the full QGIS environment as required
# https://docs.readthedocs.io/en/stable/builds.html
if not os.environ.get('READTHEDOCS') in ['True', 'TRUE', True]:
if True and not os.environ.get('READTHEDOCS') in ['True', 'TRUE', True]:
debugLog('load crosshair')
from .externals.qps.crosshair.crosshair import CrosshairStyle, CrosshairWidget, CrosshairMapCanvasItem, \
CrosshairDialog, getCrosshairStyle
......@@ -116,7 +119,6 @@ def initResources():
initQtResources(pathlib.Path(__file__).parent)
def initEditorWidgets():
"""
Initialises QgsEditorWidgets
......
......@@ -1540,7 +1540,7 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
return vectorLayers
def addTimeSeriesImages(self, files: list, loadAsync=True):
def addTimeSeriesImages(self, files: list, loadAsync:bool=True):
"""
Adds images to the time series
:param files:
......@@ -1550,9 +1550,11 @@ class EOTimeSeriesViewer(QgisInterface, QObject):
defDir = s.value('dir_datasources')
filters = QgsProviderRegistry.instance().fileRasterFilters()
files, filter = QFileDialog.getOpenFileNames(
directory=defDir,
filter=filters,
parent=self.ui,
# options=QFileDialog.DontUseNativeDialog #none-native is too slow
)
......
......@@ -587,8 +587,8 @@ class MapView(QFrame):
:param sensor:
:return:
"""
self.mInitialStretch.pop(sensor)
if sensor in self.mInitialStretch.keys():
self.mInitialStretch.pop(sensor)
toRemove = []
for t in self.mSensorLayerList:
......
......@@ -1127,17 +1127,16 @@ class TimeSeriesFindOverlapTask(QgsTask):
callback=None,
description='Calculate image pixel overlap',
sampleSize: int = 25,
block_size=25):
progress_interval: int = 2):
super().__init__(description=description)
assert block_size >= 1
assert sampleSize >= 1
assert progress_interval >= 1
assert isinstance(extent, SpatialExtent)
self.mBlockSize: int = block_size
self.mTSS: typing.List[str] = [tss.uri() for tss in timeSeriesSources]
self.mCallback = callback
self.mTargetExtent = extent.__copy__()
self.mSampleSize = sampleSize
self.mProgressInterval = datetime.timedelta(seconds=progress_interval)
self.mIntersections: typing.Dict[str, bool] = dict()
self.mError = None
......@@ -1160,7 +1159,6 @@ class TimeSeriesFindOverlapTask(QgsTask):
n = len(self.mTSS)
t0 = datetime.datetime.now()
report_delay = datetime.timedelta(seconds=2)
for i, tssUri in enumerate(self.mTSS):
if self.isCanceled():
......@@ -1175,35 +1173,45 @@ class TimeSeriesFindOverlapTask(QgsTask):
continue
if not targetExtent2.intersects(tss.spatialExtent()):
del targetExtent2
continue
lyr: QgsRasterLayer = tss.asRasterLayer()
del tss
if not isinstance(lyr, QgsRasterLayer):
continue
dp: QgsRasterDataProvider = lyr.dataProvider()
stats: QgsRasterBandStats = dp.bandStatistics(1,
stats: QgsRasterBandStats = lyr.dataProvider().bandStatistics(1,
stats=QgsRasterBandStats.Range,
extent=targetExtent2,
sampleSize=self.mSampleSize)
del lyr
if not isinstance(stats, QgsRasterBandStats):
continue
self.mIntersections[tssUri] = (stats.minimumValue, stats.maximumValue) != (emptyMin, emptyMax)
del stats
del targetExtent2
progress = int(100 * (i + 1) / n)
dt = datetime.datetime.now() - t0
if dt > report_delay:
if dt > self.mProgressInterval:
self.sigTimeSeriesSourceOverlap.emit(self.mIntersections.copy())
self.mIntersections.clear()
self.setProgress(progress)
#self.sigTimeSeriesSourceOverlap.emit(self.mIntersections)
#self.mIntersections.clear()
t0 = datetime.datetime.now()
except Exception as ex:
self.mError = ex
return False
#self.sigTimeSeriesSourceOverlap.emit(self.mIntersections)
if len(self.mIntersections) > 0:
self.sigTimeSeriesSourceOverlap.emit(self.mIntersections.copy())
self.mIntersections.clear()
del targetCRS
del extentLookup
return True
def canCancel(self) -> bool:
......@@ -1212,7 +1220,6 @@ class TimeSeriesFindOverlapTask(QgsTask):
def finished(self, result):
if self.mCallback is not None:
self.mCallback(result, self)
#print('Finished', flush=True)
class TimeSeriesLoadingTask(QgsTask):
......@@ -1223,14 +1230,18 @@ class TimeSeriesLoadingTask(QgsTask):
files: typing.List[str],
description: str = "Load Images",
callback=None,
block_size: int = 50):
progress_interval: int = 3):
super().__init__(description=description)
self.mFiles = files
self.mSources = []
assert progress_interval >= 1
self.mFiles: typing.List[str] = files
self.mSources: typing.List[TimeSeriesSource] = []
self.mProgressInterval = datetime.timedelta(seconds=progress_interval)
self.mCallback = callback
self.mResultBlockSize = block_size
self.mInvalidSources = []
self.mInvalidSources: typing.List[typing.Tuple[str, Exception]] = []
self.mError: Exception = None
def canCancel(self) -> bool:
return True
......@@ -1238,32 +1249,42 @@ class TimeSeriesLoadingTask(QgsTask):
def run(self) -> bool:
result_block = []
n = len(self.mFiles)
next_progress = 10
for i, path in enumerate(self.mFiles):
assert isinstance(path, str)
try:
tss = TimeSeriesSource.create(path)
assert isinstance(tss, TimeSeriesSource)
self.mSources.append(tss)
result_block.append(tss)
except Exception as ex:
self.mInvalidSources.append((path, ex))
if len(result_block) >= self.mResultBlockSize:
self.sigFoundSources.emit(result_block[:])
result_block.clear()
if self.isCanceled():
return False
t0 = datetime.datetime.now()
try:
for i, path in enumerate(self.mFiles):
assert isinstance(path, str)
if self.isCanceled():
return False
progress = int(100 * (i + 1) / n)
if progress > next_progress:
self.setProgress(progress)
next_progress += 10
try:
tss = TimeSeriesSource.create(path)
assert isinstance(tss, TimeSeriesSource)
self.mSources.append(tss)
result_block.append(tss)
del tss
except Exception as ex:
self.mInvalidSources.append((path, ex))
if self.isCanceled():
return False
dt = datetime.datetime.now() - t0
if dt > self.mProgressInterval:
progress = int(100 * (i + 1) / n)
self.setProgress(progress)
self.sigFoundSources.emit(result_block[:])
result_block.clear()
if len(result_block) > 0:
self.sigFoundSources.emit(result_block[:])
result_block.clear()
except Exception as ex:
self.mError = ex
return False
if len(result_block) > 0:
self.sigFoundSources.emit(result_block[:])
return True
def finished(self, result):
......@@ -1355,16 +1376,10 @@ class TimeSeries(QAbstractItemModel):
qgsTask = TimeSeriesFindOverlapTask(ext,
tssToTest,
sampleSize=value(Keys.RasterOverlapSampleSize),
block_size=value(Keys.QgsTaskBlockSize),
callback=self.onTaskFinished)
tid = id(qgsTask)
#self.mTasks[tid] = qgsTask
qgsTask.sigTimeSeriesSourceOverlap.connect(self.onFoundOverlap)
qgsTask.progressChanged.connect(self.sigProgress.emit)
#qgsTask.sigTimeSeriesSourceOverlap.connect(self.onFoundOverlap)
qgsTask.taskCompleted.connect(lambda *args, _tid=tid: self.onRemoveTask(_tid))
qgsTask.taskTerminated.connect(lambda *args, _tid=tid: self.onRemoveTask(_tid))
if runAsync:
tm = QgsApplication.taskManager()
......@@ -1762,8 +1777,12 @@ class TimeSeries(QAbstractItemModel):
return None
def addTimeSeriesSources(self, sources: typing.List[TimeSeriesSource]):
"""
Adds a list of time series sources to the time series
:param sources: list-of-TimeSeriesSources
"""
assert isinstance(sources, list)
print('Add TSS...', flush=True)
# print('Add TSS...', flush=True)
addedDates = []
for i, source in enumerate(sources):
assert isinstance(source, TimeSeriesSource)
......@@ -1799,12 +1818,11 @@ class TimeSeries(QAbstractItemModel):
qgsTask = TimeSeriesLoadingTask(sourcePaths,
callback=self.onTaskFinished,
# block_size=value(Keys.QgsTaskBlockSize)
)
tid = id(qgsTask)
self.mTasks[tid] = qgsTask
qgsTask.taskCompleted.connect(lambda *args, tid=tid: self.onRemoveTask(tid))
qgsTask.taskTerminated.connect(lambda *args, tid=tid: self.onRemoveTask(tid))
#tid = id(qgsTask)
#self.mTasks[tid] = qgsTask
#qgsTask.taskCompleted.connect(lambda *args, tid=tid: self.onRemoveTask(tid))
#qgsTask.taskTerminated.connect(lambda *args, tid=tid: self.onRemoveTask(tid))
qgsTask.sigFoundSources.connect(self.addTimeSeriesSources)
qgsTask.progressChanged.connect(self.sigProgress.emit)
......@@ -1835,6 +1853,7 @@ class TimeSeries(QAbstractItemModel):
if success and len(task.mIntersections) > 0:
self.onFoundOverlap(task.mIntersections)
def addTimeSeriesSource(self, source: TimeSeriesSource) -> TimeSeriesDate:
"""
:param source:
......
......@@ -127,7 +127,7 @@ def create_plugin(include_testdata: bool = False,
MD.mVersion = BUILD_NAME
MD.writeMetadataTxt(PATH_METADATAFILE)
#1. (re)-compile all resource files
# 1. (re)-compile all resource files
from scripts.compile_resourcefiles import compileEOTSVResourceFiles
compileEOTSVResourceFiles()
......@@ -152,7 +152,7 @@ def create_plugin(include_testdata: bool = False,
os.makedirs(fileDst.parent, exist_ok=True)
shutil.copy(fileSrc, fileDst.parent)
#update metadata version
# update metadata version
f = open(DIR_REPO / 'eotimeseriesviewer' / '__init__.py')
lines = f.read()
......@@ -188,20 +188,21 @@ def create_plugin(include_testdata: bool = False,
info.append('from pyplugin_installer.installer import pluginInstaller')
info.append('pluginInstaller.installFromZipFile(r"{}")'.format(PLUGIN_ZIP))
info.append('#### Close (and restart manually)\n')
#print('iface.mainWindow().close()\n')
# print('iface.mainWindow().close()\n')
info.append('QProcess.startDetached(QgsApplication.arguments()[0], [])')
info.append('QgsApplication.quit()\n')
info.append('## press ENTER\n')
print('\n'.join(info))
#cb = QGuiApplication.clipboard()
#if isinstance(cb, QClipboard):
# cb = QGuiApplication.clipboard()
# if isinstance(cb, QClipboard):
# cb.setText('\n'.join(info))
print('Finished')
return PLUGIN_ZIP.as_posix()
def rst2html(pathMD: pathlib.Path) -> str:
"""
Convert a rst file to html
......@@ -286,7 +287,8 @@ if __name__ == "__main__":
parser.add_argument('-l', '--latest',
required=False,
help='Name the output zip like timeseriesviewer.<branch name>.latest.zip, e.g. for generic uploads',
help='Name the output zip like timeseriesviewer.<branch name>.latest.zip,'
'e.g. for generic uploads',
default=None,
action='store_true')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment