Commit b1153b61 authored by Benjamin Jakimow's avatar Benjamin Jakimow
Browse files

temporalprofiles.py - cleaned QgsTask


Signed-off-by: Benjamin Jakimow's avatarBenjamin Jakimow <benjamin.jakimow@geo.hu-berlin.de>
parent 8855a694
Pipeline #12415 failed
......@@ -88,6 +88,7 @@ try:
except:
pass
def temporalProfileFeatureFields(sensor: SensorInstrument, singleBandOnly=False) -> QgsFields:
"""
Returns the fields of a single temporal profile
......@@ -108,6 +109,7 @@ def temporalProfileFeatureFields(sensor: SensorInstrument, singleBandOnly=False)
return fields
def sensorExampleQgsFeature(sensor:SensorInstrument, singleBandOnly=False) -> QgsFeature:
"""
Returns an exemplary QgsFeature with value for a specific sensor
......@@ -135,6 +137,7 @@ def sensorExampleQgsFeature(sensor:SensorInstrument, singleBandOnly=False) -> Qg
f.setAttribute(bandKey, 1.0)
return f
def geometryToPixel(ds:gdal.Dataset, geometry: QgsGeometry) -> typing.Tuple[list, list]:
"""
Returns the pixel-positions of pixels whose pixel center is covered by a geometry
......@@ -191,12 +194,12 @@ def geometryToPixel(ds:gdal.Dataset, geometry: QgsGeometry) -> typing.Tuple[list
return x_indices, y_indices
def dateDOY(date):
if isinstance(date, np.datetime64):
date = date.astype(datetime.date)
return date.timetuple().tm_yday
def daysPerYear(year):
if isinstance(year, np.datetime64):
......@@ -206,6 +209,7 @@ def daysPerYear(year):
return dateDOY(datetime.date(year=year, month=12, day=31))
def date2num(d):
#kindly taken from https://stackoverflow.com/questions/6451655/python-how-to-convert-datetime-dates-to-decimal-years
if isinstance(d, np.datetime64):
......@@ -223,6 +227,7 @@ def date2num(d):
fraction = 0.9999999
return float(d.year) + fraction
def num2date(n, dt64=True, qDate=False):
n = float(n)
if n < 1:
......@@ -732,11 +737,11 @@ class TemporalProfileLayer(QgsVectorLayer):
if len(qgsTask.MISSING_DATA) == 0:
return
tid = id(qgsTask)
self.mTasks[tid] = qgsTask
#tid = id(qgsTask)
#self.mTasks[tid] = qgsTask
qgsTask.taskCompleted.connect(lambda *args, t=tid: self.onRemoveTask(t))
qgsTask.taskTerminated.connect(lambda *args, t=tid: self.onRemoveTask(t))
#qgsTask.taskCompleted.connect(lambda *args, t=tid: self.onRemoveTask(t))
#qgsTask.taskTerminated.connect(lambda *args, t=tid: self.onRemoveTask(t))
if run_async:
tm = QgsApplication.taskManager()
......@@ -1024,6 +1029,7 @@ class TemporalProfileLayer(QgsVectorLayer):
#self.sensorPxLayers.clear()
pass
class TemporalProfileLoaderTask(QgsTask):
"""
A QgsTask to load pixel-band values from different Time Series Source images and
......@@ -1036,15 +1042,15 @@ class TemporalProfileLoaderTask(QgsTask):
required_profiles: typing.List[TemporalProfile] = None,
required_sensor_bands: typing.Dict[SensorInstrument, typing.List[int]] = None,
callback=None,
block_size: int=10):
progress_interval: int = 10):
super().__init__(description='Load Temporal Profiles')
assert isinstance(block_size, int) and block_size > 0
assert isinstance(progress_interval, int) and progress_interval > 0
assert isinstance(temporalProfileLayer, TemporalProfileLayer)
timeSeries: TimeSeries = temporalProfileLayer.timeSeries()
self.nTotal = len(timeSeries)
self.mProgressInterval = datetime.timedelta(seconds=progress_interval)
self.mRequiredSensorBands: typing.Dict[SensorInstrument, typing.List[int]] = dict()
self.mRequiredSensorBandKeys: typing.Dict[SensorInstrument, typing.List[str]] = dict()
self.mTSS2TSD = dict()
......@@ -1061,7 +1067,7 @@ class TemporalProfileLoaderTask(QgsTask):
self.mRequiredSensorBands[sensor] = sorted(band_indices)
for band_index in self.mRequiredSensorBands[sensor]:
assert isinstance(band_index, int)
assert band_index >= 0 and band_index < sensor.nb
assert 0 <= band_index < sensor.nb
for sensor, band_indices in self.mRequiredSensorBands.items():
self.mRequiredSensorBandKeys[sensor] = [bandIndex2bandKey(i) for i in band_indices]
......@@ -1111,7 +1117,6 @@ class TemporalProfileLoaderTask(QgsTask):
self.GEOMETRY_CACHE[tp.id()][crsWKT] = tp.geometry(crs)
self.mCallback = callback
self.mBlockSize = block_size
def profileIDs(self) -> typing.List[int]:
return list(self.MISSING_DATA.keys())
......@@ -1126,8 +1131,8 @@ class TemporalProfileLoaderTask(QgsTask):
block_results = []
n_total = len(self.timeSeriesSources())
next_progress = 5
t0 = datetime.datetime.now()
try:
for n, tss in enumerate(self.timeSeriesSources()):
assert isinstance(tss, TimeSeriesSource)
......@@ -1143,6 +1148,8 @@ class TemporalProfileLoaderTask(QgsTask):
INTERSECTING[tpID] = geom
else:
print('Missing geometry for crsWKT={}\nTSS={}\n'.format(tss.crsWkt(), tss.uri()))
del geom, GEOM
if len(INTERSECTING) == 0:
continue
......@@ -1156,8 +1163,11 @@ class TemporalProfileLoaderTask(QgsTask):
if len(px_x) > 0:
PX_INDICES[tpID] = (px_x, px_y)
del tpID, geom
if len(PX_INDICES) == 0:
# profiles are out of image
del PX_INDICES
continue
# create a dictionary that tells us which pixels / TPs positions are to load from which band
......@@ -1171,6 +1181,7 @@ class TemporalProfileLoaderTask(QgsTask):
required_band_profiles[band_key] = set()
required_band_profiles[band_key].add(tpID)
del missingTSDValues
# load required bands and required pixel positions only
for band_key, tpIds in required_band_profiles.items():
......@@ -1194,22 +1205,36 @@ class TemporalProfileLoaderTask(QgsTask):
if band.GetNoDataValue():
block = block[np.where(block != band.GetNoDataValue())]
if len(block) == 0:
del block
continue
# get mean pixel value
value = np.nanmean(block)
del block
if np.isfinite(value):
self.MISSING_DATA[tpID][tsd][band_key] = value
del band
del required_band_profiles
if self.isCanceled():
self.mErrors.append('Canceled')
return False
progress = 100 * n / n_total
if progress >= next_progress:
dt = datetime.datetime.now() - t0
if dt > self.mProgressInterval:
t0 = datetime.datetime.now()
progress = 100 * n / n_total
self.setProgress(progress)
next_progress += 5
del INTERSECTING
del PX_INDICES
del ds
del ext
del tsd
del tss
s = ""
except Exception as ex:
print(traceback.format_exc())
......@@ -1227,6 +1252,7 @@ class TemporalProfileLoaderTask(QgsTask):
if self.mCallback is not None:
self.mCallback(result, self)
class TemporalProfileTableModel(QgsAttributeTableModel):
AUTOGENERATES_COLUMNS = [FN_ID, FN_Y, FN_X]
......@@ -1308,7 +1334,6 @@ class TemporalProfileTableModel(QgsAttributeTableModel):
return result
def headerData(self, section:int, orientation:Qt.Orientation, role:int):
data = super(TemporalProfileTableModel, self).headerData(section, orientation, role)
if role == Qt.ToolTipRole and orientation == Qt.Horizontal:
......@@ -1327,7 +1352,6 @@ class TemporalProfileTableModel(QgsAttributeTableModel):
def supportedDropActions(self):
return Qt.CopyAction | Qt.MoveAction
def supportedDragActions(self):
return Qt.CopyAction
......@@ -1349,10 +1373,7 @@ class TemporalProfileTableModel(QgsAttributeTableModel):
class TemporalProfileFeatureSelectionManager(QgsIFeatureSelectionManager):
def __init__(self, layer, parent=None):
s =""
super(TemporalProfileFeatureSelectionManager, self).__init__(parent)
assert isinstance(layer, QgsVectorLayer)
self.mLayer = layer
......@@ -1373,9 +1394,8 @@ class TemporalProfileFeatureSelectionManager(QgsIFeatureSelectionManager):
self.mLayer.select(ids)
def selectFeatures(self, selection, command):
super(TemporalProfileFeatureSelectionManager, self).selectFeatures(selection, command)
super(TemporalProfileFeatureSelectionManager, self).selectF
s = ""
def selectedFeatureCount(self):
return self.mLayer.selectedFeatureCount()
......
......@@ -104,7 +104,7 @@ class TestMain(EOTSVTestCase):
TSV = EOTimeSeriesViewer()
TSV.createMapView('True Color')
TSV.loadExampleTimeSeries()
TSV.loadExampleTimeSeries(loadAsync=True)
while QgsApplication.taskManager().countActiveTasks() > 0 or len(TSV.timeSeries().mTasks) > 0:
QCoreApplication.processEvents()
......
Supports Markdown
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