Skip to content
Snippets Groups Projects
labeling.py 39.1 KiB
Newer Older
import sys, os, re, enum
from qgis.gui import *
Benjamin Jakimow's avatar
Benjamin Jakimow committed
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
from eotimeseriesviewer.externals.qps.layerproperties import *
from eotimeseriesviewer.utils import loadUI, qgisInstance
from eotimeseriesviewer.externals.qps.classification.classificationscheme \
    import ClassificationSchemeWidget, ClassificationScheme, ClassInfo, ClassificationSchemeComboBox

from eotimeseriesviewer.timeseries import TimeSeriesDatum
#the QgsProject(s) and QgsMapLayerStore(s) to search for QgsVectorLayers
MAP_LAYER_STORES = [QgsProject.instance()]

CONFKEY_CLASSIFICATIONSCHEME = 'classificationScheme'
    """Enumeration for shortcuts to be derived from a TimeSeriesDatum instance"""
Benjamin Jakimow's avatar
Benjamin Jakimow committed
    Date = 'Date-Time'
    DOY = 'Day of Year (DOY)'
    Year = 'Year'
    DecimalYear = 'Decimal year'
    Sensor = 'Sensor name'
def shortcuts(field:QgsField):
    """
    Returns the possible LabelShortCutTypes for a certain field
    :param fieldName: str
    :return: [list]
    """
    assert isinstance(field, QgsField)

    shortCutsString = [LabelShortcutType.Sensor, LabelShortcutType.Date, LabelShortcutType.Classification]
    shortCutsInt = [LabelShortcutType.Year, LabelShortcutType.DOY, LabelShortcutType.Classification]
    shortCutsFloat = [LabelShortcutType.Year, LabelShortcutType.DOY, LabelShortcutType.DecimalYear, LabelShortcutType.Classification]
    t = field.typeName().lower()
    if t == 'string':
        options.extend(shortCutsString)
        options.extend(shortCutsInt)
        options.extend(shortCutsFloat)
    elif t.startswith('integer'):
        options.extend(shortCutsInt)
    elif t.startswith('real'):
        options.extend(shortCutsInt)
        options.extend(shortCutsFloat)
    else:
        s = ""
    result = []
    for o in options:
        if o not in result:
            result.append(o)
    return result

def layerClassSchemes(layer:QgsVectorLayer)->list:
    assert isinstance(layer, QgsVectorLayer)
    schemes = []
    for i in range(layer.fields().count()):
        setup = layer.editorWidgetSetup(i)
        assert isinstance(setup, QgsEditorWidgetSetup)
        if setup.type() == EDITOR_WIDGET_REGISTRY_KEY:
            cs = setup.config().get(CONFKEY_CLASSIFICATIONSCHEME)
            if isinstance(cs, ClassificationScheme):
                schemes.append(cs)
    return schemes

def labelShortcutLayerClassificationSchemes(layer:QgsVectorLayer):
    """
    Returns the ClassificationSchemes used for labeling shortcuts
    :param layer: QgsVectorLayer
    :return: [list-of-classificationSchemes]
    """
    classSchemes = []
    assert isinstance(layer, QgsVectorLayer)
    for i in range(layer.fields().count()):
        setup = layer.editorWidgetSetup(i)
        assert isinstance(setup, QgsEditorWidgetSetup)
        if setup.type() == EDITOR_WIDGET_REGISTRY_KEY:
            conf = setup.config()
            ci = conf.get(CONFKEY_CLASSIFICATIONSCHEME)
            if isinstance(ci, ClassificationScheme) and ci not in classSchemes:
                classSchemes.add(ci)

    return classSchemes

def labelShortcutLayers()->list:
    """
    Returns a list of all known QgsVectorLayers with at least one LabelShortcutEditWidget
    :return: [list-of-QgsVectorLayer]
    """
    classSchemes = set()
    for store in MAP_LAYER_STORES:
        assert isinstance(store, (QgsProject, QgsMapLayerStore))
        for layer in store.mapLayers().values():
            if isinstance(layer, QgsVectorLayer):
                for i in range(layer.fields().count()):
                    setup = layer.editorWidgetSetup(i)
                    assert isinstance(setup, QgsEditorWidgetSetup)
                    if setup.type() == EDITOR_WIDGET_REGISTRY_KEY:
                        if layer not in layers:
                            layers.append(layer)

def applyShortcutsToRegisteredLayers(tsd:TimeSeriesDatum, classInfos:list):

    for layer in labelShortcutLayers():
        assert isinstance(layer, QgsVectorLayer)
        applyShortcuts(layer, tsd, classInfos)


def applyShortcuts(vectorLayer:QgsVectorLayer, tsd:TimeSeriesDatum, classInfos:dict=None):
    """
    Labels selected features with information related to TimeSeriesDatum tsd, according to
    the settings specified in this model.
    :param tsd: TimeSeriesDatum
    :param classInfos:
    """
    assert isinstance(tsd, TimeSeriesDatum)
    assert isinstance(vectorLayer, QgsVectorLayer)

    assert vectorLayer.isEditable()

    #Lookup-Table for classiicationSchemes
    LUT_Classifications = dict()
    for i in range(vectorLayer.fields().count()):
        field = vectorLayer.fields().at(i)
        setup = vectorLayer.editorWidgetSetup(i)
        assert isinstance(setup, QgsEditorWidgetSetup)
        if setup.type() == EDITOR_WIDGET_REGISTRY_KEY:
            conf = setup.config()
            labelType = conf.get(CONFKEY_LABELTYPE)
            classScheme = conf.get(CONFKEY_CLASSIFICATIONSCHEME)
            if labelType == LabelShortcutType.Classification and isinstance(classScheme, ClassificationScheme):
                LUT_Classifications[i] = classScheme
                LUT_Classifications[classScheme.name()] = classScheme
                LUT_Classifications[field.name()] = classScheme

    for i in range(vectorLayer.fields().count()):
        setup = vectorLayer.editorWidgetSetup(i)
        assert isinstance(setup, QgsEditorWidgetSetup)
        if setup.type() == EDITOR_WIDGET_REGISTRY_KEY:
            field = vectorLayer.fields().at(i)
            assert isinstance(field, QgsField)

            conf = setup.config()
            labelType = conf.get(CONFKEY_LABELTYPE)
            if isinstance(labelType, LabelShortcutType):
                value = None
                if labelType == LabelShortcutType.Sensor:
                    value = tsd.sensor().name()
                elif labelType == LabelShortcutType.DOY:
                    value = tsd.doy()
                elif labelType == LabelShortcutType.Date:
                    value = str(tsd.date())
                elif labelType == LabelShortcutType.DecimalYear:
                    value = tsd.decimalYear()
                elif labelType == LabelShortcutType.Classification:
                    fieldClassScheme = conf.get(CONFKEY_CLASSIFICATIONSCHEME)
                    if isinstance(fieldClassScheme, ClassificationScheme):
                        for ciKey, classInfo in classInfos.items():
                            classScheme = LUT_Classifications.get(ciKey)
                            if classScheme == fieldClassScheme and classInfo in fieldClassScheme:
                                if field.type() == QVariant.String:
                                    value = classInfo.name()
                                else:
                                    value = classInfo.label()
                                break

                if value == None:
                    continue

                if field.type() == QVariant.String:
                    value = str(value)

                for feature in vectorLayer.selectedFeatures():
                    assert isinstance(feature, QgsFeature)
                    oldValue = feature.attribute(field.name())
                    vectorLayer.changeAttributeValue(feature.id(), i, value, oldValue)
Loading
Loading full blame...