123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- """
- ***************************************************************************
- ReliefColorsWidget.py
- ---------------------
- Date : December 2016
- Copyright : (C) 2016 by Alexander Bruy
- Email : alexander dot bruy at gmail dot com
- ***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************
- """
- __author__ = 'Alexander Bruy'
- __date__ = 'December 2016'
- __copyright__ = '(C) 2016, Alexander Bruy'
- import os
- import codecs
- from qgis.PyQt import uic
- from qgis.PyQt.QtCore import pyqtSlot, QDir
- from qgis.PyQt.QtGui import QColor, QBrush
- from qgis.PyQt.QtWidgets import (QTreeWidgetItem,
- QFileDialog,
- QMessageBox,
- QInputDialog,
- QColorDialog
- )
- from qgis.PyQt.QtXml import QDomDocument
- from qgis.core import QgsApplication, QgsMapLayer
- from qgis.analysis import QgsRelief
- from processing.gui.wrappers import WidgetWrapper
- from processing.tools import system
- pluginPath = os.path.dirname(__file__)
- WIDGET, BASE = uic.loadUiType(os.path.join(pluginPath, 'reliefcolorswidgetbase.ui'))
- class ReliefColorsWidget(BASE, WIDGET):
- def __init__(self):
- super().__init__(None)
- self.setupUi(self)
- self.btnAdd.setIcon(QgsApplication.getThemeIcon('/symbologyAdd.svg'))
- self.btnRemove.setIcon(QgsApplication.getThemeIcon('/symbologyRemove.svg'))
- self.btnUp.setIcon(QgsApplication.getThemeIcon('/mActionArrowUp.svg'))
- self.btnDown.setIcon(QgsApplication.getThemeIcon('/mActionArrowDown.svg'))
- self.btnLoad.setIcon(QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
- self.btnSave.setIcon(QgsApplication.getThemeIcon('/mActionFileSave.svg'))
- self.btnAuto.setIcon(QgsApplication.getThemeIcon('/mActionReload.svg'))
- self.layer = None
- @pyqtSlot()
- def on_btnAdd_clicked(self):
- item = QTreeWidgetItem()
- item.setText(0, '0.00')
- item.setText(1, '0.00')
- item.setBackground(2, QBrush(QColor(127, 127, 127)))
- self.reliefClassTree.addTopLevelItem(item)
- @pyqtSlot()
- def on_btnRemove_clicked(self):
- selectedItems = self.reliefClassTree.selectedItems()
- for item in selectedItems:
- self.reliefClassTree.invisibleRootItem().removeChild(item)
- item = None
- @pyqtSlot()
- def on_btnDown_clicked(self):
- selectedItems = self.reliefClassTree.selectedItems()
- for item in selectedItems:
- currentIndex = self.reliefClassTree.indexOfTopLevelItem(item)
- if currentIndex < self.reliefClassTree.topLevelItemCount() - 1:
- self.reliefClassTree.takeTopLevelItem(currentIndex)
- self.reliefClassTree.insertTopLevelItem(currentIndex + 1, item)
- self.reliefClassTree.setCurrentItem(item)
- @pyqtSlot()
- def on_btnUp_clicked(self):
- selectedItems = self.reliefClassTree.selectedItems()
- for item in selectedItems:
- currentIndex = self.reliefClassTree.indexOfTopLevelItem(item)
- if currentIndex > 0:
- self.reliefClassTree.takeTopLevelItem(currentIndex)
- self.reliefClassTree.insertTopLevelItem(currentIndex - 1, item)
- self.reliefClassTree.setCurrentItem(item)
- @pyqtSlot()
- def on_btnLoad_clicked(self):
- fileName, _ = QFileDialog.getOpenFileName(None,
- self.tr('Import Colors and elevations from XML'),
- QDir.homePath(),
- self.tr('XML files (*.xml *.XML)'))
- if fileName == '':
- return
- doc = QDomDocument()
- with codecs.open(fileName, 'r', encoding='utf-8') as f:
- content = f.read()
- if not doc.setContent(content):
- QMessageBox.critical(None,
- self.tr('Error parsing XML'),
- self.tr('The XML file could not be loaded'))
- return
- self.reliefClassTree.clear()
- reliefColorList = doc.elementsByTagName('ReliefColor')
- for i in range(reliefColorList.length()):
- elem = reliefColorList.at(i).toElement()
- item = QTreeWidgetItem()
- item.setText(0, elem.attribute('MinElevation'))
- item.setText(1, elem.attribute('MaxElevation'))
- item.setBackground(2, QBrush(QColor(int(elem.attribute('red')),
- int(elem.attribute('green')),
- int(elem.attribute('blue')))))
- self.reliefClassTree.addTopLevelItem(item)
- @pyqtSlot()
- def on_btnSave_clicked(self):
- fileName, _ = QFileDialog.getSaveFileName(None,
- self.tr('Export Colors and elevations as XML'),
- QDir.homePath(),
- self.tr('XML files (*.xml *.XML)'))
- if fileName == '':
- return
- if not fileName.lower().endswith('.xml'):
- fileName += '.xml'
- doc = QDomDocument()
- colorsElem = doc.createElement('ReliefColors')
- doc.appendChild(colorsElem)
- colors = self.reliefColors()
- for c in colors:
- elem = doc.createElement('ReliefColor')
- elem.setAttribute('MinElevation', str(c.minElevation))
- elem.setAttribute('MaxElevation', str(c.maxElevation))
- elem.setAttribute('red', str(c.color.red()))
- elem.setAttribute('green', str(c.color.green()))
- elem.setAttribute('blue', str(c.color.blue()))
- colorsElem.appendChild(elem)
- with codecs.open(fileName, 'w', encoding='utf-8') as f:
- f.write(doc.toString(2))
- @pyqtSlot()
- def on_btnAuto_clicked(self):
- if self.layer is None:
- return
- relief = QgsRelief(self.layer, system.getTempFilename(), 'GTiff')
- colors = relief.calculateOptimizedReliefClasses()
- self.populateColors(colors)
- @pyqtSlot(QTreeWidgetItem, int)
- def on_reliefClassTree_itemDoubleClicked(self, item, column):
- if not item:
- return
- if column == 0:
- d, ok = QInputDialog.getDouble(None,
- self.tr('Enter lower elevation class bound'),
- self.tr('Elevation'),
- float(item.text(0)),
- decimals=2)
- if ok:
- item.setText(0, str(d))
- elif column == 1:
- d, ok = QInputDialog.getDouble(None,
- self.tr('Enter upper elevation class bound'),
- self.tr('Elevation'),
- float(item.text(1)),
- decimals=2)
- if ok:
- item.setText(1, str(d))
- elif column == 2:
- c = QColorDialog.getColor(item.background(2).color(),
- None,
- self.tr('Select color for relief class'))
- if c.isValid():
- item.setBackground(2, QBrush(c))
- def reliefColors(self):
- colors = []
- for i in range(self.reliefClassTree.topLevelItemCount()):
- item = self.reliefClassTree.topLevelItem(i)
- if item:
- c = QgsRelief.ReliefColor(item.background(2).color(),
- float(item.text(0)),
- float(item.text(1)))
- colors.append(c)
- return colors
- def populateColors(self, colors):
- self.reliefClassTree.clear()
- for c in colors:
- item = QTreeWidgetItem()
- item.setText(0, str(c.minElevation))
- item.setText(1, str(c.maxElevation))
- item.setBackground(2, QBrush(c.color))
- self.reliefClassTree.addTopLevelItem(item)
- def setLayer(self, layer):
- self.layer = layer
- def setValue(self, value):
- self.reliefClassTree.clear()
- rows = value.split(';')
- for r in rows:
- v = r.split(',')
- item = QTreeWidgetItem()
- item.setText(0, v[0])
- item.setText(1, v[1])
- color = QColor(int(v[2]), int(v[3]), int(v[4]))
- item.setBackground(2, QBrush(color))
- self.reliefClassTree.addTopLevelItem(item)
- def value(self):
- rColors = self.reliefColors()
- colors = ''
- for c in rColors:
- colors += '{:f}, {:f}, {:d}, {:d}, {:d};'.format(c.minElevation,
- c.maxElevation,
- c.color.red(),
- c.color.green(),
- c.color.blue())
- return colors[:-1]
- class ReliefColorsWidgetWrapper(WidgetWrapper):
- def createWidget(self):
- return ReliefColorsWidget()
- def postInitialize(self, wrappers):
- for wrapper in wrappers:
- if wrapper.param.name == self.param.parent:
- self.setLayer(wrapper.value())
- wrapper.widgetValueHasChanged.connect(self.parentValueChanged)
- break
- def parentValueChanged(self, wrapper):
- self.setLayer(wrapper.parameterValue())
- def setLayer(self, layer):
- if isinstance(layer, QgsMapLayer):
- layer = layer.source()
- self.widget.setLayer(layer)
- def setValue(self, value):
- self.widget.setValue(value)
- def value(self):
- return self.widget.value()
|