mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			218 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
"""
 | 
						|
***************************************************************************
 | 
						|
    Heatmap.py
 | 
						|
    ---------------------
 | 
						|
    Date                 : December 2016
 | 
						|
    Copyright            : (C) 2016 by Nyall Dawson
 | 
						|
    Email                : nyall dot dawson 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__ = 'Nyall Dawson'
 | 
						|
__date__ = 'December 2016'
 | 
						|
__copyright__ = '(C) 2016, Nyall Dawson'
 | 
						|
 | 
						|
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD
 | 
						|
from processing.tools import dataobjects
 | 
						|
 | 
						|
import os
 | 
						|
from qgis.PyQt import uic
 | 
						|
from qgis.gui import QgsDoubleSpinBox
 | 
						|
from qgis.core import (QgsRectangle,
 | 
						|
                       QgsProcessingUtils)
 | 
						|
 | 
						|
pluginPath = os.path.dirname(__file__)
 | 
						|
WIDGET, BASE = uic.loadUiType(
 | 
						|
    os.path.join(pluginPath, 'RasterResolutionWidget.ui'))
 | 
						|
 | 
						|
 | 
						|
class HeatmapPixelSizeWidget(BASE, WIDGET):
 | 
						|
 | 
						|
    def __init__(self):
 | 
						|
        super(HeatmapPixelSizeWidget, self).__init__(None)
 | 
						|
        self.setupUi(self)
 | 
						|
 | 
						|
        self.layer_bounds = QgsRectangle()
 | 
						|
        self.source = None
 | 
						|
        self.raster_bounds = QgsRectangle()
 | 
						|
        self.radius = 100
 | 
						|
        self.radius_field = None
 | 
						|
 | 
						|
        self.mCellXSpinBox.setShowClearButton(False)
 | 
						|
        self.mCellYSpinBox.setShowClearButton(False)
 | 
						|
        self.mRowsSpinBox.setShowClearButton(False)
 | 
						|
        self.mColumnsSpinBox.setShowClearButton(False)
 | 
						|
 | 
						|
        self.mCellYSpinBox.valueChanged.connect(self.mCellXSpinBox.setValue)
 | 
						|
        self.mCellXSpinBox.valueChanged.connect(self.pixelSizeChanged)
 | 
						|
        self.mRowsSpinBox.valueChanged.connect(self.rowsChanged)
 | 
						|
        self.mColumnsSpinBox.valueChanged.connect(self.columnsChanged)
 | 
						|
 | 
						|
    def setRadius(self, radius):
 | 
						|
        self.radius = radius
 | 
						|
        self.recalculate_bounds()
 | 
						|
 | 
						|
    def setRadiusField(self, radius_field):
 | 
						|
        self.radius_field = radius_field
 | 
						|
        self.recalculate_bounds()
 | 
						|
 | 
						|
    def setSource(self, source):
 | 
						|
        if not source:
 | 
						|
            return
 | 
						|
        bounds = source.sourceExtent()
 | 
						|
        if bounds.isNull():
 | 
						|
            return
 | 
						|
 | 
						|
        self.source = source
 | 
						|
        self.layer_bounds = bounds
 | 
						|
        self.recalculate_bounds()
 | 
						|
 | 
						|
    def recalculate_bounds(self):
 | 
						|
        self.raster_bounds = QgsRectangle(self.layer_bounds)
 | 
						|
 | 
						|
        if not self.source:
 | 
						|
            return
 | 
						|
 | 
						|
        max_radius = self.radius
 | 
						|
        if self.radius_field:
 | 
						|
            idx = self.source.fields().lookupField(self.radius_field)
 | 
						|
            try:
 | 
						|
                max_radius = float(self.source.maximumValue(idx))
 | 
						|
            except:
 | 
						|
                pass
 | 
						|
 | 
						|
        self.raster_bounds.setXMinimum(self.raster_bounds.xMinimum() - max_radius)
 | 
						|
        self.raster_bounds.setYMinimum(self.raster_bounds.yMinimum() - max_radius)
 | 
						|
        self.raster_bounds.setXMaximum(self.raster_bounds.xMaximum() + max_radius)
 | 
						|
        self.raster_bounds.setYMaximum(self.raster_bounds.yMaximum() + max_radius)
 | 
						|
 | 
						|
        self.pixelSizeChanged()
 | 
						|
 | 
						|
    def pixelSizeChanged(self):
 | 
						|
        cell_size = self.mCellXSpinBox.value()
 | 
						|
        if cell_size <= 0:
 | 
						|
            return
 | 
						|
        self.mCellYSpinBox.blockSignals(True)
 | 
						|
        self.mCellYSpinBox.setValue(cell_size)
 | 
						|
        self.mCellYSpinBox.blockSignals(False)
 | 
						|
        rows = max(round(self.raster_bounds.height() / cell_size) + 1, 1)
 | 
						|
        cols = max(round(self.raster_bounds.width() / cell_size) + 1, 1)
 | 
						|
        self.mRowsSpinBox.blockSignals(True)
 | 
						|
        self.mRowsSpinBox.setValue(rows)
 | 
						|
        self.mRowsSpinBox.blockSignals(False)
 | 
						|
        self.mColumnsSpinBox.blockSignals(True)
 | 
						|
        self.mColumnsSpinBox.setValue(cols)
 | 
						|
        self.mColumnsSpinBox.blockSignals(False)
 | 
						|
 | 
						|
    def rowsChanged(self):
 | 
						|
        rows = self.mRowsSpinBox.value()
 | 
						|
        if rows <= 0:
 | 
						|
            return
 | 
						|
        cell_size = self.raster_bounds.height() / rows
 | 
						|
        cols = max(round(self.raster_bounds.width() / cell_size) + 1, 1)
 | 
						|
        self.mColumnsSpinBox.blockSignals(True)
 | 
						|
        self.mColumnsSpinBox.setValue(cols)
 | 
						|
        self.mColumnsSpinBox.blockSignals(False)
 | 
						|
        for w in [self.mCellXSpinBox, self.mCellYSpinBox]:
 | 
						|
            w.blockSignals(True)
 | 
						|
            w.setValue(cell_size)
 | 
						|
            w.blockSignals(False)
 | 
						|
 | 
						|
    def columnsChanged(self):
 | 
						|
        cols = self.mColumnsSpinBox.value()
 | 
						|
        if cols < 2:
 | 
						|
            return
 | 
						|
        cell_size = self.raster_bounds.width() / (cols - 1)
 | 
						|
        rows = max(round(self.raster_bounds.height() / cell_size), 1)
 | 
						|
        self.mRowsSpinBox.blockSignals(True)
 | 
						|
        self.mRowsSpinBox.setValue(rows)
 | 
						|
        self.mRowsSpinBox.blockSignals(False)
 | 
						|
        for w in [self.mCellXSpinBox, self.mCellYSpinBox]:
 | 
						|
            w.blockSignals(True)
 | 
						|
            w.setValue(cell_size)
 | 
						|
            w.blockSignals(False)
 | 
						|
 | 
						|
    def setValue(self, value):
 | 
						|
        try:
 | 
						|
            numeric_value = float(value)
 | 
						|
        except:
 | 
						|
            return False
 | 
						|
 | 
						|
        self.mCellXSpinBox.setValue(numeric_value)
 | 
						|
        self.mCellYSpinBox.setValue(numeric_value)
 | 
						|
        return True
 | 
						|
 | 
						|
    def value(self):
 | 
						|
        return self.mCellXSpinBox.value()
 | 
						|
 | 
						|
 | 
						|
class HeatmapPixelSizeWidgetWrapper(WidgetWrapper):
 | 
						|
 | 
						|
    def __init__(self, param, dialog, row=0, col=0, **kwargs):
 | 
						|
        super().__init__(param, dialog, row, col, **kwargs)
 | 
						|
        self.context = dataobjects.createContext()
 | 
						|
 | 
						|
    def _panel(self):
 | 
						|
        return HeatmapPixelSizeWidget()
 | 
						|
 | 
						|
    def createWidget(self):
 | 
						|
        if self.dialogType == DIALOG_STANDARD:
 | 
						|
            return self._panel()
 | 
						|
        else:
 | 
						|
            w = QgsDoubleSpinBox()
 | 
						|
            w.setShowClearButton(False)
 | 
						|
            w.setMinimum(0)
 | 
						|
            w.setMaximum(99999999999)
 | 
						|
            w.setDecimals(6)
 | 
						|
            w.setToolTip(self.tr('Resolution of each pixel in output raster, in layer units'))
 | 
						|
            return w
 | 
						|
 | 
						|
    def postInitialize(self, wrappers):
 | 
						|
        if self.dialogType != DIALOG_STANDARD:
 | 
						|
            return
 | 
						|
 | 
						|
        for wrapper in wrappers:
 | 
						|
            if wrapper.parameterDefinition().name() == self.param.parent_layer:
 | 
						|
                self.setSource(wrapper.parameterValue())
 | 
						|
                wrapper.widgetValueHasChanged.connect(self.parentLayerChanged)
 | 
						|
            elif wrapper.parameterDefinition().name() == self.param.radius_param:
 | 
						|
                self.setRadius(wrapper.parameterValue())
 | 
						|
                wrapper.widgetValueHasChanged.connect(self.radiusChanged)
 | 
						|
            elif wrapper.parameterDefinition().name() == self.param.radius_field_param:
 | 
						|
                self.setSource(wrapper.parameterValue())
 | 
						|
                wrapper.widgetValueHasChanged.connect(self.radiusFieldChanged)
 | 
						|
 | 
						|
    def parentLayerChanged(self, wrapper):
 | 
						|
        self.setSource(wrapper.parameterValue())
 | 
						|
 | 
						|
    def setSource(self, source):
 | 
						|
        source = QgsProcessingUtils.variantToSource(source, self.context)
 | 
						|
        self.widget.setSource(source)
 | 
						|
 | 
						|
    def radiusChanged(self, wrapper):
 | 
						|
        self.setRadius(wrapper.parameterValue())
 | 
						|
 | 
						|
    def setRadius(self, radius):
 | 
						|
        self.widget.setRadius(radius)
 | 
						|
 | 
						|
    def radiusFieldChanged(self, wrapper):
 | 
						|
        self.setRadiusField(wrapper.parameterValue())
 | 
						|
 | 
						|
    def setRadiusField(self, radius_field):
 | 
						|
        self.widget.setRadiusField(radius_field)
 | 
						|
 | 
						|
    def setValue(self, value):
 | 
						|
        return self.widget.setValue(value)
 | 
						|
 | 
						|
    def value(self):
 | 
						|
        return self.widget.value()
 |