Newer
Older

Benjamin Jakimow
committed
# -*- coding: utf-8 -*-
"""
***************************************************************************
classificationscheme.py
Methods and Objects to describe raster classifications
---------------------
Date : Juli 2017
Copyright : (C) 2017 by Benjamin Jakimow
Email : benjamin.jakimow@geo.hu-berlin.de
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""

Benjamin Jakimow
committed
from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
import numpy as np
from osgeo import gdal
from qps.utils import gdalDataset, nextColor, loadUIFormClass, findMapLayer, registeredMapLayers

Benjamin Jakimow
committed
loadClassificationUI = lambda name: loadUIFormClass(os.path.join(os.path.dirname(__file__), name))
DEFAULT_UNCLASSIFIEDCOLOR = QColor('black')
DEFAULT_FIRST_COLOR = QColor('#a6cee3')
MIMEDATA_KEY = 'hub-classscheme'
MIMEDATA_KEY_TEXT = 'text/plain'
MIMEDATA_INTERNAL_IDs = 'classinfo_ids'

Benjamin Jakimow
committed
"""
Returns QgsMapLayers from which a ClassificationScheme can be derived.
Searches in all QgsMapLayerStores known to classification.MAP_LAYER_STORES
:return: [list-of-QgsMapLayer]
"""
results = []
for lyr in registeredMapLayers():
if isinstance(lyr, QgsVectorLayer) and isinstance(lyr.renderer(), QgsCategorizedSymbolRenderer):
results.append(lyr)
elif isinstance(lyr, QgsRasterLayer) and isinstance(lyr.renderer(), QgsPalettedRasterRenderer):
results.append(lyr)

Benjamin Jakimow
committed
return results
def hasClassification(pathOrDataset):
"""
This function tests if a gdal-readable raster data set contains
categorical information that can be used to retrieve a ClassificationScheme
:param pathOrDataset: string | gdal.Dataset
:return: True | False
"""
ds = None
try:
if isinstance(pathOrDataset, gdal.Dataset):
ds = pathOrDataset
elif isinstance(pathOrDataset, str):
ds = gdal.Open(pathOrDataset)
elif isinstance(ds, QgsRasterLayer):
ds = gdal.Open(ds.source())
except Exception as ex:
pass

Benjamin Jakimow
committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
if not isinstance(ds, gdal.Dataset):
return False
for b in range(ds.RasterCount):
band = ds.GetRasterBand(b + 1)
assert isinstance(band, gdal.Band)
if band.GetCategoryNames() or band.GetColorTable():
return True
return False
def getTextColorWithContrast(c:QColor)->QColor:
"""
Returns a QColor with good contrast to c
:param c: QColor
:return: QColor
"""
assert isinstance(c, QColor)
if c.lightness() < 0.5:
return QColor('white')
else:
return QColor('black')
class ClassInfo(QObject):
sigSettingsChanged = pyqtSignal()
def __init__(self, label=0, name=None, color=None, parent=None):
super(ClassInfo, self).__init__(parent)
if name is None:
name = 'Unclassified' if label == 0 else 'Class {}'.format(label)
if color is None:
if label == 0:
color = DEFAULT_UNCLASSIFIEDCOLOR
else:
color = DEFAULT_FIRST_COLOR
self.mName = name
self.mLabel = label
self.mColor = color
if color:
self.setColor(color)
def setLabel(self, label:int):
"""
Sets the label value.
:param label: int, must be >= 0
"""
assert isinstance(label, int)
assert label >= 0
self.mLabel = label
self.sigSettingsChanged.emit()
def label(self)->int:
"""
Returns the class label values
:return: int
"""
return self.mLabel
def color(self)->QColor:
"""
Returns the class color.
:return: QColor
"""
return QColor(self.mColor)
def name(self)->str:
"""
Returns the class name
:return: str
"""
return self.mName
def setColor(self, color:QColor):
"""
Sets the class color.
:param color: QColor
"""
assert isinstance(color, QColor)
self.mColor = color
self.sigSettingsChanged.emit()
def setName(self, name:str):
"""
Sets thes class name
:param name: str
"""
assert isinstance(name, str)
self.mName = name
self.sigSettingsChanged.emit()
def pixmap(self, *args)->QPixmap:
"""
Returns a QPixmap. Default size is 20x20px
:param args: QPixmap arguments.
:return: QPixmap
"""
if len(args) == 0:
args = (QSize(20, 20),)
pm = QPixmap(*args)
pm.fill(self.mColor)
return pm
def icon(self, *args)->QIcon:
"""
Returns the class color as QIcon
:param args: QPixmap arguments
:return: QIcon
"""
return QIcon(self.pixmap(*args))
def clone(self):
"""
Create a copy of this ClassInfo
Loading
Loading full blame...