diff --git a/.github/workflows/test_plugin.yaml b/.github/workflows/test_plugin.yaml index f9f9c33..605aafa 100644 --- a/.github/workflows/test_plugin.yaml +++ b/.github/workflows/test_plugin.yaml @@ -7,24 +7,68 @@ on: - "tests/**" - ".github/workflows/test_plugin.yaml" +env: + DEBIAN_FRONTEND: noninteractive + QT_QPA_PLATFORM: offscreen + XDG_RUNTIME_DIR: /tmp + PYTHONPATH: /usr/share/qgis/python/plugins:/usr/share/qgis/python:./qgis-plugin-bivariate-renderer jobs: Tests-plugin-BivariateRenderer: - runs-on: ubuntu-latest - - container: cahik/vscode-ubuntu-qgis-testing:v2 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - - name: Print dir - run: dir + - name: Prepare QGIS + run: | + sudo gpg -k && \ + KEYRING=/usr/share/keyrings/qgis-archive-keyring.gpg && \ + wget -O $KEYRING https://download.qgis.org/downloads/qgis-archive-keyring.gpg && \ + sudo touch /etc/apt/sources.list.d/qgis.sources && \ + echo 'Types: deb deb-src' | sudo tee -a /etc/apt/sources.list.d/qgis.sources && \ + echo 'URIs: https://qgis.org/ubuntugis' | sudo tee -a /etc/apt/sources.list.d/qgis.sources && \ + echo 'Suites: '$(lsb_release -c -s) | sudo tee -a /etc/apt/sources.list.d/qgis.sources && \ + echo 'Architectures: '$(dpkg --print-architecture) | sudo tee -a /etc/apt/sources.list.d/qgis.sources && \ + echo 'Components: main' | sudo tee -a /etc/apt/sources.list.d/qgis.sources && \ + echo 'Signed-By: '$KEYRING | sudo tee -a /etc/apt/sources.list.d/qgis.sources && \ + LASTSUPPORTED=focal && \ + KEYRING=/usr/share/keyrings/ubuntugis-archive-keyring.gpg && \ + sudo gpg --no-default-keyring --keyring $KEYRING --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 6B827C12C2D425E227EDCA75089EBE08314DF160 && \ + sudo touch /etc/apt/sources.list.d/ubuntugis-unstable.sources && \ + echo 'Types: deb deb-src' | sudo tee -a /etc/apt/sources.list.d/ubuntugis-unstable.sources && \ + echo 'URIs:https://ppa.launchpadcontent.net/ubuntugis/ubuntugis-unstable/ubuntu' | sudo tee -a /etc/apt/sources.list.d/ubuntugis-unstable.sources && \ + echo 'Suites: '$(lsb_release -c -s)| sudo tee -a /etc/apt/sources.list.d/ubuntugis-unstable.sources && \ + echo 'Architectures: '$(dpkg --print-architecture) | sudo tee -a /etc/apt/sources.list.d/ubuntugis-unstable.sources && \ + echo 'Components: main' | sudo tee -a /etc/apt/sources.list.d/ubuntugis-unstable.sources && \ + echo 'Signed-By: '$KEYRING | sudo tee -a /etc/apt/sources.list.d/ubuntugis-unstable.sources + + - name: Install + run: | + sudo apt-get update && \ + sudo apt-get -y -q install --no-install-recommends wget software-properties-common build-essential ca-certificates python3-pip dialog apt-utils && \ + sudo apt -y -q install qgis qgis-dev qgis-plugin-grass + + - name: Install Python packages + run: | + pip install --no-cache-dir pytest pytest-qgis pytest-cov pillow flake8 mypy pycodestyle pb_tool pytest-qt pixelmatch --break-system-packages + + - name: Print Dir + run: | + ls -la - name: Run tests run: | - PYTHONPATH=$PYTHONPATH:./qgis-plugin-bivariate-renderer - pytest tests --cov=BivariateRenderer --cov-report=term-missing:skip-covered -rP -vv -s --ignore=tests/tests_visual_result_generation \ No newline at end of file + pytest tests --cov=BivariateRenderer --cov-report=term-missing:skip-covered -rP -vv -s --ignore=tests/tests_visual_result_generation + + - name: Upload Artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + if-no-files-found: warn + name: artifacts + path: /tmp/images_diff \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 5c2262c..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Python: QGIS Plugin", - "type": "python", - "request": "attach", - "port": 5678, - "host": "localhost" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 9b78179..b0ddb93 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,37 +7,16 @@ "**/.pytest_cache": true, "**/.mypy_cache": true }, - "python.analysis.extraPaths": [ - "/usr/share/qgis/python/plugins", - "/usr/share/qgis/python" - ], - "python.linting.pycodestyleEnabled": true, - "python.linting.pycodestyleArgs": [ - "--max-line-length=160", - "--ignore=W293,W504" - ], - "python.linting.flake8Enabled": true, - "python.linting.flake8Args": [ - "--max-line-length=160", - "--ignore=W293,W504" - ], - "python.linting.mypyEnabled": true, - "python.linting.mypyArgs": [ - "--follow-imports=silent", - "--ignore-missing-imports", - "--show-column-numbers", - "--no-pretty", - "--no-strict-optional" - ], - "python.formatting.provider": "yapf", - "python.formatting.yapfArgs": [ - "--style", - "{based_on_style: google, indent_width: 4, column_limit=99}" - ], - "svg.preview.background": "custom", "python.testing.pytestArgs": [ "tests", "-rP" ], "python.testing.pytestEnabled": true, + "[python]": { + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "ms-python.black-formatter", + "editor.formatOnSave": true, + }, } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2219603..ee9c404 100755 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -21,7 +21,7 @@ { "label": "Run Pytest image generation", "type": "shell", - "command": "BIVARIATE_GENERATE=True pytest tests/tests_visual_result_generation -rP -vv -s", + "command": "BIVARIATE_GENERATE=True QT_QPA_PLATFORM=offscreen pytest tests/tests_visual_result_generation -rP -vv -s", "group": { "kind": "test", "isDefault": false diff --git a/BivariateRenderer/__init__.py b/BivariateRenderer/__init__.py index 2ead172..4647e28 100755 --- a/BivariateRenderer/__init__.py +++ b/BivariateRenderer/__init__.py @@ -32,4 +32,5 @@ def classFactory(iface): # pylint: disable=invalid-name """ # from .bivariate_renderer_plugin import BivariateRendererPlugin + return BivariateRendererPlugin(iface) diff --git a/BivariateRenderer/bivariate_renderer_plugin.py b/BivariateRenderer/bivariate_renderer_plugin.py index 697fa87..e0fc838 100755 --- a/BivariateRenderer/bivariate_renderer_plugin.py +++ b/BivariateRenderer/bivariate_renderer_plugin.py @@ -25,11 +25,10 @@ from qgis.core import QgsApplication from qgis.gui import QgsGui -from .renderer.bivariate_renderer_metadata import BivariateRendererMetadata - +from .bivariate_renderer_provider import BivariateRendererProvider from .layoutitems.layout_item import BivariateRendererLayoutItemMetadata from .layoutitems.layout_item_widget import BivariateRendererLayoutItemGuiMetadata -from .bivariate_renderer_provider import BivariateRendererProvider +from .renderer.bivariate_renderer_metadata import BivariateRendererMetadata class BivariateRendererPlugin: @@ -45,8 +44,7 @@ def __init__(self, iface): self.bivariate_renderer_layout_item_metadata = BivariateRendererLayoutItemMetadata() # TODO disconnect - QgsApplication.layoutItemRegistry().addLayoutItemType( - self.bivariate_renderer_layout_item_metadata) + QgsApplication.layoutItemRegistry().addLayoutItemType(self.bivariate_renderer_layout_item_metadata) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" @@ -54,8 +52,7 @@ def initGui(self): QgsApplication.rendererRegistry().addRenderer(self.bivariate_renderer_metadata) # TODO disconnect - QgsGui.layoutItemGuiRegistry().addLayoutItemGuiMetadata( - self.bivariate_renderer_layout_item_gui_metadata) + QgsGui.layoutItemGuiRegistry().addLayoutItemGuiMetadata(self.bivariate_renderer_layout_item_gui_metadata) self.initProcessing() diff --git a/BivariateRenderer/bivariate_renderer_provider.py b/BivariateRenderer/bivariate_renderer_provider.py index dc1b674..7638b00 100644 --- a/BivariateRenderer/bivariate_renderer_provider.py +++ b/BivariateRenderer/bivariate_renderer_provider.py @@ -1,8 +1,8 @@ from pathlib import Path +from qgis.core import QgsProcessingProvider from qgis.PyQt.QtGui import QIcon -from qgis.core import QgsProcessingProvider from BivariateRenderer.tools.tool_calculate_categories import CalculateCategoriesAlgorithm @@ -33,7 +33,7 @@ def id(self): string should be a unique, short, character only string, eg "qgis" or "gdal". This string should not be localised. """ - return 'bivariatepolygonrenderer' + return "bivariatepolygonrenderer" def name(self): """ diff --git a/BivariateRenderer/colormixing/color_mixing_method.py b/BivariateRenderer/colormixing/color_mixing_method.py index c386c5b..c656d1f 100755 --- a/BivariateRenderer/colormixing/color_mixing_method.py +++ b/BivariateRenderer/colormixing/color_mixing_method.py @@ -24,9 +24,11 @@ def name(self) -> str: def mix_colors(self, color1: QColor, color2: QColor) -> QColor: - return QColor(int((color1.red() + color2.red()) / 2), - int((color1.green() + color2.green()) / 2), - int((color1.blue() + color2.blue()) / 2)) + return QColor( + int((color1.red() + color2.red()) / 2), + int((color1.green() + color2.green()) / 2), + int((color1.blue() + color2.blue()) / 2), + ) class ColorMixingMethodDarken(ColorMixingMethod): @@ -39,8 +41,9 @@ def name(self) -> str: def mix_colors(self, color1: QColor, color2: QColor) -> QColor: - return QColor(min(color1.red(), color2.red()), min(color1.green(), color2.green()), - min(color1.blue(), color2.blue())) + return QColor( + min(color1.red(), color2.red()), min(color1.green(), color2.green()), min(color1.blue(), color2.blue()) + ) class ColorMixingMethodMultiply(ColorMixingMethod): @@ -53,6 +56,8 @@ def name(self) -> str: def mix_colors(self, color1: QColor, color2: QColor) -> QColor: - return QColor(int((color1.redF() * color2.redF()) * 255), - int((color1.greenF() * color2.greenF()) * 255), - int((color1.blueF() * color2.blueF()) * 255)) + return QColor( + int((color1.redF() * color2.redF()) * 255), + int((color1.greenF() * color2.greenF()) * 255), + int((color1.blueF() * color2.blueF()) * 255), + ) diff --git a/BivariateRenderer/colormixing/color_mixing_methods_register.py b/BivariateRenderer/colormixing/color_mixing_methods_register.py index d8cb846..8d465f7 100755 --- a/BivariateRenderer/colormixing/color_mixing_methods_register.py +++ b/BivariateRenderer/colormixing/color_mixing_methods_register.py @@ -1,8 +1,12 @@ from typing import List, Optional from ..utils import Singleton -from .color_mixing_method import (ColorMixingMethodDirect, ColorMixingMethodDarken, - ColorMixingMethod, ColorMixingMethodMultiply) +from .color_mixing_method import ( + ColorMixingMethod, + ColorMixingMethodDarken, + ColorMixingMethodDirect, + ColorMixingMethodMultiply, +) class ColorMixingMethodsRegister(metaclass=Singleton): diff --git a/BivariateRenderer/colorramps/bivariate_color_ramp.py b/BivariateRenderer/colorramps/bivariate_color_ramp.py index 631e9df..131a4fd 100755 --- a/BivariateRenderer/colorramps/bivariate_color_ramp.py +++ b/BivariateRenderer/colorramps/bivariate_color_ramp.py @@ -1,257 +1,347 @@ +from __future__ import annotations + +import math from abc import ABC, abstractmethod +from typing import List + +from qgis.core import QgsGradientColorRamp, QgsSymbolLayerUtils +from qgis.PyQt.QtGui import QColor, QIcon +from qgis.PyQt.QtXml import QDomDocument, QDomElement -from qgis.core import QgsGradientColorRamp -from qgis.PyQt.QtGui import QIcon, QColor +from BivariateRenderer.colormixing.color_mixing_method import ColorMixingMethod, ColorMixingMethodMultiply +from BivariateRenderer.colormixing.color_mixing_methods_register import ColorMixingMethodsRegister -from ..utils import get_icon +from ..utils import get_icon_path class BivariateColorRamp(ABC): + _name: str = "Default Bivariate Color Ramp" + _icon: str - @property - @abstractmethod - def color_ramp_1(self) -> QgsGradientColorRamp: - pass + def __init__(self, number_classes: int = 9) -> None: + self._number_of_classes = number_classes @property - @abstractmethod - def color_ramp_2(self) -> QgsGradientColorRamp: - pass - - @property - @abstractmethod def name(self) -> str: - pass + return self._name @property - @abstractmethod def icon(self) -> QIcon: - pass - - -class BivariateColorRampCyanBrow(BivariateColorRamp): + return QIcon(self._icon) @property - def name(self) -> str: - return "Cyan - Brown" + def number_of_classes(self) -> int: + return self._number_of_classes - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#80b9b5")) - - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#a86a25")) - - @property - def icon(self) -> QIcon: - return get_icon("cp_cyan_brown.png") - - -class BivariateColorRampTurquoiseGold(BivariateColorRamp): - - @property - def name(self) -> str: - return "Turquoise - Gold" + @abstractmethod + def get_color(self, position_value1: int, position_value2: int) -> QColor: ... - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#4e9ec2")) + @abstractmethod + def save(self, doc: QDomDocument) -> QDomElement: ... - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#f6b500")) + @staticmethod + @abstractmethod + def load(bivariate_element: QDomElement): ... - @property - def icon(self) -> QIcon: - return get_icon("cp_turquoise_gold.png") + @abstractmethod + def clone(self) -> BivariateColorRamp: ... -class BivariateColorRampOrangeBlue(BivariateColorRamp): +class BivariateColorRampGradient(BivariateColorRamp): + _color_ramp_1: QgsGradientColorRamp = QgsGradientColorRamp(QColor("#000000"), QColor("#ffffff")) + _color_ramp_2: QgsGradientColorRamp = QgsGradientColorRamp(QColor("#ffffff"), QColor("#000000")) - @property - def name(self) -> str: - return "Orange - Blue" + def __init__( + self, number_classes_per_ramp: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes_per_ramp) + self._color_mixing_method = color_mixing_method @property def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#f6742e")) + return self._color_ramp_1 @property def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#17afe7")) + return self._color_ramp_2 - @property - def icon(self) -> QIcon: - return get_icon("cp_orange_blue.png") + def set_number_of_classes(self, number_of_classes: int) -> None: + self._number_of_classes = number_of_classes + def set_color_ramp_1(self, color_ramp: QgsGradientColorRamp) -> None: + self._color_ramp_1 = color_ramp -class BivariateColorRampYellowBlue(BivariateColorRamp): + def set_color_ramp_2(self, color_ramp: QgsGradientColorRamp) -> None: + self._color_ramp_2 = color_ramp @property - def name(self) -> str: - return "Yellow - Blue" + def color_mixing_method(self) -> ColorMixingMethod: + return self._color_mixing_method - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#f1d301")) + def set_color_mixing_method(self, color_mixing_method: ColorMixingMethod) -> None: + self._color_mixing_method = color_mixing_method - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#0097f1")) + def get_color(self, position_value1: int, position_value2: int) -> QColor: + color1 = self.color_ramp_1.color(position_value1 / (self._number_of_classes - 1)) + color2 = self.color_ramp_2.color(position_value2 / (self._number_of_classes - 1)) - @property - def icon(self) -> QIcon: - return get_icon("cp_yellow_blue.png") + result_color = self.color_mixing_method.mix_colors(color1, color2) + return result_color -class BivariateColorRampLigthYellowPurple(BivariateColorRamp): + def save(self, doc: QDomDocument) -> QDomElement: + main_element = doc.createElement("BivariateColorRamp") - @property - def name(self) -> str: - return "Ligth Yellow - Purple" + main_element.setAttribute("type", "Gradient") - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#cab55a")) + main_element.setAttribute("number_of_classes", str(self.number_of_classes)) + main_element.setAttribute("color_mixing_method", self.color_mixing_method.name()) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#9a73af")) + color_ramp_elem = QgsSymbolLayerUtils.saveColorRamp("color_ramp_1", self.color_ramp_1, doc) + main_element.appendChild(color_ramp_elem) - @property - def icon(self) -> QIcon: - return get_icon("cp_ligth_yellow_purple.png") + color_ramp_elem = QgsSymbolLayerUtils.saveColorRamp("color_ramp_2", self.color_ramp_2, doc) + main_element.appendChild(color_ramp_elem) + return main_element -class BivariateColorRampCyanViolet(BivariateColorRamp): + @staticmethod + def load(bivariate_ramp_element: QDomElement) -> BivariateColorRampGradient: + bivariate_color_ramp = BivariateColorRampGradient() - @property - def name(self) -> str: - return "Cyan - Violet" + bivariate_color_ramp.set_number_of_classes(int(bivariate_ramp_element.attribute("number_of_classes"))) - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#5bcaca")) + color_mixing_method_name = bivariate_ramp_element.attribute("color_mixing_method") + color_mixing_method = ColorMixingMethodsRegister().get_by_name(color_mixing_method_name) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#bf64ad")) + if color_mixing_method: + bivariate_color_ramp.set_color_mixing_method(color_mixing_method) - @property - def icon(self) -> QIcon: - return get_icon("cp_cyan_violet.png") + bivariate_color_ramp.set_color_ramp_1( + QgsSymbolLayerUtils.loadColorRamp(bivariate_ramp_element.firstChildElement("colorramp")) + ) + bivariate_color_ramp.set_color_ramp_2( + QgsSymbolLayerUtils.loadColorRamp(bivariate_ramp_element.lastChildElement("colorramp")) + ) -class BivariateColorRampBlueGreen(BivariateColorRamp): + return bivariate_color_ramp - @property - def name(self) -> str: - return "Blue - Green" + def clone(self) -> BivariateColorRampGradient: + bivariate_color_ramp = BivariateColorRampGradient() - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#6c84b7")) + bivariate_color_ramp._name = self._name + bivariate_color_ramp.set_number_of_classes(self.number_of_classes) + bivariate_color_ramp.set_color_mixing_method(self.color_mixing_method) + bivariate_color_ramp.set_color_ramp_1(self.color_ramp_1.clone()) + bivariate_color_ramp.set_color_ramp_2(self.color_ramp_2.clone()) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#73af7f")) + return bivariate_color_ramp - @property - def icon(self) -> QIcon: - return get_icon("cp_blue_green.png") +class BivariateColorRampManual(BivariateColorRamp): + _colors: List[List[QColor]] = [] -class BivariateColorRampVioletBlue(BivariateColorRamp): + def __init__(self, colors: List[List[QColor]]) -> None: + number_classes = len(colors) - @property - def name(self) -> str: - return "Violet - Blue" + super().__init__(number_classes) + self._colors = colors - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#ae3a4c")) + for row_colors in self._colors: + if not len(row_colors) != number_classes: + raise ValueError("Colors list do not create a square.") - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#4886c2")) + def get_color(self, position_value1: int, position_value2: int) -> QColor: + return self._colors[position_value1][position_value2] - @property - def icon(self) -> QIcon: - return get_icon("cp_violet_blue.png") + def save(self, doc: QDomDocument) -> QDomElement: + main_element = doc.createElement("BivariateColorRamp") + main_element.setAttribute("type", "Manual") -class BivariateColorRampPinkBlue(BivariateColorRamp): + main_element.setAttribute("number_of_classes", str(self.number_of_classes)) - @property - def name(self) -> str: - return "Pink - Blue" + colors_element = doc.createElement("colors") - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#cb5b5b")) + squareColors = int(math.sqrt(self.number_of_classes)) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#66adc0")) + for i in range(squareColors): + for j in range(squareColors): + color_element = doc.createElement("color") + color_element.setAttribute("value", self._colors[i][j].name()) + colors_element.appendChild(color_element) - @property - def icon(self) -> QIcon: - return get_icon("cp_pink_blue.png") + main_element.appendChild(colors_element) + return main_element -class BivariateColorRampGreenPink(BivariateColorRamp): + @staticmethod + def load(bivariate_ramp_element: QDomElement) -> BivariateColorRampManual: - @property - def name(self) -> str: - return "Green - Pink" + number_of_classes = bivariate_ramp_element.attribute("number_of_classes") - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#4cac26")) + squareColors = int(math.sqrt(number_of_classes)) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#d0258c")) + colors_elements = bivariate_ramp_element.childNodes() - @property - def icon(self) -> QIcon: - return get_icon("cp_green_pink.png") + colors: List[List[QColor]] = [] + for _ in range(squareColors): + colors.append([QColor("#000000") for _ in range(squareColors)]) + for i in range(squareColors): + for j in range(squareColors): + color_element = colors_elements.at(i * squareColors + j) + if color_element.nodeName() != "color": + raise ValueError(f"Invalid child node name `{color_element.nodeName()}` element.") + else: + colors[i][j] = QColor(color_element.attribute("value")) -class BivariateColorRampGreenPurple(BivariateColorRamp): + return BivariateColorRampManual(colors) - @property - def name(self) -> str: - return "Green - Purple" + def clone(self) -> BivariateColorRampManual: - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#028834")) + cols = [] + for _, colors in enumerate(self._colors): + cols_row = [] + for _, color in enumerate(colors): + cols_row.append(QColor(color)) + cols.append(cols_row) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#7a3293")) + bivariate_color_ramp = BivariateColorRampManual(cols) - @property - def icon(self) -> QIcon: - return get_icon("cp_green_purple.png") + bivariate_color_ramp._name = self._name + return bivariate_color_ramp -class BivariateColorRampOrangePurple(BivariateColorRamp): - @property - def name(self) -> str: - return "Orange - Purple" +class BivariateColorRampCyanBrow(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Cyan - Brown" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#80b9b5")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#a86a25")) + self._icon = get_icon_path("cp_cyan_brown.png") - @property - def color_ramp_1(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#e95f00")) - @property - def color_ramp_2(self) -> QgsGradientColorRamp: - return QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#5e3c96")) +class BivariateColorRampTurquoiseGold(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Turquoise - Gold" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#4e9ec2")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#f6b500")) + self._icon = get_icon_path("cp_turquoise_gold.png") - @property - def icon(self) -> QIcon: - return get_icon("cp_orange_purple.png") + +class BivariateColorRampOrangeBlue(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Orange - Blue" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#f6742e")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#17afe7")) + self._icon = get_icon_path("cp_orange_blue.png") + + +class BivariateColorRampYellowBlue(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Yellow - Blue" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#f1d301")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#0097f1")) + self._icon = get_icon_path("cp_yellow_blue.png") + + +class BivariateColorRampLigthYellowPurple(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Ligth Yellow - Purple" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#cab55a")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#9a73af")) + self._icon = get_icon_path("cp_ligth_yellow_purple.png") + + +class BivariateColorRampCyanViolet(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Cyan - Violet" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#5bcaca")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#bf64ad")) + self._icon = get_icon_path("cp_cyan_violet.png") + + +class BivariateColorRampBlueGreen(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Blue - Green" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#6c84b7")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#73af7f")) + self._icon = get_icon_path("cp_blue_green.png") + + +class BivariateColorRampVioletBlue(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Violet - Blue" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#ae3a4c")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#4886c2")) + self._icon = get_icon_path("cp_violet_blue.png") + + +class BivariateColorRampPinkBlue(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Pink - Blue" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#cb5b5b")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#66adc0")) + self._icon = get_icon_path("cp_pink_blue.png") + + +class BivariateColorRampGreenPink(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Green - Pink" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#4cac26")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#d0258c")) + self._icon = get_icon_path("cp_green_pink.png") + + +class BivariateColorRampGreenPurple(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Green - Purple" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#028834")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#7a3293")) + self._icon = get_icon_path("cp_green_purple.png") + + +class BivariateColorRampOrangePurple(BivariateColorRampGradient): + def __init__( + self, number_classes: int = 3, color_mixing_method: ColorMixingMethod = ColorMixingMethodMultiply() + ) -> None: + super().__init__(number_classes, color_mixing_method) + self._name = "Orange - Purple" + self._color_ramp_1 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#e95f00")) + self._color_ramp_2 = QgsGradientColorRamp(QColor("#d3d3d3"), QColor("#5e3c96")) + self._icon = get_icon_path("cp_orange_purple.png") diff --git a/BivariateRenderer/colorramps/color_ramps_register.py b/BivariateRenderer/colorramps/color_ramps_register.py index 8a7a929..8df545b 100755 --- a/BivariateRenderer/colorramps/color_ramps_register.py +++ b/BivariateRenderer/colorramps/color_ramps_register.py @@ -3,13 +3,21 @@ from qgis.PyQt.QtGui import QIcon from ..utils import Singleton -from .bivariate_color_ramp import (BivariateColorRamp, BivariateColorRampBlueGreen, - BivariateColorRampCyanBrow, BivariateColorRampCyanViolet, - BivariateColorRampGreenPink, BivariateColorRampGreenPurple, - BivariateColorRampLigthYellowPurple, - BivariateColorRampOrangeBlue, BivariateColorRampOrangePurple, - BivariateColorRampPinkBlue, BivariateColorRampTurquoiseGold, - BivariateColorRampVioletBlue, BivariateColorRampYellowBlue) +from .bivariate_color_ramp import ( + BivariateColorRamp, + BivariateColorRampBlueGreen, + BivariateColorRampCyanBrow, + BivariateColorRampCyanViolet, + BivariateColorRampGreenPink, + BivariateColorRampGreenPurple, + BivariateColorRampLigthYellowPurple, + BivariateColorRampOrangeBlue, + BivariateColorRampOrangePurple, + BivariateColorRampPinkBlue, + BivariateColorRampTurquoiseGold, + BivariateColorRampVioletBlue, + BivariateColorRampYellowBlue, +) class BivariateColorRampsRegister(metaclass=Singleton): @@ -27,7 +35,7 @@ class BivariateColorRampsRegister(metaclass=Singleton): BivariateColorRampPinkBlue(), BivariateColorRampTurquoiseGold(), BivariateColorRampVioletBlue(), - BivariateColorRampYellowBlue() + BivariateColorRampYellowBlue(), ] @property diff --git a/BivariateRenderer/layoutitems/layout_item.py b/BivariateRenderer/layoutitems/layout_item.py index 3529f02..ec1ecbf 100755 --- a/BivariateRenderer/layoutitems/layout_item.py +++ b/BivariateRenderer/layoutitems/layout_item.py @@ -1,18 +1,28 @@ from pathlib import Path from typing import Optional -from qgis.PyQt.QtGui import QIcon, QColor +from qgis.core import ( + QgsFillSymbol, + QgsLayout, + QgsLayoutItem, + QgsLayoutItemAbstractMetadata, + QgsLayoutItemRenderContext, + QgsLineSymbol, + QgsMapLayerType, + QgsProject, + QgsReadWriteContext, + QgsSymbol, + QgsSymbolLayerUtils, + QgsTextFormat, + QgsVectorLayer, +) +from qgis.PyQt.QtGui import QColor, QIcon from qgis.PyQt.QtXml import QDomDocument, QDomElement -from qgis.core import (QgsLayoutItem, QgsLayout, QgsLayoutItemAbstractMetadata, QgsVectorLayer, - QgsTextFormat, QgsLayoutItemRenderContext, QgsLineSymbol, - QgsReadWriteContext, QgsSymbolLayerUtils, QgsSymbol, QgsProject, - QgsMapLayerType, QgsFillSymbol) - -from ..text_constants import Texts, IDS -from ..utils import default_line_symbol, get_icon, load_symbol_xml -from ..renderer.bivariate_renderer import BivariateRenderer from ..legendrenderer.legend_renderer import LegendRenderer +from ..renderer.bivariate_renderer import BivariateRenderer +from ..text_constants import IDS, Texts +from ..utils import default_line_symbol, get_icon_path, load_symbol_xml DEFAULT_AXIS_X_TEXT = "Axis X" DEFAULT_AXIS_Y_TEXT = "Axis Y" @@ -92,7 +102,8 @@ def __init__(self, layout: QgsLayout): self.ticks_use_category_midpoints = False self.symbol_rectangle_without_values = load_symbol_xml( - Path(__file__).parent.parent / "data" / "empty_rectangle_fill_symbol.xml") + Path(__file__).parent.parent / "data" / "empty_rectangle_fill_symbol.xml" + ) self.replace_rectangle_without_values = False self.use_rectangle_without_values_color_from_legend = False @@ -137,7 +148,9 @@ def to_legend_renderer(self) -> LegendRenderer: legend_render.use_category_midpoints = self.ticks_use_category_midpoints legend_render.replace_rectangle_without_values = self.replace_rectangle_without_values - legend_render.use_rectangle_without_values_color_from_legend = self.use_rectangle_without_values_color_from_legend + legend_render.use_rectangle_without_values_color_from_legend = ( + self.use_rectangle_without_values_color_from_legend + ) legend_render.symbol_rectangle_without_values = self.symbol_rectangle_without_values return legend_render @@ -152,11 +165,11 @@ def draw(self, context: QgsLayoutItemRenderContext) -> None: if self.renderer: - legend_render.render_legend(render_context, item_size.width(), item_size.height(), - self.renderer) + legend_render.render_legend(render_context, item_size.width(), item_size.height(), self.renderer) - def writePropertiesToElement(self, bivariate_legend_element: QDomElement, doc: QDomDocument, - context: QgsReadWriteContext) -> bool: + def writePropertiesToElement( + self, bivariate_legend_element: QDomElement, doc: QDomDocument, context: QgsReadWriteContext + ) -> bool: bivariate_legend_element.setAttribute("axis_x_name", self.text_axis_x) bivariate_legend_element.setAttribute("axis_y_name", self.text_axis_y) @@ -164,24 +177,18 @@ def writePropertiesToElement(self, bivariate_legend_element: QDomElement, doc: Q bivariate_legend_element.setAttribute("legend_rotated", str(self.legend_rotated)) bivariate_legend_element.setAttribute("draw_axes_text", str(self.add_axes_texts)) bivariate_legend_element.setAttribute("draw_axes_arrow", str(self.add_axes_arrows)) - bivariate_legend_element.setAttribute("draw_axes_values_texts", - str(self.add_axes_values_texts)) + bivariate_legend_element.setAttribute("draw_axes_values_texts", str(self.add_axes_values_texts)) bivariate_legend_element.setAttribute("y_axis_rotation", str(self.y_axis_rotation)) bivariate_legend_element.setAttribute("ticks_x_precision", str(self.ticks_x_precision)) bivariate_legend_element.setAttribute("ticks_y_precision", str(self.ticks_y_precision)) bivariate_legend_element.setAttribute("space_above_ticks", str(self.space_above_ticks)) - bivariate_legend_element.setAttribute("ticks_use_category_midpoints", - str(self.ticks_use_category_midpoints)) - - bivariate_legend_element.setAttribute("draw_colors_separators", - str(self.add_colors_separators)) - bivariate_legend_element.setAttribute("color_separator_width", - str(self.color_separator_width)) - bivariate_legend_element.setAttribute("color_separator_color", - self.color_separator_color.name()) - - bivariate_legend_element.setAttribute("arrows_common_start_point", - str(self.arrows_common_start_point)) + bivariate_legend_element.setAttribute("ticks_use_category_midpoints", str(self.ticks_use_category_midpoints)) + + bivariate_legend_element.setAttribute("draw_colors_separators", str(self.add_colors_separators)) + bivariate_legend_element.setAttribute("color_separator_width", str(self.color_separator_width)) + bivariate_legend_element.setAttribute("color_separator_color", self.color_separator_color.name()) + + bivariate_legend_element.setAttribute("arrows_common_start_point", str(self.arrows_common_start_point)) bivariate_legend_element.setAttribute("arrow_width", str(self.arrow_width)) line_symbol = doc.createElement("lineSymbol") @@ -204,16 +211,14 @@ def writePropertiesToElement(self, bivariate_legend_element: QDomElement, doc: Q bivariate_legend_element.appendChild(text_axes_values_format) - bivariate_legend_element.setAttribute("replace_empty_rectangles", - str(self.replace_rectangle_without_values)) + bivariate_legend_element.setAttribute("replace_empty_rectangles", str(self.replace_rectangle_without_values)) bivariate_legend_element.setAttribute( - "empty_rectangle_use_legend_color", - str(self.use_rectangle_without_values_color_from_legend)) + "empty_rectangle_use_legend_color", str(self.use_rectangle_without_values_color_from_legend) + ) empty_polygon_symbol_elem = doc.createElement("emptyPolygonSymbol") - symbol_elem = QgsSymbolLayerUtils.saveSymbol("", self.symbol_rectangle_without_values, doc, - context) + symbol_elem = QgsSymbolLayerUtils.saveSymbol("", self.symbol_rectangle_without_values, doc, context) empty_polygon_symbol_elem.appendChild(symbol_elem) @@ -224,8 +229,9 @@ def writePropertiesToElement(self, bivariate_legend_element: QDomElement, doc: Q return True - def readPropertiesFromElement(self, element: QDomElement, document: QDomDocument, - context: QgsReadWriteContext) -> bool: + def readPropertiesFromElement( + self, element: QDomElement, document: QDomDocument, context: QgsReadWriteContext + ) -> bool: if self.linked_layer: self.layer = None @@ -260,8 +266,7 @@ def readPropertiesFromElement(self, element: QDomElement, document: QDomDocument self.ticks_y_precision = int(element.attribute("ticks_y_precision")) self.space_above_ticks = int(element.attribute("space_above_ticks")) - self.ticks_use_category_midpoints = element.attribute( - "ticks_use_category_midpoints") == "True" + self.ticks_use_category_midpoints = element.attribute("ticks_use_category_midpoints") == "True" self.legend_rotated = element.attribute("legend_rotated") == "True" @@ -288,10 +293,10 @@ def readPropertiesFromElement(self, element: QDomElement, document: QDomDocument self.color_separator_width = int(element.attribute("color_separator_width")) self.color_separator_color = QColor(element.attribute("color_separator_color")) - self.replace_rectangle_without_values = element.attribute( - "replace_empty_rectangles") == "True" - self.use_rectangle_without_values_color_from_legend = element.attribute( - "empty_rectangle_use_legend_color") == "True" + self.replace_rectangle_without_values = element.attribute("replace_empty_rectangles") == "True" + self.use_rectangle_without_values_color_from_legend = ( + element.attribute("empty_rectangle_use_legend_color") == "True" + ) empty_polygon_symbol_elem = element.firstChildElement("emptyPolygonSymbol") @@ -315,8 +320,9 @@ def set_y_axis_rotation(self, rotation: float) -> None: self.refresh() - def set_axis_texts_settings(self, draw: bool, text_format: QgsTextFormat, axis_x_text: str, - axis_y_text: str) -> None: + def set_axis_texts_settings( + self, draw: bool, text_format: QgsTextFormat, axis_x_text: str, axis_y_text: str + ) -> None: self.text_format = text_format self.add_axes_texts = draw self.text_axis_x = axis_x_text @@ -333,8 +339,15 @@ def are_labels_default(self) -> bool: return self.text_axis_x == "Axis X" and self.text_axis_y == "Axis Y" - def set_ticks_settings(self, draw: bool, text_format: QgsTextFormat, use_midpoint: bool, - axis_x_precision: int, axis_y_precision: int, space_above: int) -> None: + def set_ticks_settings( + self, + draw: bool, + text_format: QgsTextFormat, + use_midpoint: bool, + axis_x_precision: int, + axis_y_precision: int, + space_above: int, + ) -> None: self.add_axes_values_texts = draw self.text_values_format = text_format self.ticks_use_category_midpoints = use_midpoint @@ -351,8 +364,7 @@ def set_color_separator_settings(self, draw: bool, color: QColor, width: float) self.refresh() - def set_arrows_settings(self, draw: bool, line_format: QgsLineSymbol, use_common_point: bool, - width: float) -> None: + def set_arrows_settings(self, draw: bool, line_format: QgsLineSymbol, use_common_point: bool, width: float) -> None: self.add_axes_arrows = draw self.arrows_common_start_point = use_common_point self.arrow_width = width @@ -360,8 +372,7 @@ def set_arrows_settings(self, draw: bool, line_format: QgsLineSymbol, use_common self.refresh() - def set_rectangle_without_values_settings(self, use: bool, symbol: QgsFillSymbol, - color_from_legend: bool) -> None: + def set_rectangle_without_values_settings(self, use: bool, symbol: QgsFillSymbol, color_from_legend: bool) -> None: self.symbol_rectangle_without_values = symbol self.replace_rectangle_without_values = use @@ -394,7 +405,7 @@ def type(self) -> int: def icon(self) -> QIcon: - return get_icon("legend_icon.png") + return QIcon(get_icon_path("legend_icon.png")) def beginCommand(self, commandText: str, command) -> None: if not isinstance(command, int): @@ -405,8 +416,7 @@ def beginCommand(self, commandText: str, command) -> None: class BivariateRendererLayoutItemMetadata(QgsLayoutItemAbstractMetadata): def __init__(self): - super().__init__(IDS.plot_item_bivariate_renderer_legend, - Texts.plot_item_bivariate_renderer) + super().__init__(IDS.plot_item_bivariate_renderer_legend, Texts.plot_item_bivariate_renderer) def createItem(self, layout): return BivariateRendererLayoutItem(layout) diff --git a/BivariateRenderer/layoutitems/layout_item_widget.py b/BivariateRenderer/layoutitems/layout_item_widget.py index beb79d9..270b398 100755 --- a/BivariateRenderer/layoutitems/layout_item_widget.py +++ b/BivariateRenderer/layoutitems/layout_item_widget.py @@ -1,19 +1,20 @@ from enum import Enum -from qgis.PyQt.QtWidgets import (QComboBox, QVBoxLayout, QLabel, QCheckBox, QPlainTextEdit, - QSpinBox, QDoubleSpinBox) - -from qgis.PyQt.QtGui import QIcon +from qgis.core import Qgis, QgsLayoutItem, QgsMapLayer, QgsMapLayerType, QgsProject, QgsVectorLayer +from qgis.gui import ( + QgsCollapsibleGroupBoxBasic, + QgsColorButton, + QgsFontButton, + QgsLayoutItemAbstractGuiMetadata, + QgsLayoutItemBaseWidget, + QgsSymbolButton, +) from qgis.PyQt.QtCore import Qt +from qgis.PyQt.QtGui import QIcon +from qgis.PyQt.QtWidgets import QCheckBox, QComboBox, QDoubleSpinBox, QLabel, QPlainTextEdit, QSpinBox, QVBoxLayout -from qgis.core import (QgsLayoutItem, QgsProject, QgsVectorLayer, QgsMapLayer, QgsMapLayerType, - Qgis) - -from qgis.gui import (QgsLayoutItemBaseWidget, QgsLayoutItemAbstractGuiMetadata, QgsFontButton, - QgsSymbolButton, QgsCollapsibleGroupBoxBasic, QgsColorButton) - -from ..text_constants import Texts, IDS -from ..utils import log, get_symbol_dict, get_icon +from ..text_constants import IDS, Texts +from ..utils import get_icon_path, get_symbol_dict, log from .layout_item import BivariateRendererLayoutItem @@ -96,7 +97,7 @@ def __init__(self, parent, layout_object: QgsLayoutItem): def widget_rotate_y_axis_texts(self) -> QgsCollapsibleGroupBoxBasic: - cg_rotate = QgsCollapsibleGroupBoxBasic('Rotate Y Axis') + cg_rotate = QgsCollapsibleGroupBoxBasic("Rotate Y Axis") cg_rotate_layout = QVBoxLayout() self.rotate_direction = QComboBox() @@ -125,7 +126,7 @@ def update_y_axis_rotation(self) -> None: def widget_rotate(self) -> QgsCollapsibleGroupBoxBasic: - cg_rotate = QgsCollapsibleGroupBoxBasic('Rotate Legend') + cg_rotate = QgsCollapsibleGroupBoxBasic("Rotate Legend") cg_rotate_layout = QVBoxLayout() self.rotate_legend = QCheckBox("Rotate") @@ -141,13 +142,12 @@ def widget_rotate(self) -> QgsCollapsibleGroupBoxBasic: def widget_non_existing_symbols(self) -> QgsCollapsibleGroupBoxBasic: - cg_nonexisting_symbol = QgsCollapsibleGroupBoxBasic('Symbol that do not exist in values') + cg_nonexisting_symbol = QgsCollapsibleGroupBoxBasic("Symbol that do not exist in values") cg_nonexisting_symbol_layout = QVBoxLayout() self.replace_empty_symbols = QCheckBox("Replace symbols without values") self.replace_empty_symbols.setChecked(self.layout_item.replace_rectangle_without_values) - self.replace_empty_symbols.stateChanged.connect( - self.pass_rectangle_without_values_settings) + self.replace_empty_symbols.stateChanged.connect(self.pass_rectangle_without_values_settings) self.empty_symbol = QgsSymbolButton() self.empty_symbol.setMinimumWidth(50) @@ -157,8 +157,7 @@ def widget_non_existing_symbols(self) -> QgsCollapsibleGroupBoxBasic: self.empty_symbol.changed.connect(self.pass_rectangle_without_values_settings) self.replace_symbol_color = QCheckBox("Replace symbol color by color from legend") - self.replace_symbol_color.setChecked( - self.layout_item.use_rectangle_without_values_color_from_legend) + self.replace_symbol_color.setChecked(self.layout_item.use_rectangle_without_values_color_from_legend) self.replace_symbol_color.stateChanged.connect(self.pass_rectangle_without_values_settings) cg_nonexisting_symbol_layout.addWidget(self.replace_empty_symbols) @@ -172,7 +171,7 @@ def widget_non_existing_symbols(self) -> QgsCollapsibleGroupBoxBasic: def widget_arrow_axes(self) -> QgsCollapsibleGroupBoxBasic: - cg_axes_arrows = QgsCollapsibleGroupBoxBasic('Axes Arrows') + cg_axes_arrows = QgsCollapsibleGroupBoxBasic("Axes Arrows") cg_axes_arrows_layout = QVBoxLayout() self.add_arrows = QCheckBox("Add axis arrows") @@ -214,7 +213,7 @@ def widget_arrow_axes(self) -> QgsCollapsibleGroupBoxBasic: def widget_text_axes(self) -> QgsCollapsibleGroupBoxBasic: - cg_axes_descriptions = QgsCollapsibleGroupBoxBasic('Axes Descriptions') + cg_axes_descriptions = QgsCollapsibleGroupBoxBasic("Axes Descriptions") cg_axes_descriptions_layout = QVBoxLayout() self.b_font = QgsFontButton() @@ -254,7 +253,7 @@ def widget_text_axes(self) -> QgsCollapsibleGroupBoxBasic: def widget_text_ticks(self) -> QgsCollapsibleGroupBoxBasic: - cg_axes_value_descriptions = QgsCollapsibleGroupBoxBasic('Axes Numerical Values') + cg_axes_value_descriptions = QgsCollapsibleGroupBoxBasic("Axes Numerical Values") cg_axes_descriptions_layout = QVBoxLayout() self.b_font_values = QgsFontButton() @@ -309,7 +308,7 @@ def widget_text_ticks(self) -> QgsCollapsibleGroupBoxBasic: def widget_spacer(self) -> QgsCollapsibleGroupBoxBasic: - cg_color_separator = QgsCollapsibleGroupBoxBasic('Color separators') + cg_color_separator = QgsCollapsibleGroupBoxBasic("Color separators") cg_color_separator_layout = QVBoxLayout() self.add_color_spacer = QCheckBox("Add color separators") @@ -341,55 +340,62 @@ def widget_spacer(self) -> QgsCollapsibleGroupBoxBasic: def pass_rectangle_without_values_settings(self): self.layout_item.beginCommand( - self.tr('Bivariate Legend - Rectangle without values settings'), - UndoBivariateLegend.RectanglesWithoutValues) + self.tr("Bivariate Legend - Rectangle without values settings"), UndoBivariateLegend.RectanglesWithoutValues + ) self.layout_item.set_rectangle_without_values_settings( self.replace_empty_symbols.isChecked(), - self.empty_symbol.symbol().clone(), self.replace_symbol_color.isChecked()) + self.empty_symbol.symbol().clone(), + self.replace_symbol_color.isChecked(), + ) self.layout_item.endCommand() def pass_arrow_settings(self): - self.layout_item.beginCommand(self.tr('Bivariate Legend - Arrows settings'), - UndoBivariateLegend.Arrows) - self.layout_item.set_arrows_settings(self.add_arrows.isChecked(), - self.b_line_symbol.symbol().clone(), - self.arrows_start_same_point.isChecked(), - self.arrow_width.value()) + self.layout_item.beginCommand(self.tr("Bivariate Legend - Arrows settings"), UndoBivariateLegend.Arrows) + self.layout_item.set_arrows_settings( + self.add_arrows.isChecked(), + self.b_line_symbol.symbol().clone(), + self.arrows_start_same_point.isChecked(), + self.arrow_width.value(), + ) self.layout_item.endCommand() def pass_color_spacer_settings(self): - self.layout_item.beginCommand(self.tr('Bivariate Legend - Change color spacer settings'), - UndoBivariateLegend.ColorSpacer) - self.layout_item.set_color_separator_settings(self.add_color_spacer.isChecked(), - self.color_spacer_color.color(), - self.color_spacer_width.value()) + self.layout_item.beginCommand( + self.tr("Bivariate Legend - Change color spacer settings"), UndoBivariateLegend.ColorSpacer + ) + self.layout_item.set_color_separator_settings( + self.add_color_spacer.isChecked(), self.color_spacer_color.color(), self.color_spacer_width.value() + ) self.layout_item.endCommand() def pass_axis_ticks_settings(self): - self.layout_item.beginCommand(self.tr('Bivariate Legend - Axis numeric values settings'), - UndoBivariateLegend.AxisNumericTexts) - self.layout_item.set_ticks_settings(self.add_axes_values_text.isChecked(), - self.b_font_values.textFormat(), - self.ticks_use_midpoint.isChecked(), - self.ticks_precision_x.value(), - self.ticks_precision_y.value(), - self.space_above_ticks.value()) + self.layout_item.beginCommand( + self.tr("Bivariate Legend - Axis numeric values settings"), UndoBivariateLegend.AxisNumericTexts + ) + self.layout_item.set_ticks_settings( + self.add_axes_values_text.isChecked(), + self.b_font_values.textFormat(), + self.ticks_use_midpoint.isChecked(), + self.ticks_precision_x.value(), + self.ticks_precision_y.value(), + self.space_above_ticks.value(), + ) self.layout_item.endCommand() def pass_axis_texts_settings(self): - self.layout_item.beginCommand(self.tr('Bivariate Legend - Axis texts settings'), - UndoBivariateLegend.AxisTexts) - self.layout_item.set_axis_texts_settings(self.add_axes_text.isChecked(), - self.b_font.textFormat(), - self.axis_x_name.toPlainText(), - self.axis_y_name.toPlainText()) + self.layout_item.beginCommand(self.tr("Bivariate Legend - Axis texts settings"), UndoBivariateLegend.AxisTexts) + self.layout_item.set_axis_texts_settings( + self.add_axes_text.isChecked(), + self.b_font.textFormat(), + self.axis_x_name.toPlainText(), + self.axis_y_name.toPlainText(), + ) self.layout_item.endCommand() def update_rotate_legend(self): - self.layout_item.beginCommand(self.tr('Bivariate Legend - Rotated legend'), - UndoBivariateLegend.Rotate) + self.layout_item.beginCommand(self.tr("Bivariate Legend - Rotated legend"), UndoBivariateLegend.Rotate) self.layout_item.set_legend_rotated(self.rotate_legend.isChecked()) self.layout_item.endCommand() @@ -408,8 +414,9 @@ def update_layer_to_work_with(self): if layer.name() == self.cb_layers.currentText(): - self.layout_item.beginCommand(self.tr('Bivariate Legend - Change layer'), - UndoBivariateLegend.ChangeLayer) + self.layout_item.beginCommand( + self.tr("Bivariate Legend - Change layer"), UndoBivariateLegend.ChangeLayer + ) self.layout_item.blockSignals(True) self.layout_item.set_linked_layer(layer) @@ -433,14 +440,13 @@ class BivariateRendererLayoutItemGuiMetadata(QgsLayoutItemAbstractGuiMetadata): """ def __init__(self): - super().__init__(IDS.plot_item_bivariate_renderer_legend, - Texts.plot_item_bivariate_renderer) + super().__init__(IDS.plot_item_bivariate_renderer_legend, Texts.plot_item_bivariate_renderer) def createItemWidget(self, item: QgsLayoutItem): # pylint: disable=missing-docstring, no-self-use return BivariateRendererLayoutItemWidget(None, item) def creationIcon(self) -> QIcon: - return get_icon("add_legend_icon.png") + return QIcon(get_icon_path("add_legend_icon.png")) class UndoBivariateLegend(Enum): diff --git a/BivariateRenderer/legendrenderer/legend_renderer.py b/BivariateRenderer/legendrenderer/legend_renderer.py index 9adc41d..d1b4e4b 100755 --- a/BivariateRenderer/legendrenderer/legend_renderer.py +++ b/BivariateRenderer/legendrenderer/legend_renderer.py @@ -1,14 +1,21 @@ -from typing import List import math +from typing import List +from qgis.core import ( + QgsBasicNumericFormat, + QgsFillSymbol, + QgsLineString, + QgsLineSymbol, + QgsNumericFormatContext, + QgsPoint, + QgsRenderContext, + QgsTextFormat, + QgsTextRenderer, +) from qgis.PyQt.QtCore import QPointF, QRectF, Qt -from qgis.PyQt.QtGui import QPolygonF, QPainter, QTransform, QColor, QPen +from qgis.PyQt.QtGui import QColor, QPainter, QPen, QPolygonF, QTransform -from qgis.core import (QgsTextFormat, QgsLineSymbol, QgsRenderContext, QgsTextRenderer, - QgsBasicNumericFormat, QgsNumericFormatContext, QgsLineString, QgsPoint, - QgsFillSymbol) - -from ..renderer.bivariate_renderer import LegendPolygon, BivariateRenderer +from ..renderer.bivariate_renderer import BivariateRenderer, LegendPolygon from ..utils import default_line_symbol @@ -128,13 +135,9 @@ def set_text_height(self, text_axis_x: List[str], text_axis_y: List[str]) -> Non if self.add_axes_texts: - self._text_height_x = QgsTextRenderer.textHeight(self.context, - self.text_format, - textLines=text_axis_x) + self._text_height_x = QgsTextRenderer.textHeight(self.context, self.text_format, textLines=text_axis_x) - self._text_height_y = QgsTextRenderer.textHeight(self.context, - self.text_format, - textLines=text_axis_y) + self._text_height_y = QgsTextRenderer.textHeight(self.context, self.text_format, textLines=text_axis_y) else: @@ -332,15 +335,16 @@ def transform(self) -> QTransform: size = self.height - max_size - scale_factor_orig = self.height / math.sqrt( - math.pow(max_size, 2) + math.pow(max_size, 2)) + scale_factor_orig = self.height / math.sqrt(math.pow(max_size, 2) + math.pow(max_size, 2)) scale_factor = (int(scale_factor_orig * 100) / 100) - 0.02 self._transform.translate(self.width / 2, self.height / 2) self._transform.rotate(-45) self._transform.scale(scale_factor, scale_factor) - self._transform.translate(-(self.width / 2) - (size / 2) * scale_factor_orig, - -(self.height / 2) + (size / 2) * scale_factor_orig) + self._transform.translate( + -(self.width / 2) - (size / 2) * scale_factor_orig, + -(self.height / 2) + (size / 2) * scale_factor_orig, + ) else: @@ -356,9 +360,13 @@ def draw_polygons(self, polygons: List[LegendPolygon]) -> None: for polygon in polygons: polygon_draw = QPolygonF( - QRectF(self.polygon_start_pos_x + polygon.x * self.size_constant, - self.polygon_start_pos_y - (polygon.y + 1) * self.size_constant, - self.size_constant, self.size_constant)) + QRectF( + self.polygon_start_pos_x + polygon.x * self.size_constant, + self.polygon_start_pos_y - (polygon.y + 1) * self.size_constant, + self.size_constant, + self.size_constant, + ) + ) polygon_draw = self.transform.map(polygon_draw) @@ -368,8 +376,7 @@ def draw_polygons(self, polygons: List[LegendPolygon]) -> None: self.symbol_rectangle_without_values.setColor(polygon.symbol.color()) self.symbol_rectangle_without_values.startRender(self.context) - self.symbol_rectangle_without_values.renderPolygon(polygon_draw, None, None, - self.context) + self.symbol_rectangle_without_values.renderPolygon(polygon_draw, None, None, self.context) self.symbol_rectangle_without_values.stopRender(self.context) else: @@ -400,10 +407,7 @@ def draw_axes_arrows(self) -> None: def axis_text_max_lines(self) -> int: return max(len(self._text_axis_x), len(self._text_axis_y)) - def add_empty_lines(self, - text: List[str], - number_of_lines: int, - add_before_text: bool = False) -> List[str]: + def add_empty_lines(self, text: List[str], number_of_lines: int, add_before_text: bool = False) -> List[str]: if add_before_text: @@ -413,10 +417,7 @@ def add_empty_lines(self, return text + ["\n"] * number_of_lines - def add_lines_if_shorter(self, - text: List[str], - required_length: int, - add_before_text: bool = False) -> List[str]: + def add_lines_if_shorter(self, text: List[str], required_length: int, add_before_text: bool = False) -> List[str]: if len(text) == required_length: @@ -436,18 +437,29 @@ def text_axis_y(self) -> List[str]: rotated_counterclockwise = self._text_rotation_y == 90 - return self.add_lines_if_shorter(self._text_axis_y, self.axis_text_max_lines, - rotated_counterclockwise) + return self.add_lines_if_shorter(self._text_axis_y, self.axis_text_max_lines, rotated_counterclockwise) def draw_axes_texts(self) -> None: - QgsTextRenderer.drawText(self.transform.map(self.text_position_x), self.text_rotation_x, - QgsTextRenderer.AlignCenter, self.text_axis_x, self.context, - self.text_format, QgsTextRenderer.AlignBottom) - - QgsTextRenderer.drawText(self.transform.map(self.text_position_y), self.text_rotation_y, - QgsTextRenderer.AlignCenter, self.text_axis_y, self.context, - self.text_format, QgsTextRenderer.AlignBottom) + QgsTextRenderer.drawText( + self.transform.map(self.text_position_x), + self.text_rotation_x, + QgsTextRenderer.AlignCenter, + self.text_axis_x, + self.context, + self.text_format, + QgsTextRenderer.AlignBottom, + ) + + QgsTextRenderer.drawText( + self.transform.map(self.text_position_y), + self.text_rotation_y, + QgsTextRenderer.AlignCenter, + self.text_axis_y, + self.context, + self.text_format, + QgsTextRenderer.AlignBottom, + ) def format_tick_value(self, value: float, precision: int) -> List[str]: @@ -462,11 +474,11 @@ def axis_tick_text_height(self) -> float: if self.add_axes_ticks_texts: - return QgsTextRenderer.textHeight(self.context, - self.text_format_ticks, - textLines=self.format_tick_value( - self.texts_axis_x_ticks[0], - self.ticks_x_precision)) + return QgsTextRenderer.textHeight( + self.context, + self.text_format_ticks, + textLines=self.format_tick_value(self.texts_axis_x_ticks[0], self.ticks_x_precision), + ) else: @@ -477,11 +489,11 @@ def axis_tick_last_y_value_width(self) -> float: if self.add_axes_ticks_texts and not self.use_category_midpoints: - return QgsTextRenderer.textWidth(self.context, - self.text_format_ticks, - textLines=self.format_tick_value( - max(self.texts_axis_y_ticks), - self.ticks_y_precision)) + return QgsTextRenderer.textWidth( + self.context, + self.text_format_ticks, + textLines=self.format_tick_value(max(self.texts_axis_y_ticks), self.ticks_y_precision), + ) else: @@ -492,11 +504,11 @@ def axis_tick_last_x_value_width(self) -> float: if self.add_axes_ticks_texts and not self.use_category_midpoints: - return QgsTextRenderer.textWidth(self.context, - self.text_format_ticks, - textLines=self.format_tick_value( - max(self.texts_axis_x_ticks), - self.ticks_x_precision)) + return QgsTextRenderer.textWidth( + self.context, + self.text_format_ticks, + textLines=self.format_tick_value(max(self.texts_axis_x_ticks), self.ticks_x_precision), + ) else: @@ -574,21 +586,29 @@ def draw_values(self) -> None: text_position = self.position_axis_tick_x(i) - QgsTextRenderer.drawText(self.transform.map(text_position), self.text_rotation_x, - QgsTextRenderer.AlignCenter, - self.format_tick_value(value, self.ticks_x_precision), - self.context, self.text_format_ticks, - QgsTextRenderer.AlignBottom) + QgsTextRenderer.drawText( + self.transform.map(text_position), + self.text_rotation_x, + QgsTextRenderer.AlignCenter, + self.format_tick_value(value, self.ticks_x_precision), + self.context, + self.text_format_ticks, + QgsTextRenderer.AlignBottom, + ) for i, value in enumerate(self.texts_axis_y_ticks): text_position = self.position_axis_tick_y(len(self.texts_axis_y_ticks) - i - 1) - QgsTextRenderer.drawText(self.transform.map(text_position), self.text_rotation_y, - QgsTextRenderer.AlignCenter, - self.format_tick_value(value, self.ticks_y_precision), - self.context, self.text_format_ticks, - QgsTextRenderer.AlignBottom) + QgsTextRenderer.drawText( + self.transform.map(text_position), + self.text_rotation_y, + QgsTextRenderer.AlignCenter, + self.format_tick_value(value, self.ticks_y_precision), + self.context, + self.text_format_ticks, + QgsTextRenderer.AlignBottom, + ) def set_space_above_ticks(self, space: int) -> None: self._space_above_ticks = int(space) @@ -609,9 +629,13 @@ def draw_spacers(self, polygons): for polygon in polygons: polygon = QPolygonF( - QRectF(self.polygon_start_pos_x + polygon.x * self.size_constant, - self.polygon_start_pos_y - (polygon.y + 1) * self.size_constant, - self.size_constant, self.size_constant)) + QRectF( + self.polygon_start_pos_x + polygon.x * self.size_constant, + self.polygon_start_pos_y - (polygon.y + 1) * self.size_constant, + self.size_constant, + self.size_constant, + ) + ) polygon = self.transform.map(polygon) @@ -634,16 +658,13 @@ def draw_debug_lines(self): self.painter.setPen(pen) - line = QgsLineString([ - QgsPoint(0, self.height - self.text_height_max), - QgsPoint(self.width, self.height - self.text_height_max) - ]) + line = QgsLineString( + [QgsPoint(0, self.height - self.text_height_max), QgsPoint(self.width, self.height - self.text_height_max)] + ) line.draw(self.painter) - line = QgsLineString( - [QgsPoint(self.text_height_max, 0), - QgsPoint(self.text_height_max, self.height)]) + line = QgsLineString([QgsPoint(self.text_height_max, 0), QgsPoint(self.text_height_max, self.height)]) line.draw(self.painter) @@ -652,37 +673,35 @@ def draw_debug_lines(self): self.painter.setPen(pen) - line = QgsLineString([ - QgsPoint(0, self.height - self.axis_text_tics_top), - QgsPoint(self.width, self.height - self.axis_text_tics_top) - ]) + line = QgsLineString( + [ + QgsPoint(0, self.height - self.axis_text_tics_top), + QgsPoint(self.width, self.height - self.axis_text_tics_top), + ] + ) line.draw(self.painter) - line = QgsLineString( - [QgsPoint(self.axis_text_tics_top, 0), - QgsPoint(self.axis_text_tics_top, self.height)]) + line = QgsLineString([QgsPoint(self.axis_text_tics_top, 0), QgsPoint(self.axis_text_tics_top, self.height)]) line.draw(self.painter) self.painter.restore() - def render_legend(self, context: QgsRenderContext, width: float, height: float, - renderer: BivariateRenderer) -> None: + def render_legend( + self, context: QgsRenderContext, width: float, height: float, renderer: BivariateRenderer + ) -> None: if self.use_category_midpoints: - self.texts_axis_x_ticks = BivariateRenderer.classes_to_legend_midpoints( - renderer.field_1_classes) - self.texts_axis_y_ticks = BivariateRenderer.classes_to_legend_midpoints( - renderer.field_2_classes) + self.texts_axis_x_ticks = BivariateRenderer.classes_to_legend_midpoints(renderer.field_1_classes) + self.texts_axis_y_ticks = BivariateRenderer.classes_to_legend_midpoints(renderer.field_2_classes) else: self.texts_axis_x_ticks = renderer.field_1_labels self.texts_axis_y_ticks = renderer.field_2_labels self.render(context, width, height, renderer.generate_legend_polygons()) - def render(self, context: QgsRenderContext, width: float, height: float, - polygons: List[LegendPolygon]) -> None: + def render(self, context: QgsRenderContext, width: float, height: float, polygons: List[LegendPolygon]) -> None: self.context = context diff --git a/BivariateRenderer/renderer/bivariate_legend.py b/BivariateRenderer/renderer/bivariate_legend.py index 80d152d..e3bbfd6 100644 --- a/BivariateRenderer/renderer/bivariate_legend.py +++ b/BivariateRenderer/renderer/bivariate_legend.py @@ -1,7 +1,6 @@ -from typing import List, Dict +from typing import Dict, List -from qgis.core import (QgsDefaultVectorLayerLegend, QgsVectorLayer, QgsLayerTreeModelLegendNode, - QgsSymbolLegendNode) +from qgis.core import QgsDefaultVectorLayerLegend, QgsLayerTreeModelLegendNode, QgsSymbolLegendNode, QgsVectorLayer from .bivariate_renderer import BivariateRenderer @@ -13,8 +12,7 @@ def __init__(self, bivariate_renderer: BivariateRenderer, layer: QgsVectorLayer self.bivariate_renderer = bivariate_renderer self.layer = layer - def createLayerTreeModelLegendNodes(self, - layer_tree_layer) -> List[QgsLayerTreeModelLegendNode]: + def createLayerTreeModelLegendNodes(self, layer_tree_layer) -> List[QgsLayerTreeModelLegendNode]: items: Dict[str, QgsSymbolLegendNode] = {} @@ -23,9 +21,9 @@ def createLayerTreeModelLegendNodes(self, label = self.bivariate_renderer.getFeatureCombinationHash(feature) if label not in items.keys(): - legend_item = QgsSymbolLegendNode(layer_tree_layer, - self.bivariate_renderer.legendSymbolItem(label), - self) + legend_item = QgsSymbolLegendNode( + layer_tree_layer, self.bivariate_renderer.legendSymbolItem(label), self + ) legend_item.setUserLabel(label) items[label] = legend_item diff --git a/BivariateRenderer/renderer/bivariate_renderer.py b/BivariateRenderer/renderer/bivariate_renderer.py index 2cc58b6..3fcbc4c 100755 --- a/BivariateRenderer/renderer/bivariate_renderer.py +++ b/BivariateRenderer/renderer/bivariate_renderer.py @@ -1,37 +1,42 @@ from __future__ import annotations -from typing import List, Dict, Tuple -from dataclasses import dataclass +from dataclasses import dataclass +from typing import Dict, List, Optional, Tuple + +from qgis.core import ( + QgsClassificationEqualInterval, + QgsClassificationMethod, + QgsClassificationRange, + QgsFeature, + QgsFeatureRenderer, + QgsFillSymbol, + QgsLegendSymbolItem, + QgsVectorLayer, +) from qgis.PyQt.QtGui import QColor from qgis.PyQt.QtXml import QDomDocument, QDomElement -from qgis.core import (QgsFeatureRenderer, QgsClassificationRange, QgsFeature, QgsColorRamp, - QgsFillSymbol, QgsSymbolLayerUtils, QgsVectorLayer, QgsClassificationMethod, - QgsClassificationEqualInterval, QgsLegendSymbolItem) +from BivariateRenderer.colorramps.bivariate_color_ramp import ( + BivariateColorRamp, + BivariateColorRampCyanViolet, + BivariateColorRampGradient, + BivariateColorRampManual, +) from ..text_constants import Texts -from ..colormixing.color_mixing_methods_register import ColorMixingMethodsRegister -from ..colormixing.color_mixing_method import ColorMixingMethod, ColorMixingMethodDarken class BivariateRenderer(QgsFeatureRenderer): - def __init__(self, syms=None): - super().__init__(Texts.bivariate_renderer_short_name) - self.number_classes: int = 3 - - self.color_mixing_method = ColorMixingMethodDarken() - self.classification_method = QgsClassificationEqualInterval() + self.bivariate_color_ramp: BivariateColorRamp = BivariateColorRampCyanViolet() + self.field_name_1: str = None self.field_name_2: str = None - self.color_ramp_1: QgsColorRamp = None - self.color_ramp_2: QgsColorRamp = None - self.cached_symbols: Dict[str, QgsFillSymbol] = {} self.labels_existing: List[str] = [] @@ -39,35 +44,27 @@ def __init__(self, syms=None): self.field_2_classes: List[QgsClassificationRange] = [] def __repr__(self) -> str: - return f"BivariateRenderer with {self.number_classes} classes for each attribute, " \ - f"for fields {self.field_name_1} and {self.field_name_2}, " \ - f"with classification method {self.classification_method.name()}," \ - f"field 1 vals {self.field_1_min};{self.field_1_max} " \ - f"field 2 vals {self.field_2_min};{self.field_2_max} " + return ( + f"BivariateRenderer " + f"for fields {self.field_name_1} and {self.field_name_2}, " + f"with classification method {self.classification_method.name()}," + f"field 1 vals {self.field_1_min};{self.field_1_max}, " + f"field 2 vals {self.field_2_min};{self.field_2_max}. " + f"With ramp {self.bivariate_color_ramp.name}." + ) def _reset_cache(self): self.cached_symbols = {} - def setColorMixingMethod(self, method: ColorMixingMethod) -> None: - self.color_mixing_method = method - self._reset_cache() + def set_bivariate_color_ramp(self, color_ramp: Optional[BivariateColorRamp]) -> None: + if color_ramp: + self.bivariate_color_ramp = color_ramp + self._reset_cache() def setClassificationMethod(self, method: QgsClassificationMethod) -> None: self.classification_method = method self._reset_cache() - def setNumberOfClasses(self, number: int) -> None: - self.number_classes = int(number) - self._reset_cache() - - def setColorRamp1(self, color_ramp: QgsColorRamp) -> None: - self.color_ramp_1 = color_ramp - self._reset_cache() - - def setColorRamp2(self, color_ramp: QgsColorRamp) -> None: - self.color_ramp_2 = color_ramp - self._reset_cache() - def setFieldName1(self, field_name: str) -> None: self.field_name_1 = field_name self._reset_cache() @@ -78,13 +75,10 @@ def setFieldName2(self, field_name: str) -> None: @staticmethod def classes_to_legend_breaks(classes: List[QgsClassificationRange]) -> List[float]: - values = [] for i, interval_class in enumerate(classes): - if i == 0: - values.append(interval_class.lowerBound()) values.append(interval_class.upperBound()) @@ -93,7 +87,6 @@ def classes_to_legend_breaks(classes: List[QgsClassificationRange]) -> List[floa @staticmethod def classes_to_legend_midpoints(classes: List[QgsClassificationRange]) -> List[float]: - values = [] for interval_class in classes: @@ -102,32 +95,30 @@ def classes_to_legend_midpoints(classes: List[QgsClassificationRange]) -> List[f return values def setField1ClassificationData(self, layer: QgsVectorLayer, attribute: str) -> None: - self.field_1_classes = self.classification_method.classes(layer, attribute, - self.number_classes) + self.field_1_classes = self.classification_method.classes( + layer, attribute, self.bivariate_color_ramp.number_of_classes + ) self._reset_cache() def setField2ClassificationData(self, layer: QgsVectorLayer, attribute: str) -> None: - self.field_2_classes = self.classification_method.classes(layer, attribute, - self.number_classes) + self.field_2_classes = self.classification_method.classes( + layer, attribute, self.bivariate_color_ramp.number_of_classes + ) self._reset_cache() def _positionValue(self, value: float, classes: List[QgsClassificationRange]) -> int: - for i, range_class in enumerate(classes): - if range_class.lowerBound() <= value <= range_class.upperBound(): class_value = i return class_value def positionValueField1(self, value: float) -> int: - return self._positionValue(value, self.field_1_classes) def positionValueField2(self, value: float) -> int: - return self._positionValue(value, self.field_2_classes) def getFeatureCombinationHash(self, feature: QgsFeature) -> str: @@ -138,13 +129,7 @@ def getPositionValuesCombinationHash(self, value1: int, value2: int) -> str: return f"{value1 + 1}-{value2 + 1}" def getFeatureColor(self, position_value1: int, position_value2: int) -> QColor: - - color1 = self.color_ramp_1.color(position_value1 / (self.number_classes - 1)) - color2 = self.color_ramp_2.color(position_value2 / (self.number_classes - 1)) - - result_color = self.color_mixing_method.mix_colors(color1, color2) - - return result_color + return self.bivariate_color_ramp.get_color(position_value1, position_value2) def position_values(self, feature: QgsFeature) -> Tuple[int, int]: value1 = feature.attribute(self.field_name_1) @@ -156,7 +141,6 @@ def position_values(self, feature: QgsFeature) -> Tuple[int, int]: return (position_value1, position_value2) def symbolForFeature(self, feature: QgsFeature, context): - position_value1, position_value2 = self.position_values(feature) identifier = self.getPositionValuesCombinationHash(position_value1, position_value2) @@ -191,44 +175,30 @@ def clone(self) -> QgsFeatureRenderer: r.setFieldName1(self.field_name_1) r.setFieldName2(self.field_name_2) r.classification_method = self.classification_method.clone() - r.setNumberOfClasses(self.number_classes) - r.setColorRamp1(self.color_ramp_1.clone()) - r.setColorRamp2(self.color_ramp_2.clone()) r.field_1_classes = self.field_1_classes r.field_2_classes = self.field_2_classes - r.setColorMixingMethod(self.color_mixing_method) r.cached_symbols = self.cached_symbols r.labels_existing = self.labels_existing + r.bivariate_color_ramp = self.bivariate_color_ramp.clone() return r def save(self, doc: QDomDocument, context): - renderer_elem = doc.createElement("renderer-v2") - renderer_elem.setAttribute('type', Texts.bivariate_renderer_short_name) - - number_classes_elem = doc.createElement('number_of_classes') - number_classes_elem.setAttribute("value", str(self.number_classes)) - renderer_elem.appendChild(number_classes_elem) + renderer_elem.setAttribute("type", Texts.bivariate_renderer_short_name) classification_method_elem = self.classification_method.save(doc, context) renderer_elem.appendChild(classification_method_elem) - field_1_elem = doc.createElement('field_name_1') + field_1_elem = doc.createElement("field_name_1") field_1_elem.setAttribute("name", self.field_name_1) renderer_elem.appendChild(field_1_elem) - field_2_elem = doc.createElement('field_name_2') + field_2_elem = doc.createElement("field_name_2") field_2_elem.setAttribute("name", self.field_name_2) renderer_elem.appendChild(field_2_elem) - color_ramp_elem = QgsSymbolLayerUtils.saveColorRamp("color_ramp_1", self.color_ramp_1, doc) - renderer_elem.appendChild(color_ramp_elem) - - color_ramp_elem = QgsSymbolLayerUtils.saveColorRamp("color_ramp_2", self.color_ramp_2, doc) - renderer_elem.appendChild(color_ramp_elem) - ranges_elem1 = doc.createElement("ranges_1") for class_range in self.field_1_classes: @@ -255,49 +225,37 @@ def save(self, doc: QDomDocument, context): renderer_elem.appendChild(ranges_elem2) - color_mixing_method_elem = doc.createElement('color_mixing_method') - color_mixing_method_elem.setAttribute("name", self.color_mixing_method.name()) - renderer_elem.appendChild(color_mixing_method_elem) - symbols_elem = doc.createElement("symbols") for symbol in self.cached_symbols.keys(): - symbol_elem = doc.createElement('symbol') + symbol_elem = doc.createElement("symbol") symbol_elem.setAttribute("color", self.cached_symbols[symbol].color().name()) symbol_elem.setAttribute("label", symbol) symbols_elem.appendChild(symbol_elem) renderer_elem.appendChild(symbols_elem) - number_classes_elem = doc.createElement('existing_labels') + number_classes_elem = doc.createElement("existing_labels") labels = "" if self.existing_labels(): labels = "|".join(self.labels_existing) number_classes_elem.setAttribute("value", labels) renderer_elem.appendChild(number_classes_elem) + renderer_elem.appendChild(self.bivariate_color_ramp.save(doc)) + return renderer_elem @staticmethod def create_render_from_element(element: QDomElement, context) -> BivariateRenderer: - r = BivariateRenderer() r.setFieldName1(element.firstChildElement("field_name_1").attribute("name")) r.setFieldName2(element.firstChildElement("field_name_2").attribute("name")) - r.setNumberOfClasses(int( - element.firstChildElement("number_of_classes").attribute("value"))) - method_elem = element.firstChildElement("classificationMethod") r.setClassificationMethod(QgsClassificationMethod.create(method_elem, context)) - color_ramp_1_elem = element.firstChildElement("colorramp") - r.setColorRamp1(QgsSymbolLayerUtils.loadColorRamp(color_ramp_1_elem)) - - color_ramp_2_elem = element.lastChildElement("colorramp") - r.setColorRamp2(QgsSymbolLayerUtils.loadColorRamp(color_ramp_2_elem)) - ranges_field_1 = element.firstChildElement("ranges_1") field_1_classes = [] @@ -305,7 +263,6 @@ def create_render_from_element(element: QDomElement, context) -> BivariateRender range_elem = ranges_field_1.firstChildElement() while not range_elem.isNull(): - if range_elem.tagName() == "range_1": lower_value = float(range_elem.attribute("lower")) upper_value = float(range_elem.attribute("upper")) @@ -322,7 +279,6 @@ def create_render_from_element(element: QDomElement, context) -> BivariateRender range_elem = ranges_field_2.firstChildElement() while not range_elem.isNull(): - if range_elem.tagName() == "range_2": lower_value = float(range_elem.attribute("lower")) upper_value = float(range_elem.attribute("upper")) @@ -335,15 +291,11 @@ def create_render_from_element(element: QDomElement, context) -> BivariateRender r.field_1_classes = field_1_classes r.field_2_classes = field_2_classes - r.setColorMixingMethod(ColorMixingMethodsRegister().get_by_name( - element.firstChildElement("color_mixing_method").attribute("name"))) - symbols_elem = element.firstChildElement("symbols") symbol_elem = symbols_elem.firstChildElement() while not symbol_elem.isNull(): - if symbol_elem.tagName() == "symbol": color = QColor(symbol_elem.attribute("color")) label = symbol_elem.attribute("label") @@ -362,6 +314,18 @@ def create_render_from_element(element: QDomElement, context) -> BivariateRender r.labels_existing = labels + bivariate_ramp_elem = element.firstChildElement("BivariateColorRamp") + bivariate_ramp = None + if not bivariate_ramp_elem.isNull(): + bivariate_ramp_type = bivariate_ramp_elem.attribute("type") + if bivariate_ramp_type == "Gradient": + bivariate_ramp = BivariateColorRampGradient.load(bivariate_ramp_elem) + elif bivariate_ramp_type == "Manual": + bivariate_ramp = BivariateColorRampManual.load(bivariate_ramp_elem) + + if bivariate_ramp: + r.bivariate_color_ramp = bivariate_ramp + return r def load(self, symbology_elem: QDomElement, context): @@ -369,18 +333,13 @@ def load(self, symbology_elem: QDomElement, context): @staticmethod def get_default_symbol() -> QgsFillSymbol: - - symbol = QgsFillSymbol.createSimple({ - "color": "#cccccc", - "outline_width": "0.0", - "outline_color": "0,0,0", - 'outline_style': 'no' - }) + symbol = QgsFillSymbol.createSimple( + {"color": "#cccccc", "outline_width": "0.0", "outline_color": "0,0,0", "outline_style": "no"} + ) return symbol def symbol_for_values(self, value1: int, value2: int) -> QgsFillSymbol: - identifier = self.getPositionValuesCombinationHash(value1, value2) if identifier not in self.cached_symbols: @@ -392,42 +351,34 @@ def symbol_for_values(self, value1: int, value2: int) -> QgsFillSymbol: return self.cached_symbols[identifier] def generate_legend_polygons(self) -> List[LegendPolygon]: - polygons = [] for x, field_1_cat in enumerate(self.field_1_classes): - for y, field_2_cat in enumerate(self.field_2_classes): - exist = True if self.getPositionValuesCombinationHash(x, y) not in self.existing_labels(): exist = False - polygons.append( - LegendPolygon(x=x, - y=y, - symbol=self.symbol_for_values(x, y), - exist_in_map=exist)) + polygons.append(LegendPolygon(x=x, y=y, symbol=self.symbol_for_values(x, y), exist_in_map=exist)) return polygons def __eq__(self, other: object) -> bool: - if not isinstance(other, BivariateRenderer): return False else: - if (self.field_name_1 == other.field_name_1 and - self.field_name_2 == other.field_name_2 and - self.number_classes == other.number_classes and - # self.classification_method.id() == other.classification_method.id() and - self.field_1_min == other.field_1_min and - self.field_1_max == other.field_1_max and - self.field_2_min == other.field_2_min and - self.field_2_max == other.field_2_max and - self.color_ramp_1.properties() == other.color_ramp_1.properties() and - self.color_ramp_2.properties() == other.color_ramp_2.properties()): + if ( + self.field_name_1 == other.field_name_1 + and self.field_name_2 == other.field_name_2 + and + # self.classification_method.id() == other.classification_method.id() and + self.field_1_min == other.field_1_min + and self.field_1_max == other.field_1_max + and self.field_2_min == other.field_2_min + and self.field_2_max == other.field_2_max + ): return True else: @@ -439,8 +390,10 @@ def field_2_min(self) -> float: @property def field_2_max(self) -> float: - return (self.field_2_classes[len(self.field_2_classes) - 1].lowerBound() + - self.field_2_classes[len(self.field_2_classes) - 1].upperBound()) / 2 + return ( + self.field_2_classes[len(self.field_2_classes) - 1].lowerBound() + + self.field_2_classes[len(self.field_2_classes) - 1].upperBound() + ) / 2 @property def field_2_labels(self) -> List[float]: @@ -452,8 +405,10 @@ def field_1_min(self) -> float: @property def field_1_max(self) -> float: - return (self.field_1_classes[len(self.field_1_classes) - 1].lowerBound() + - self.field_1_classes[len(self.field_1_classes) - 1].upperBound()) / 2 + return ( + self.field_1_classes[len(self.field_1_classes) - 1].lowerBound() + + self.field_1_classes[len(self.field_1_classes) - 1].upperBound() + ) / 2 @property def field_1_labels(self) -> List[float]: @@ -473,16 +428,14 @@ def existing_labels(self) -> List[str]: return [x for x in sorted(self.labels_existing)] def generateCategories(self): - - for x in range(self.number_classes): - for y in range(self.number_classes): + for x in range(self.bivariate_color_ramp.number_of_classes): + for y in range(self.bivariate_color_ramp.number_of_classes): identifier = self.getPositionValuesCombinationHash(x, y) self.cached_symbols[identifier] = self.symbol_for_values(x, y) @dataclass class LegendPolygon: - x: float y: float symbol: QgsFillSymbol diff --git a/BivariateRenderer/renderer/bivariate_renderer_metadata.py b/BivariateRenderer/renderer/bivariate_renderer_metadata.py index 06fb220..55e12aa 100755 --- a/BivariateRenderer/renderer/bivariate_renderer_metadata.py +++ b/BivariateRenderer/renderer/bivariate_renderer_metadata.py @@ -1,13 +1,11 @@ -from pathlib import Path - -from qgis.core import (QgsRendererAbstractMetadata) - +from qgis.core import QgsRendererAbstractMetadata +from qgis.PyQt.QtGui import QIcon from qgis.PyQt.QtXml import QDomElement +from ..text_constants import Texts +from ..utils import get_icon_path from .bivariate_renderer import BivariateRenderer from .bivariate_renderer_widget import BivariateRendererWidget -from ..text_constants import Texts -from ..utils import get_icon class BivariateRendererMetadata(QgsRendererAbstractMetadata): @@ -15,7 +13,7 @@ class BivariateRendererMetadata(QgsRendererAbstractMetadata): def __init__(self): super().__init__(Texts.bivariate_renderer_short_name, Texts.bivariate_renderer_full_name) - super().setIcon(get_icon("legend_icon.png")) + super().setIcon(QIcon(get_icon_path("legend_icon.png"))) def name(self) -> str: return Texts.bivariate_renderer_short_name diff --git a/BivariateRenderer/renderer/bivariate_renderer_widget.py b/BivariateRenderer/renderer/bivariate_renderer_widget.py index 0ce099c..dd67c3a 100755 --- a/BivariateRenderer/renderer/bivariate_renderer_widget.py +++ b/BivariateRenderer/renderer/bivariate_renderer_widget.py @@ -1,23 +1,26 @@ -from qgis.PyQt.QtGui import (QImage, QColor, QPainter, QPixmap) -from qgis.PyQt.QtWidgets import (QFormLayout, QLabel, QComboBox) -from qgis.PyQt.QtCore import pyqtSignal, Qt +from qgis.core import ( + QgsClassificationEqualInterval, + QgsClassificationJenks, + QgsClassificationLogarithmic, + QgsClassificationPrettyBreaks, + QgsClassificationQuantile, + QgsFieldProxyModel, + QgsGradientColorRamp, + QgsRenderContext, +) +from qgis.gui import QgsColorRampButton, QgsDoubleSpinBox, QgsFieldComboBox, QgsRendererWidget +from qgis.PyQt.QtCore import Qt, pyqtSignal +from qgis.PyQt.QtGui import QColor, QImage, QPainter, QPixmap +from qgis.PyQt.QtWidgets import QComboBox, QFormLayout, QLabel -from qgis.gui import (QgsRendererWidget, QgsColorRampButton, QgsFieldComboBox, QgsDoubleSpinBox) - -from qgis.core import (QgsGradientColorRamp, QgsClassificationJenks, - QgsClassificationEqualInterval, QgsClassificationQuantile, - QgsClassificationPrettyBreaks, QgsClassificationLogarithmic, - QgsFieldProxyModel, QgsRenderContext) - -from .bivariate_renderer import BivariateRenderer -from ..legendrenderer.legend_renderer import LegendRenderer from ..colormixing.color_mixing_methods_register import ColorMixingMethodsRegister +from ..colorramps.bivariate_color_ramp import BivariateColorRamp, BivariateColorRampGradient from ..colorramps.color_ramps_register import BivariateColorRampsRegister -from .bivariate_legend import BivariateLegendViewerLegend - -from ..utils import (log) - +from ..legendrenderer.legend_renderer import LegendRenderer from ..text_constants import Texts +from ..utils import log +from .bivariate_legend import BivariateLegendViewerLegend +from .bivariate_renderer import BivariateRenderer class BivariateRendererWidget(QgsRendererWidget): @@ -33,6 +36,10 @@ class BivariateRendererWidget(QgsRendererWidget): default_color_ramp_1 = register_color_ramps.get_by_name("Violet - Blue").color_ramp_1 default_color_ramp_2 = register_color_ramps.get_by_name("Violet - Blue").color_ramp_2 + bivariate_color_ramp = BivariateColorRampGradient(9) + bivariate_color_ramp.set_color_ramp_1(default_color_ramp_1) + bivariate_color_ramp.set_color_ramp_2(default_color_ramp_2) + bivariate_renderer: BivariateRenderer legend_renderer: LegendRenderer @@ -42,7 +49,7 @@ class BivariateRendererWidget(QgsRendererWidget): QgsClassificationJenks().name(): QgsClassificationJenks(), QgsClassificationQuantile().name(): QgsClassificationQuantile(), QgsClassificationPrettyBreaks().name(): QgsClassificationPrettyBreaks(), - QgsClassificationLogarithmic().name(): QgsClassificationLogarithmic() + QgsClassificationLogarithmic().name(): QgsClassificationLogarithmic(), } scale_factor = 1 @@ -58,6 +65,7 @@ def __init__(self, layer, style, renderer: BivariateRenderer): else: self.bivariate_renderer = renderer.clone() self.bivariate_renderer.generateCategories() + self.bivariate_color_ramp = self.bivariate_renderer.bivariate_color_ramp self.legend_renderer = LegendRenderer() @@ -103,20 +111,18 @@ def __init__(self, layer, style, renderer: BivariateRenderer): self.sb_number_classes.setMinimum(2) self.sb_number_classes.setMaximum(5) self.sb_number_classes.setSingleStep(1) - self.sb_number_classes.valueChanged.connect(self.setNumberOfClasses) - self.sb_number_classes.setValue(self.bivariate_renderer.number_classes) + self.sb_number_classes.setValue(self.bivariate_renderer.bivariate_color_ramp.number_of_classes) self.cb_classification_methods = QComboBox() self.cb_classification_methods.addItems(list(self.classification_methods.keys())) - self.cb_classification_methods.currentIndexChanged.connect(self.setClassificationMethod) if self.bivariate_renderer.classification_method: - if self.bivariate_renderer.classification_method.name() in list( - self.classification_methods.keys()): + if self.bivariate_renderer.classification_method.name() in list(self.classification_methods.keys()): - index = list(self.classification_methods.keys()).\ - index(self.bivariate_renderer.classification_method.name()) + index = list(self.classification_methods.keys()).index( + self.bivariate_renderer.classification_method.name() + ) else: @@ -129,12 +135,13 @@ def __init__(self, layer, style, renderer: BivariateRenderer): self.cb_classification_methods.setCurrentIndex(0) self.cb_colormixing_methods = QComboBox() + self.cb_colormixing_methods.addItems(self.register_color_mixing.names) - self.cb_colormixing_methods.currentIndexChanged.connect(self.setColorMixingMethod) - if self.bivariate_renderer.color_mixing_method: + if self.bivariate_renderer.bivariate_color_ramp.color_mixing_method: self.cb_colormixing_methods.setCurrentText( - self.bivariate_renderer.color_mixing_method.name()) + self.bivariate_renderer.bivariate_color_ramp.color_mixing_method.name() + ) else: self.cb_colormixing_methods.setCurrentIndex(1) @@ -154,18 +161,16 @@ def __init__(self, layer, style, renderer: BivariateRenderer): self.cb_color_ramps.currentIndexChanged.connect(self.change_color_ramps) self.bt_color_ramp1 = QgsColorRampButton() - self.bt_color_ramp1.colorRampChanged.connect(self.setColorRamp1) - if self.bivariate_renderer.color_ramp_1: - self.bt_color_ramp1.setColorRamp(self.bivariate_renderer.color_ramp_1) + if self.bivariate_renderer.bivariate_color_ramp.color_ramp_1: + self.bt_color_ramp1.setColorRamp(self.bivariate_renderer.bivariate_color_ramp.color_ramp_1) else: self.bt_color_ramp1.setColorRamp(self.default_color_ramp_1) self.bt_color_ramp2 = QgsColorRampButton() - self.bt_color_ramp2.colorRampChanged.connect(self.setColorRamp2) - if self.bivariate_renderer.color_ramp_2: - self.bt_color_ramp2.setColorRamp(self.bivariate_renderer.color_ramp_2) + if self.bivariate_renderer.bivariate_color_ramp.color_ramp_2: + self.bt_color_ramp2.setColorRamp(self.bivariate_renderer.bivariate_color_ramp.color_ramp_2) else: self.bt_color_ramp2.setColorRamp(self.default_color_ramp_2) @@ -186,7 +191,8 @@ def __init__(self, layer, style, renderer: BivariateRenderer): self.form_layout.addRow( QLabel( "Data are categorized using Equal Interval classification\nmethod into provided number of categories for both fields." - )) + ) + ) # self.form_layout.addRow("Select classification method:", self.cb_classification_methods) self.form_layout.addRow("Color mixing method", self.cb_colormixing_methods) self.form_layout.addRow("Field 1", self.cb_field1) @@ -197,6 +203,14 @@ def __init__(self, layer, style, renderer: BivariateRenderer): self.form_layout.addRow("Legend", self.label_legend) self.setLayout(self.form_layout) + self.sb_number_classes.valueChanged.connect(self.update_bivariate_color_ramp) + self.cb_classification_methods.currentIndexChanged.connect(self.update_bivariate_color_ramp) + self.bt_color_ramp1.colorRampChanged.connect(self.update_bivariate_color_ramp) + self.bt_color_ramp2.colorRampChanged.connect(self.update_bivariate_color_ramp) + self.cb_colormixing_methods.currentIndexChanged.connect(self.update_bivariate_color_ramp) + + self.update_bivariate_color_ramp() + self.update_legend() def rotate_palette(self): @@ -261,8 +275,9 @@ def update_legend(self): self.legend_renderer.set_space_above_ticks(self.text_ticks_size / 2) - self.legend_renderer.render(context, self.legend_size, self.legend_size, - self.bivariate_renderer.generate_legend_polygons()) + self.legend_renderer.render( + context, self.legend_size, self.legend_size, self.bivariate_renderer.generate_legend_polygons() + ) painter.end() @@ -274,26 +289,19 @@ def updateLayerLegend(self): legend = BivariateLegendViewerLegend(self.bivariate_renderer, self.vectorLayer()) self.vectorLayer().setLegend(legend) - def setNumberOfClasses(self) -> None: - - self.bivariate_renderer.setNumberOfClasses(int(self.sb_number_classes.value())) - - self.setField1Classes() - self.setField2Classes() - - self.legend_changed.emit() + def update_bivariate_color_ramp(self) -> None: + self.bivariate_color_ramp.set_number_of_classes(int(self.sb_number_classes.value())) - def setColorMixingMethod(self) -> None: + self.bivariate_color_ramp.set_color_mixing_method( + self.register_color_mixing.get_by_name(self.cb_colormixing_methods.currentText()) + ) - self.bivariate_renderer.setColorMixingMethod( - self.register_color_mixing.get_by_name(self.cb_colormixing_methods.currentText())) + self.bivariate_color_ramp.set_color_ramp_1(self.bt_color_ramp1.colorRamp()) + self.bivariate_color_ramp.set_color_ramp_2(self.bt_color_ramp2.colorRamp()) - self.legend_changed.emit() - - def setClassificationMethod(self) -> None: + self.bivariate_renderer.set_bivariate_color_ramp(self.bivariate_color_ramp) - classification_method = self.classification_methods[ - self.cb_classification_methods.currentText()] + classification_method = self.classification_methods[self.cb_classification_methods.currentText()] self.bivariate_renderer.setClassificationMethod(classification_method) @@ -302,18 +310,6 @@ def setClassificationMethod(self) -> None: self.legend_changed.emit() - def setColorRamp1(self) -> None: - - self.bivariate_renderer.setColorRamp1(self.bt_color_ramp1.colorRamp()) - - self.legend_changed.emit() - - def setColorRamp2(self) -> None: - - self.bivariate_renderer.setColorRamp2(self.bt_color_ramp2.colorRamp()) - - self.legend_changed.emit() - def setFieldName1(self) -> None: self.field_name_1 = self.cb_field1.currentText() @@ -354,5 +350,14 @@ def change_color_ramps(self) -> None: if name != "": bivariate_color_ramp = self.register_color_ramps.get_by_name(name) + self.bivariate_color_ramp = bivariate_color_ramp + self.bivariate_renderer.set_bivariate_color_ramp(bivariate_color_ramp) + + self.bt_color_ramp1.blockSignals(True) + self.bt_color_ramp2.blockSignals(True) self.bt_color_ramp1.setColorRamp(bivariate_color_ramp.color_ramp_1) self.bt_color_ramp2.setColorRamp(bivariate_color_ramp.color_ramp_2) + self.bt_color_ramp1.blockSignals(False) + self.bt_color_ramp2.blockSignals(False) + + self.legend_changed.emit() diff --git a/BivariateRenderer/tools/tool_calculate_categories.py b/BivariateRenderer/tools/tool_calculate_categories.py index db1552a..bfda153 100755 --- a/BivariateRenderer/tools/tool_calculate_categories.py +++ b/BivariateRenderer/tools/tool_calculate_categories.py @@ -1,7 +1,14 @@ -from qgis.core import (QgsProcessingAlgorithm, QgsProcessingParameterVectorLayer, QgsProcessing, - QgsProcessingParameterNumber, QgsProcessingParameterField, - QgsProcessingParameterString, QgsField, QgsClassificationEqualInterval) -from qgis.PyQt.QtCore import (QVariant) +from qgis.core import ( + QgsClassificationEqualInterval, + QgsField, + QgsProcessing, + QgsProcessingAlgorithm, + QgsProcessingParameterField, + QgsProcessingParameterNumber, + QgsProcessingParameterString, + QgsProcessingParameterVectorLayer, +) +from qgis.PyQt.QtCore import QVariant class CalculateCategoriesAlgorithm(QgsProcessingAlgorithm): @@ -15,20 +22,28 @@ class CalculateCategoriesAlgorithm(QgsProcessingAlgorithm): def initAlgorithm(self, config=None): self.addParameter( - QgsProcessingParameterVectorLayer(self.INPUT_LAYER, "Input polygon layer", - [QgsProcessing.TypeVectorPolygon])) + QgsProcessingParameterVectorLayer( + self.INPUT_LAYER, "Input polygon layer", [QgsProcessing.TypeVectorPolygon] + ) + ) self.addParameter( - QgsProcessingParameterField(self.FIELD_1, - "Select field 1", - parentLayerParameterName=self.INPUT_LAYER, - type=QgsProcessingParameterField.Numeric)) + QgsProcessingParameterField( + self.FIELD_1, + "Select field 1", + parentLayerParameterName=self.INPUT_LAYER, + type=QgsProcessingParameterField.Numeric, + ) + ) self.addParameter( - QgsProcessingParameterField(self.FIELD_2, - "Select field 2", - parentLayerParameterName=self.INPUT_LAYER, - type=QgsProcessingParameterField.Numeric)) + QgsProcessingParameterField( + self.FIELD_2, + "Select field 2", + parentLayerParameterName=self.INPUT_LAYER, + type=QgsProcessingParameterField.Numeric, + ) + ) self.addParameter( QgsProcessingParameterNumber( @@ -37,12 +52,13 @@ def initAlgorithm(self, config=None): type=QgsProcessingParameterNumber.Integer, minValue=2, maxValue=5, - defaultValue=3)) + defaultValue=3, + ) + ) self.addParameter( - QgsProcessingParameterString(self.RESULT_FIELD_NAME, - "Result field name", - defaultValue="Category")) + QgsProcessingParameterString(self.RESULT_FIELD_NAME, "Result field name", defaultValue="Category") + ) def processAlgorithm(self, parameters, context, feedback): @@ -85,8 +101,7 @@ def processAlgorithm(self, parameters, context, feedback): if range_class.lowerBound() <= field_2_value <= range_class.upperBound(): class_value_2 = i + 1 - layer.changeAttributeValue(feature.id(), field_index, - "{}-{}".format(class_value_1, class_value_2)) + layer.changeAttributeValue(feature.id(), field_index, "{}-{}".format(class_value_1, class_value_2)) feedback.setProgress((number / feature_count) * 100) diff --git a/BivariateRenderer/utils.py b/BivariateRenderer/utils.py index 52d32a1..d18c33a 100755 --- a/BivariateRenderer/utils.py +++ b/BivariateRenderer/utils.py @@ -1,9 +1,8 @@ -from typing import Dict, Any import json from pathlib import Path +from typing import Any, Dict -from qgis.core import (QgsMessageLog, Qgis, QgsLineSymbol, QgsSymbol, QgsSymbolLayerUtils, - QgsReadWriteContext) +from qgis.core import Qgis, QgsLineSymbol, QgsMessageLog, QgsReadWriteContext, QgsSymbol, QgsSymbolLayerUtils from qgis.PyQt.QtGui import QColor, QIcon from qgis.PyQt.QtXml import QDomDocument @@ -17,17 +16,15 @@ def log(text: Any) -> None: # these two functions are taken from # https://github.com/TomasdelaBarra/QTRANUS/blob/c32c11f02faec561b1825479b3251c096c5f36ea/add_linktype_dialog.py def get_symbol_object(symbol_obj: Dict) -> QgsLineSymbol: - """ Return dictionary with objects of symbol""" + """Return dictionary with objects of symbol""" - from qgis.core import (QgsArrowSymbolLayer, QgsSimpleLineSymbolLayer, QgsLineSymbol) + from qgis.core import QgsArrowSymbolLayer, QgsLineSymbol, QgsSimpleLineSymbolLayer # symbol_obj = json.loads(symbol_srt.replace("'", '"').replace("ArrowLine", "Arrow")) symbol_layers = QgsLineSymbol() - for layer_symbol in symbol_obj['layers_list']: - obj_symbol = eval( - f"Qgs{layer_symbol['type_layer']}SymbolLayer.create({layer_symbol['properties_layer']})" - ) + for layer_symbol in symbol_obj["layers_list"]: + obj_symbol = eval(f"Qgs{layer_symbol['type_layer']}SymbolLayer.create({layer_symbol['properties_layer']})") symbol_layers.appendSymbolLayer(obj_symbol) symbol_layers.deleteSymbolLayer(0) @@ -36,17 +33,19 @@ def get_symbol_object(symbol_obj: Dict) -> QgsLineSymbol: def get_symbol_dict(symbol: QgsSymbol) -> Dict: - """ Return dictionary with main elements of symbol """ + """Return dictionary with main elements of symbol""" symbol_dict = dict() - symbol_dict['type'] = symbol.type() - symbol_dict['layers_list'] = [] + symbol_dict["type"] = symbol.type() + symbol_dict["layers_list"] = [] for index in range(0, symbol.symbolLayerCount()): - symbol_dict['layers_list'].append({ - 'type_layer': symbol.symbolLayer(index).layerType().split(':')[0], - 'properties_layer': symbol.symbolLayer(index).properties(), - }) + symbol_dict["layers_list"].append( + { + "type_layer": symbol.symbolLayer(index).layerType().split(":")[0], + "properties_layer": symbol.symbolLayer(index).properties(), + } + ) return symbol_dict @@ -71,8 +70,7 @@ def load_json(content: str) -> Dict: def default_line_symbol() -> QgsLineSymbol: - line_symbol = get_symbol_object( - load_json(read_file_content(path_data("axis_line_symbol.json")))) + line_symbol = get_symbol_object(load_json(read_file_content(path_data("axis_line_symbol.json")))) line_symbol.setColor(QColor(0, 0, 0)) return line_symbol @@ -83,18 +81,18 @@ def path_icon(file_name: str) -> Path: return Path(__file__).parent / "icons" / file_name -def get_icon(file_name: str) -> QIcon: +def get_icon_path(file_name: str) -> str: path = path_icon(file_name) - return QIcon(path.absolute().as_posix()) + return path.absolute().as_posix() def save_symbol_xml(symbol: QgsSymbol, file_name: Path) -> None: doc = QDomDocument() - elem = QgsSymbolLayerUtils.saveSymbol('symbol', symbol, doc, QgsReadWriteContext()) + elem = QgsSymbolLayerUtils.saveSymbol("symbol", symbol, doc, QgsReadWriteContext()) doc.appendChild(elem) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..575b199 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,34 @@ +[options.extras_require] +test = [ + "pytest", + "pytest-cov", + "pytest-qgis" +] + +[flake8] +exclude = [ + ".git", + "__pycache__", + "tests/*" +] +max-line-length = 120 + + +[tool.pytest.ini_options] +addopts = "-vv -rP -s --cov=BivariateRenderer --cov-report=term-missing:skip-covered --ignore=tests/tests_visual_result_generation" +testpaths = [ + "tests" +] + +[tool.black] +line-length = 120 + +[tool.isort] +atomic = true +profile = "black" +line_length = 120 +skip_gitignore = true + +[tool.pylint.'MESSAGES CONTROL'] +max-line-length = 120 +disable = "" \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py index ff24976..2a977c7 100755 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,13 +1,14 @@ +import inspect +import tempfile +from pathlib import Path from typing import Union -import pytest - -from qgis.core import (QgsReadWriteContext, QgsTextFormat) - -from qgis.PyQt.QtXml import QDomElement, QDomDocument - -from PIL import Image import numpy as np +import pytest +from PIL import Image +from pixelmatch.contrib.PIL import pixelmatch +from qgis.core import QgsReadWriteContext, QgsTextFormat +from qgis.PyQt.QtXml import QDomDocument, QDomElement from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer @@ -47,7 +48,7 @@ def assert_images_equal(image_1: str, image_2: str): img2 = img2.convert(img1.mode) img2 = img2.resize(img1.size) - sum_sq_diff = np.sum((np.asarray(img1).astype('float') - np.asarray(img2).astype('float'))**2) + sum_sq_diff = np.sum((np.asarray(img1).astype("float") - np.asarray(img2).astype("float")) ** 2) if 0 < sum_sq_diff: normalized_sum_sq_diff = sum_sq_diff / np.sqrt(sum_sq_diff) @@ -55,8 +56,23 @@ def assert_images_equal(image_1: str, image_2: str): normalized_sum_sq_diff = 0 if normalized_sum_sq_diff > 0.001: + diff_mask = Image.new("RGBA", img1.size) + pixelmatch(img1, img2, diff_mask, includeAA=True) + + diff_image_filenaname = diff_image_name(inspect.stack()[1]) + diff_mask.save(diff_image_filenaname) + __tracebackhide__ = True - pytest.fail(f"Images \n{image_1}\n{image_2}\ndo not look the same.\n" - f"Difference is {normalized_sum_sq_diff}.") - else: - pass + pytest.fail( + f"Images \n{image_1}\n{image_2}\ndo not look the same.\n" + f"Difference is {normalized_sum_sq_diff}. Diff file {diff_image_filenaname.as_posix()}." + ) + + +def diff_image_name(frame: inspect.FrameInfo) -> Path: + """Get the filename for the diff image based on previous frame - file na function name.""" + diff_dir = Path(tempfile.gettempdir()) / "images_diff" + if not diff_dir.exists(): + diff_dir.mkdir(exist_ok=True) + filename = diff_dir / f"{Path(frame.filename).stem}-{frame.function}.png" + return filename diff --git a/tests/conftest.py b/tests/conftest.py index 516aa1e..5f4c35d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,20 +1,35 @@ -import pytest from pathlib import Path from typing import Optional, Union -from pytest_qgis import clean_qgis_layer - -from qgis.core import (QgsProject, QgsVectorLayer, QgsLayout, QgsLayoutItemPage, QgsLayoutSize, - QgsUnitTypes, QgsStyle, QgsLayoutItemMap, QgsLayoutExporter) +import pytest +from qgis.core import ( + QgsLayout, + QgsLayoutExporter, + QgsLayoutItemMap, + QgsLayoutItemPage, + QgsLayoutSize, + QgsProject, + QgsStyle, + QgsUnitTypes, + QgsVectorLayer, +) from qgis.gui import QgsMapCanvas -from qgis.PyQt.QtGui import QImage, qRgba, QPainter -from qgis.PyQt.QtCore import QRectF, QSize - +from qgis.PyQt.QtCore import QLocale, QRectF, QSize +from qgis.PyQt.QtGui import QImage, QPainter, qRgba + +from BivariateRenderer.colorramps.color_ramps_register import ( + BivariateColorRamp, + BivariateColorRampGreenPink, + BivariateColorRampsRegister, +) from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer from BivariateRenderer.renderer.bivariate_renderer_widget import BivariateRendererWidget -from BivariateRenderer.colorramps.color_ramps_register import (BivariateColorRamp, - BivariateColorRampGreenPink, - BivariateColorRampsRegister) + + +@pytest.fixture(autouse=True, scope="session") +def change_locale(): + """Sets locale to English, United Kingdom for all tests to ensure consistent results.""" + QLocale.setDefault(QLocale(QLocale.Language.English, QLocale.Country.UnitedKingdom)) @pytest.fixture @@ -39,7 +54,6 @@ def nc_layer_path() -> str: @pytest.fixture() -@clean_qgis_layer def nc_layer(nc_layer_path) -> QgsVectorLayer: layer = QgsVectorLayer(nc_layer_path, "layer", "ogr") @@ -90,8 +104,7 @@ def layout_space(layout_height, layout_width) -> QRectF: @pytest.fixture -def layout_page_a4(qgs_layout: QgsLayout, layout_dpmm, layout_height, - layout_width) -> QgsLayoutItemPage: +def layout_page_a4(qgs_layout: QgsLayout, layout_dpmm, layout_height, layout_width) -> QgsLayoutItemPage: page = QgsLayoutItemPage(qgs_layout) page.setPageSize(QgsLayoutSize(layout_width, layout_height, QgsUnitTypes.LayoutMillimeters)) @@ -104,28 +117,18 @@ def layout_page_a4(qgs_layout: QgsLayout, layout_dpmm, layout_height, def prepare_bivariate_renderer(): def return_bivariate_renderer( - layer: QgsVectorLayer, - field1: str = "", - field2: str = "", - color_ramps: Optional[BivariateColorRamp] = None) -> BivariateRenderer: - - if color_ramps is None: - - color_ramp = BivariateColorRampsRegister().get_by_name("Violet - Blue") - - default_color_ramp_1 = color_ramp.color_ramp_1 - default_color_ramp_2 = color_ramp.color_ramp_2 + layer: QgsVectorLayer, field1: str = "", field2: str = "", color_ramp: Optional[BivariateColorRamp] = None + ) -> BivariateRenderer: - else: + color_ramp_bivariate = BivariateColorRampsRegister().get_by_name("Violet - Blue") - default_color_ramp_1 = color_ramps.color_ramp_1 - default_color_ramp_2 = color_ramps.color_ramp_2 + if color_ramp: + color_ramp_bivariate = color_ramp bivariate_renderer = BivariateRenderer() bivariate_renderer.setFieldName1(field1) bivariate_renderer.setFieldName2(field2) - bivariate_renderer.setColorRamp1(default_color_ramp_1) - bivariate_renderer.setColorRamp2(default_color_ramp_2) + bivariate_renderer.set_bivariate_color_ramp(color_ramp_bivariate) bivariate_renderer.setField1ClassificationData(layer, bivariate_renderer.field_name_1) bivariate_renderer.setField2ClassificationData(layer, bivariate_renderer.field_name_2) @@ -138,14 +141,11 @@ def return_bivariate_renderer( def prepare_bivariate_renderer_widget(prepare_bivariate_renderer): def return_bivariate_renderer_widget(layer: QgsVectorLayer) -> BivariateRendererWidget: - bivariate_renderer = prepare_bivariate_renderer(layer, - field1="AREA", - field2="PERIMETER", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + layer, field1="AREA", field2="PERIMETER", color_ramp=BivariateColorRampGreenPink() + ) - widget = BivariateRendererWidget(layer=layer, - style=QgsStyle(), - renderer=bivariate_renderer) + widget = BivariateRendererWidget(layer=layer, style=QgsStyle(), renderer=bivariate_renderer) return widget @@ -155,12 +155,14 @@ def return_bivariate_renderer_widget(layer: QgsVectorLayer) -> BivariateRenderer @pytest.fixture def save_layout_for_layer(qgs_layout, layout_page_a4, layout_space, export_page_to_image): - def function_to_run(layer: QgsVectorLayer, - image_path: Union[str, Path], - qgs_layout: QgsLayout = qgs_layout, - page=layout_page_a4, - layout_space=layout_space, - export_page_to_image=export_page_to_image) -> None: + def function_to_run( + layer: QgsVectorLayer, + image_path: Union[str, Path], + qgs_layout: QgsLayout = qgs_layout, + page=layout_page_a4, + layout_space=layout_space, + export_page_to_image=export_page_to_image, + ) -> None: canvas = QgsMapCanvas() @@ -183,10 +185,9 @@ def function_to_run(layer: QgsVectorLayer, @pytest.fixture def export_page_to_image(layout_dpmm): - def function_to_run(qgs_layout: QgsLayout, - page: QgsLayoutItemPage, - image_path: Union[Path, str], - DPMM=layout_dpmm) -> None: + def function_to_run( + qgs_layout: QgsLayout, page: QgsLayoutItemPage, image_path: Union[Path, str], DPMM=layout_dpmm + ) -> None: if isinstance(image_path, Path): image_path = image_path.as_posix() diff --git a/tests/images/correct/layout_item_legend.png b/tests/images/correct/layout_item_legend.png index c162168..373c7b3 100755 Binary files a/tests/images/correct/layout_item_legend.png and b/tests/images/correct/layout_item_legend.png differ diff --git a/tests/images/correct/layout_polygons_render.png b/tests/images/correct/layout_polygons_render.png index 10e0716..b9ab70b 100755 Binary files a/tests/images/correct/layout_polygons_render.png and b/tests/images/correct/layout_polygons_render.png differ diff --git a/tests/images/correct/legend_only.png b/tests/images/correct/legend_only.png index c2d87ab..989ccd8 100755 Binary files a/tests/images/correct/legend_only.png and b/tests/images/correct/legend_only.png differ diff --git a/tests/images/correct/legend_only_darken.png b/tests/images/correct/legend_only_darken.png index c2d87ab..989ccd8 100755 Binary files a/tests/images/correct/legend_only_darken.png and b/tests/images/correct/legend_only_darken.png differ diff --git a/tests/images/correct/legend_only_direct_mixing.png b/tests/images/correct/legend_only_direct_mixing.png index 8dc76b2..989ccd8 100755 Binary files a/tests/images/correct/legend_only_direct_mixing.png and b/tests/images/correct/legend_only_direct_mixing.png differ diff --git a/tests/images/correct/legend_replaced_missing_values.png b/tests/images/correct/legend_replaced_missing_values.png index 347958e..d436318 100644 Binary files a/tests/images/correct/legend_replaced_missing_values.png and b/tests/images/correct/legend_replaced_missing_values.png differ diff --git a/tests/images/correct/legend_with_all.png b/tests/images/correct/legend_with_all.png index f5b9df0..411c2f3 100755 Binary files a/tests/images/correct/legend_with_all.png and b/tests/images/correct/legend_with_all.png differ diff --git a/tests/images/correct/legend_with_all_rotated.png b/tests/images/correct/legend_with_all_rotated.png index bbe2708..718cc7b 100755 Binary files a/tests/images/correct/legend_with_all_rotated.png and b/tests/images/correct/legend_with_all_rotated.png differ diff --git a/tests/images/correct/legend_with_arrows.png b/tests/images/correct/legend_with_arrows.png index b50ecd5..417e7ed 100755 Binary files a/tests/images/correct/legend_with_arrows.png and b/tests/images/correct/legend_with_arrows.png differ diff --git a/tests/images/correct/legend_with_arrows_common_origin.png b/tests/images/correct/legend_with_arrows_common_origin.png index 311e848..60e2f9a 100755 Binary files a/tests/images/correct/legend_with_arrows_common_origin.png and b/tests/images/correct/legend_with_arrows_common_origin.png differ diff --git a/tests/images/correct/legend_with_arrows_texts.png b/tests/images/correct/legend_with_arrows_texts.png index 0c92ed5..b254ab8 100755 Binary files a/tests/images/correct/legend_with_arrows_texts.png and b/tests/images/correct/legend_with_arrows_texts.png differ diff --git a/tests/images/correct/legend_with_arrows_texts_rotated.png b/tests/images/correct/legend_with_arrows_texts_rotated.png index 130cdd0..2ed5862 100755 Binary files a/tests/images/correct/legend_with_arrows_texts_rotated.png and b/tests/images/correct/legend_with_arrows_texts_rotated.png differ diff --git a/tests/images/correct/legend_with_spacer.png b/tests/images/correct/legend_with_spacer.png index 18c0ece..c6a442f 100755 Binary files a/tests/images/correct/legend_with_spacer.png and b/tests/images/correct/legend_with_spacer.png differ diff --git a/tests/images/correct/legend_with_values_ticks.png b/tests/images/correct/legend_with_values_ticks.png index 85230bf..02532ab 100755 Binary files a/tests/images/correct/legend_with_values_ticks.png and b/tests/images/correct/legend_with_values_ticks.png differ diff --git a/tests/images/correct/legend_with_values_ticks_midpoints.png b/tests/images/correct/legend_with_values_ticks_midpoints.png index cb3eb2a..9d5e0bb 100755 Binary files a/tests/images/correct/legend_with_values_ticks_midpoints.png and b/tests/images/correct/legend_with_values_ticks_midpoints.png differ diff --git a/tests/images/correct/widget_layout_item.png b/tests/images/correct/widget_layout_item.png index 42a1bdf..0bbc35c 100755 Binary files a/tests/images/correct/widget_layout_item.png and b/tests/images/correct/widget_layout_item.png differ diff --git a/tests/images/correct/widget_renderer.png b/tests/images/correct/widget_renderer.png index 0b8a171..7080265 100755 Binary files a/tests/images/correct/widget_renderer.png and b/tests/images/correct/widget_renderer.png differ diff --git a/tests/test_bivariate_renderer.py b/tests/test_bivariate_renderer.py index 4e879e2..57c6594 100755 --- a/tests/test_bivariate_renderer.py +++ b/tests/test_bivariate_renderer.py @@ -1,20 +1,19 @@ from PyQt5.QtXml import QDomElement -from qgis.core import (QgsVectorLayer, QgsProject, QgsReadWriteContext) +from qgis.core import QgsProject, QgsReadWriteContext, QgsVectorLayer from qgis.PyQt.QtXml import QDomDocument from BivariateRenderer.colorramps.color_ramps_register import BivariateColorRampGreenPink from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer - from tests import assert_images_equal -def test_layer_bivariate_render(nc_layer: QgsVectorLayer, qgs_project: QgsProject, - prepare_bivariate_renderer, save_layout_for_layer): +def test_layer_bivariate_render( + nc_layer: QgsVectorLayer, qgs_project: QgsProject, prepare_bivariate_renderer, save_layout_for_layer +): - bivariate_renderer = prepare_bivariate_renderer(nc_layer, - field1="AREA", - field2="PERIMETER", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + nc_layer, field1="AREA", field2="PERIMETER", color_ramp=BivariateColorRampGreenPink() + ) nc_layer.setRenderer(bivariate_renderer) @@ -29,10 +28,9 @@ def test_layer_bivariate_render(nc_layer: QgsVectorLayer, qgs_project: QgsProjec def test_functions(nc_layer: QgsVectorLayer, prepare_bivariate_renderer): - bivariate_renderer = prepare_bivariate_renderer(nc_layer, - field1="AREA", - field2="PERIMETER", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + nc_layer, field1="AREA", field2="PERIMETER", color_ramp=BivariateColorRampGreenPink() + ) xml_renderer = """ @@ -102,11 +100,9 @@ def test_functions(nc_layer: QgsVectorLayer, prepare_bivariate_renderer): xml.setContent(xml_renderer) element = xml.documentElement() - renderer_from_xml = BivariateRenderer.create_render_from_element(element, - QgsReadWriteContext()) + renderer_from_xml = BivariateRenderer.create_render_from_element(element, QgsReadWriteContext()) assert renderer_from_xml assert bivariate_renderer == renderer_from_xml - assert isinstance(bivariate_renderer.save(QDomDocument("doc"), QgsReadWriteContext()), - QDomElement) + assert isinstance(bivariate_renderer.save(QDomDocument("doc"), QgsReadWriteContext()), QDomElement) diff --git a/tests/test_bivariate_renderer_widget.py b/tests/test_bivariate_renderer_widget.py index a6c82ea..615dae4 100644 --- a/tests/test_bivariate_renderer_widget.py +++ b/tests/test_bivariate_renderer_widget.py @@ -1,12 +1,11 @@ -from qgis.core import (QgsVectorLayer, QgsClassificationMethod, QgsTextFormat) -from qgis.gui import (QgsFieldComboBox, QgsDoubleSpinBox, QgsColorRampButton) -from qgis.PyQt.QtWidgets import (QComboBox, QLabel, QFormLayout) +from qgis.core import QgsClassificationMethod, QgsTextFormat, QgsVectorLayer +from qgis.gui import QgsColorRampButton, QgsDoubleSpinBox, QgsFieldComboBox +from qgis.PyQt.QtWidgets import QComboBox, QFormLayout, QLabel -from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink from BivariateRenderer.legendrenderer.legend_renderer import LegendRenderer - -from tests import (assert_images_equal) +from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer +from tests import assert_images_equal def test_widget_elements(nc_layer: QgsVectorLayer, prepare_bivariate_renderer_widget): diff --git a/tests/test_color_mixing.py b/tests/test_color_mixing.py index ae2c01d..b347e91 100644 --- a/tests/test_color_mixing.py +++ b/tests/test_color_mixing.py @@ -1,10 +1,13 @@ +from qgis.core import QgsLayoutUtils from qgis.PyQt.QtGui import QPainter -from qgis.core import (QgsLayoutUtils) -from BivariateRenderer.legendrenderer.legend_renderer import LegendRenderer -from BivariateRenderer.colormixing.color_mixing_method import ColorMixingMethodDarken, ColorMixingMethodDirect, ColorMixingMethod +from BivariateRenderer.colormixing.color_mixing_method import ( + ColorMixingMethod, + ColorMixingMethodDarken, + ColorMixingMethodDirect, +) from BivariateRenderer.colormixing.color_mixing_methods_register import ColorMixingMethodsRegister - +from BivariateRenderer.legendrenderer.legend_renderer import LegendRenderer from tests import assert_images_equal @@ -24,8 +27,9 @@ def test_color_mixing_register(): assert register.get_by_name("does not exist") is None -def test_color_mixing_direct_mixing(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_color_mixing_direct_mixing( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -37,26 +41,27 @@ def test_color_mixing_direct_mixing(qgis_countries_layer, qgs_project, qgs_layou assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() legend_renderer = LegendRenderer() - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("./tests/images/correct/legend_only_direct_mixing.png", - "./tests/images/image.png") + assert_images_equal("./tests/images/correct/legend_only_direct_mixing.png", "./tests/images/image.png") -def test_color_mixing_darken(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer): +def test_color_mixing_darken( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -68,19 +73,19 @@ def test_color_mixing_darken(qgis_countries_layer, qgs_project, qgs_layout, prep assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDarken() legend_renderer = LegendRenderer() - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("./tests/images/correct/legend_only_darken.png", - "./tests/images/image.png") + assert_images_equal("./tests/images/correct/legend_only_darken.png", "./tests/images/image.png") diff --git a/tests/test_color_ramps.py b/tests/test_color_ramps.py index 7ad9b7c..66cc59c 100644 --- a/tests/test_color_ramps.py +++ b/tests/test_color_ramps.py @@ -1,14 +1,22 @@ import pytest - from qgis.core import QgsGradientColorRamp from qgis.PyQt.QtGui import QIcon from BivariateRenderer.colorramps.bivariate_color_ramp import ( - BivariateColorRamp, BivariateColorRampBlueGreen, BivariateColorRampCyanBrow, - BivariateColorRampCyanViolet, BivariateColorRampGreenPink, BivariateColorRampGreenPurple, - BivariateColorRampLigthYellowPurple, BivariateColorRampOrangeBlue, - BivariateColorRampOrangePurple, BivariateColorRampPinkBlue, BivariateColorRampTurquoiseGold, - BivariateColorRampVioletBlue, BivariateColorRampYellowBlue) + BivariateColorRamp, + BivariateColorRampBlueGreen, + BivariateColorRampCyanBrow, + BivariateColorRampCyanViolet, + BivariateColorRampGreenPink, + BivariateColorRampGreenPurple, + BivariateColorRampLigthYellowPurple, + BivariateColorRampOrangeBlue, + BivariateColorRampOrangePurple, + BivariateColorRampPinkBlue, + BivariateColorRampTurquoiseGold, + BivariateColorRampVioletBlue, + BivariateColorRampYellowBlue, +) from BivariateRenderer.colorramps.color_ramps_register import BivariateColorRampsRegister color_ramps = [ @@ -24,7 +32,7 @@ BivariateColorRampPinkBlue(), BivariateColorRampTurquoiseGold(), BivariateColorRampVioletBlue(), - BivariateColorRampYellowBlue() + BivariateColorRampYellowBlue(), ] diff --git a/tests/test_layout_item_legend.py b/tests/test_layout_item_legend.py index 7798bf5..a958a95 100644 --- a/tests/test_layout_item_legend.py +++ b/tests/test_layout_item_legend.py @@ -1,16 +1,21 @@ from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink from BivariateRenderer.layoutitems.layout_item import BivariateRendererLayoutItem - -from tests import (assert_images_equal) - - -def test_generate_legend_in_layout(qgis_countries_layer, qgs_layout, qgs_project, layout_page_a4, - prepare_bivariate_renderer, layout_space, export_page_to_image): - - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid", - color_ramps=BivariateColorRampGreenPink()) +from tests import assert_images_equal + + +def test_generate_legend_in_layout( + qgis_countries_layer, + qgs_layout, + qgs_project, + layout_page_a4, + prepare_bivariate_renderer, + layout_space, + export_page_to_image, +): + + bivariate_renderer = prepare_bivariate_renderer( + qgis_countries_layer, field1="fid", field2="fid", color_ramp=BivariateColorRampGreenPink() + ) qgis_countries_layer.setRenderer(bivariate_renderer) diff --git a/tests/test_layout_item_widget.py b/tests/test_layout_item_widget.py index f33162e..1a76194 100755 --- a/tests/test_layout_item_widget.py +++ b/tests/test_layout_item_widget.py @@ -1,24 +1,23 @@ -from qgis.PyQt.QtWidgets import (QComboBox, QCheckBox, QPlainTextEdit, QSpinBox, QMainWindow) -from qgis.gui import (QgsFontButton, QgsSymbolButton) from qgis.core import QgsVectorLayer +from qgis.gui import QgsFontButton, QgsSymbolButton +from qgis.PyQt.QtWidgets import QCheckBox, QComboBox, QMainWindow, QPlainTextEdit, QSpinBox +from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink from BivariateRenderer.layoutitems.layout_item import BivariateRendererLayoutItem from BivariateRenderer.layoutitems.layout_item_widget import BivariateRendererLayoutItemWidget -from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink from BivariateRenderer.utils import default_line_symbol - -from tests import (assert_images_equal) +from tests import assert_images_equal -def test_layout_item_widget(qgis_countries_layer: QgsVectorLayer, qgs_layout, qgis_parent, - qgs_project, prepare_bivariate_renderer): +def test_layout_item_widget( + qgis_countries_layer: QgsVectorLayer, qgs_layout, qgis_parent, qgs_project, prepare_bivariate_renderer +): qgs_project.addMapLayer(qgis_countries_layer) - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + qgis_countries_layer, field1="fid", field2="fid", color_ramp=BivariateColorRampGreenPink() + ) qgis_countries_layer.setRenderer(bivariate_renderer) @@ -50,15 +49,13 @@ def test_layout_item_widget(qgis_countries_layer: QgsVectorLayer, qgs_layout, qg assert isinstance(widget.layout_item, BivariateRendererLayoutItem) -def test_visual(qgis_countries_layer: QgsVectorLayer, qgs_layout, qgis_parent, qgs_project, - prepare_bivariate_renderer): +def test_visual(qgis_countries_layer: QgsVectorLayer, qgs_layout, qgis_parent, qgs_project, prepare_bivariate_renderer): qgs_project.addMapLayer(qgis_countries_layer) - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + qgis_countries_layer, field1="fid", field2="fid", color_ramp=BivariateColorRampGreenPink() + ) qgis_countries_layer.setRenderer(bivariate_renderer) diff --git a/tests/test_legend_renderer.py b/tests/test_legend_renderer.py index 9692ca7..3b0737b 100755 --- a/tests/test_legend_renderer.py +++ b/tests/test_legend_renderer.py @@ -1,12 +1,11 @@ -from qgis.core import (QgsTextFormat, QgsLayoutUtils, QgsRenderContext) +from qgis.core import QgsLayoutUtils, QgsRenderContext, QgsTextFormat from qgis.PyQt.QtGui import QColor +from BivariateRenderer.colormixing.color_mixing_method import ColorMixingMethodDirect from BivariateRenderer.legendrenderer.legend_renderer import LegendRenderer from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer -from BivariateRenderer.colormixing.color_mixing_method import ColorMixingMethodDirect from BivariateRenderer.utils import get_symbol_dict - -from tests import (xml_string, assert_images_equal) +from tests import assert_images_equal, xml_string def test_default_values(): @@ -18,31 +17,33 @@ def test_default_values(): assert xml_string(legend_renderer.text_format) == xml_string(QgsTextFormat()) - assert get_symbol_dict(legend_renderer.axis_line_symbol)["layers_list"] == [{ - 'type_layer': 'ArrowLine', - 'properties_layer': { - 'arrow_start_width': '0.8', - 'arrow_start_width_unit': 'MM', - 'arrow_start_width_unit_scale': '3x:0,0,0,0,0,0', - 'arrow_type': '0', - 'arrow_width': '0.8', - 'arrow_width_unit': 'MM', - 'arrow_width_unit_scale': '3x:0,0,0,0,0,0', - 'head_length': '3', - 'head_length_unit': 'MM', - 'head_length_unit_scale': '3x:0,0,0,0,0,0', - 'head_thickness': '2', - 'head_thickness_unit': 'MM', - 'head_thickness_unit_scale': '3x:0,0,0,0,0,0', - 'head_type': '0', - 'is_curved': '1', - 'is_repeated': '1', - 'offset': '0', - 'offset_unit': 'MM', - 'offset_unit_scale': '3x:0,0,0,0,0,0', - 'ring_filter': '0' + assert get_symbol_dict(legend_renderer.axis_line_symbol)["layers_list"] == [ + { + "type_layer": "ArrowLine", + "properties_layer": { + "arrow_start_width": "0.8", + "arrow_start_width_unit": "MM", + "arrow_start_width_unit_scale": "3x:0,0,0,0,0,0", + "arrow_type": "0", + "arrow_width": "0.8", + "arrow_width_unit": "MM", + "arrow_width_unit_scale": "3x:0,0,0,0,0,0", + "head_length": "3", + "head_length_unit": "MM", + "head_length_unit_scale": "3x:0,0,0,0,0,0", + "head_thickness": "2", + "head_thickness_unit": "MM", + "head_thickness_unit_scale": "3x:0,0,0,0,0,0", + "head_type": "0", + "is_curved": "1", + "is_repeated": "1", + "offset": "0", + "offset_unit": "MM", + "offset_unit_scale": "3x:0,0,0,0,0,0", + "ring_filter": "0", + }, } - }] + ] assert QColor(0, 0, 0).name() == legend_renderer.axis_line_symbol.color().name() @@ -51,8 +52,9 @@ def test_default_values(): assert legend_renderer.add_axes_texts is False -def test_just_legend(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, prepare_painter): +def test_just_legend( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -66,15 +68,15 @@ def test_just_legend(qgis_countries_layer, qgs_project, qgs_layout, prepare_defa assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -83,8 +85,9 @@ def test_just_legend(qgis_countries_layer, qgs_project, qgs_layout, prepare_defa assert_images_equal("tests/images/correct/legend_only.png", "tests/images/image.png") -def test_legend_with_arrows(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, prepare_painter): +def test_legend_with_arrows( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -98,16 +101,16 @@ def test_legend_with_arrows(qgis_countries_layer, qgs_project, qgs_layout, prepa assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -116,9 +119,9 @@ def test_legend_with_arrows(qgis_countries_layer, qgs_project, qgs_layout, prepa assert_images_equal("tests/images/correct/legend_with_arrows.png", "tests/images/image.png") -def test_legend_with_arrows_texts(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer, - prepare_painter): +def test_legend_with_arrows_texts( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -132,29 +135,28 @@ def test_legend_with_arrows_texts(qgis_countries_layer, qgs_project, qgs_layout, assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True legend_renderer.add_axes_texts = True - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_with_arrows_texts.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_with_arrows_texts.png", "tests/images/image.png") -def test_legend_with_arrows_texts_rotated(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer, - prepare_painter): +def test_legend_with_arrows_texts_rotated( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -168,29 +170,29 @@ def test_legend_with_arrows_texts_rotated(qgis_countries_layer, qgs_project, qgs assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True legend_renderer.add_axes_texts = True legend_renderer.legend_rotated = True - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_with_arrows_texts_rotated.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_with_arrows_texts_rotated.png", "tests/images/image.png") -def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, prepare_painter): +def test_legend_ticks( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -204,9 +206,7 @@ def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_def assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() @@ -218,21 +218,23 @@ def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_def legend_renderer.texts_axis_x_ticks = bivariate_renderer.field_1_labels legend_renderer.texts_axis_y_ticks = bivariate_renderer.field_2_labels - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_with_values_ticks.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_with_values_ticks.png", "tests/images/image.png") -def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, prepare_painter): +def test_legend_all( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -246,9 +248,7 @@ def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_defau assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True @@ -258,10 +258,12 @@ def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_defau legend_renderer.texts_axis_x_ticks = bivariate_renderer.field_1_labels legend_renderer.texts_axis_y_ticks = bivariate_renderer.field_2_labels - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -270,8 +272,9 @@ def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_defau assert_images_equal("tests/images/correct/legend_with_all.png", "tests/images/image.png") -def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, prepare_painter): +def test_legend_all_rotated( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -285,9 +288,7 @@ def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepa assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() @@ -299,21 +300,23 @@ def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepa legend_renderer.texts_axis_x_ticks = bivariate_renderer.field_1_labels legend_renderer.texts_axis_y_ticks = bivariate_renderer.field_2_labels - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_with_all_rotated.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_with_all_rotated.png", "tests/images/image.png") -def test_legend_with_spacer(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, prepare_painter): +def test_legend_with_spacer( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): assert qgis_countries_layer assert qgs_project @@ -327,19 +330,19 @@ def test_legend_with_spacer(qgis_countries_layer, qgs_project, qgs_layout, prepa assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_colors_separators = True legend_renderer.color_separator_width_percent = 5 - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -348,9 +351,9 @@ def test_legend_with_spacer(qgis_countries_layer, qgs_project, qgs_layout, prepa assert_images_equal("tests/images/correct/legend_with_spacer.png", "tests/images/image.png") -def test_legend_with_arrows_common_origin(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer, - prepare_painter): +def test_legend_with_arrows_common_origin( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): legend_size = 500 @@ -362,28 +365,28 @@ def test_legend_with_arrows_common_origin(qgis_countries_layer, qgs_project, qgs assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True legend_renderer.arrows_common_start_point = True - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_with_arrows_common_origin.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_with_arrows_common_origin.png", "tests/images/image.png") -def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer, - prepare_painter): +def test_legend_ticks_midpoints( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, prepare_painter +): legend_size = 500 @@ -395,9 +398,7 @@ def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() @@ -408,25 +409,29 @@ def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, legend_renderer.add_axes_ticks_texts = True legend_renderer.use_category_midpoints = True legend_renderer.texts_axis_x_ticks = BivariateRenderer.classes_to_legend_midpoints( - bivariate_renderer.field_1_classes) + bivariate_renderer.field_1_classes + ) legend_renderer.texts_axis_y_ticks = BivariateRenderer.classes_to_legend_midpoints( - bivariate_renderer.field_2_classes) + bivariate_renderer.field_2_classes + ) - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_with_values_ticks_midpoints.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_with_values_ticks_midpoints.png", "tests/images/image.png") -def test_legend_empty_squares(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_painter, prepare_bivariate_renderer): +def test_legend_empty_squares( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_painter, prepare_bivariate_renderer +): legend_size = 500 @@ -438,9 +443,7 @@ def test_legend_empty_squares(qgis_countries_layer, qgs_project, qgs_layout, assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() @@ -453,12 +456,15 @@ def test_legend_empty_squares(qgis_countries_layer, qgs_project, qgs_layout, for feature in qgis_countries_layer.getFeatures(): bivariate_renderer.symbolForFeature(feature, QgsRenderContext()) - legend_renderer.render_legend(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), bivariate_renderer) + legend_renderer.render_legend( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer, + ) painter.end() image.save("./tests/images/image.png", "PNG") - assert_images_equal("tests/images/correct/legend_replaced_missing_values.png", - "tests/images/image.png") + assert_images_equal("tests/images/correct/legend_replaced_missing_values.png", "tests/images/image.png") diff --git a/tests/tests_visual_result_generation/test_generate_correct_images.py b/tests/tests_visual_result_generation/test_generate_correct_images.py index 103512b..f332fec 100755 --- a/tests/tests_visual_result_generation/test_generate_correct_images.py +++ b/tests/tests_visual_result_generation/test_generate_correct_images.py @@ -1,14 +1,14 @@ import os -import pytest -from qgis.PyQt.QtGui import QPainter, QColor -from qgis.core import (QgsLayoutUtils, QgsRenderContext) +import pytest +from qgis.core import QgsLayoutUtils, QgsRenderContext +from qgis.PyQt.QtGui import QColor, QPainter -from BivariateRenderer.legendrenderer.legend_renderer import LegendRenderer -from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer from BivariateRenderer.colormixing.color_mixing_method import ColorMixingMethodDarken, ColorMixingMethodDirect from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink from BivariateRenderer.layoutitems.layout_item import BivariateRendererLayoutItem +from BivariateRenderer.legendrenderer.legend_renderer import LegendRenderer +from BivariateRenderer.renderer.bivariate_renderer import BivariateRenderer env_value = os.getenv("BIVARIATE_GENERATE") @@ -21,8 +21,9 @@ @skip_setting -def test_generate_just_legend(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_just_legend( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -34,14 +35,15 @@ def test_generate_just_legend(qgis_countries_layer, qgs_project, qgs_layout, assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -49,8 +51,9 @@ def test_generate_just_legend(qgis_countries_layer, qgs_project, qgs_layout, @skip_setting -def test_generate_legend_with_arrows(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_legend_with_arrows( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -62,15 +65,16 @@ def test_generate_legend_with_arrows(qgis_countries_layer, qgs_project, qgs_layo assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -78,9 +82,9 @@ def test_generate_legend_with_arrows(qgis_countries_layer, qgs_project, qgs_layo @skip_setting -def test_generate_legend_with_arrows_common_origin(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, - prepare_bivariate_renderer): +def test_generate_legend_with_arrows_common_origin( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -92,16 +96,17 @@ def test_generate_legend_with_arrows_common_origin(qgis_countries_layer, qgs_pro assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True legend_renderer.arrows_common_start_point = True - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -109,8 +114,9 @@ def test_generate_legend_with_arrows_common_origin(qgis_countries_layer, qgs_pro @skip_setting -def test_generate_legend_with_arrows_text(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_legend_with_arrows_text( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -122,16 +128,17 @@ def test_generate_legend_with_arrows_text(qgis_countries_layer, qgs_project, qgs assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True legend_renderer.add_axes_texts = True - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -139,9 +146,9 @@ def test_generate_legend_with_arrows_text(qgis_countries_layer, qgs_project, qgs @skip_setting -def test_generate_legend_with_arrows_text_rotated(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, - prepare_bivariate_renderer): +def test_generate_legend_with_arrows_text_rotated( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -153,17 +160,18 @@ def test_generate_legend_with_arrows_text_rotated(qgis_countries_layer, qgs_proj assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True legend_renderer.add_axes_texts = True legend_renderer.legend_rotated = True - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -171,8 +179,9 @@ def test_generate_legend_with_arrows_text_rotated(qgis_countries_layer, qgs_proj @skip_setting -def test_generate_legend_darken(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_legend_darken( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -184,15 +193,16 @@ def test_generate_legend_darken(qgis_countries_layer, qgs_project, qgs_layout, assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDarken() legend_renderer = LegendRenderer() - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -200,8 +210,9 @@ def test_generate_legend_darken(qgis_countries_layer, qgs_project, qgs_layout, @skip_setting -def test_generate_legend_direct_mixing(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_legend_direct_mixing( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -213,15 +224,16 @@ def test_generate_legend_direct_mixing(qgis_countries_layer, qgs_project, qgs_la assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() legend_renderer = LegendRenderer() - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -229,13 +241,19 @@ def test_generate_legend_direct_mixing(qgis_countries_layer, qgs_project, qgs_la @skip_setting -def test_generate_legend_in_layout(qgis_countries_layer, qgs_layout, qgs_project, layout_page_a4, - prepare_bivariate_renderer, layout_space, export_page_to_image): - - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid", - color_ramps=BivariateColorRampGreenPink()) +def test_generate_legend_in_layout( + qgis_countries_layer, + qgs_layout, + qgs_project, + layout_page_a4, + prepare_bivariate_renderer, + layout_space, + export_page_to_image, +): + + bivariate_renderer = prepare_bivariate_renderer( + qgis_countries_layer, field1="fid", field2="fid", color_ramp=BivariateColorRampGreenPink() + ) qgis_countries_layer.setRenderer(bivariate_renderer) @@ -248,13 +266,13 @@ def test_generate_legend_in_layout(qgis_countries_layer, qgs_layout, qgs_project qgs_layout.addItem(layout_item) - export_page_to_image(qgs_layout, layout_page_a4, - "./tests/images/correct/layout_item_legend.png") + export_page_to_image(qgs_layout, layout_page_a4, "./tests/images/correct/layout_item_legend.png") @skip_setting -def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer): +def test_legend_ticks( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -266,9 +284,7 @@ def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_def assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() @@ -280,10 +296,12 @@ def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_def legend_renderer.texts_axis_x_ticks = bivariate_renderer.field_1_labels legend_renderer.texts_axis_y_ticks = bivariate_renderer.field_2_labels - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -291,8 +309,7 @@ def test_legend_ticks(qgis_countries_layer, qgs_project, qgs_layout, prepare_def @skip_setting -def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer): +def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer): legend_size = 500 @@ -304,9 +321,7 @@ def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_defau assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_axes_arrows = True @@ -316,10 +331,12 @@ def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_defau legend_renderer.texts_axis_x_ticks = bivariate_renderer.field_1_labels legend_renderer.texts_axis_y_ticks = bivariate_renderer.field_2_labels - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -327,8 +344,9 @@ def test_legend_all(qgis_countries_layer, qgs_project, qgs_layout, prepare_defau @skip_setting -def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer): +def test_legend_all_rotated( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -340,9 +358,7 @@ def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepa assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() @@ -354,10 +370,12 @@ def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepa legend_renderer.texts_axis_x_ticks = bivariate_renderer.field_1_labels legend_renderer.texts_axis_y_ticks = bivariate_renderer.field_2_labels - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -365,13 +383,13 @@ def test_legend_all_rotated(qgis_countries_layer, qgs_project, qgs_layout, prepa @skip_setting -def test_layer_bivariate_render(nc_layer, qgs_project, qgs_layout, prepare_default_QImage, - prepare_bivariate_renderer, save_layout_for_layer): +def test_layer_bivariate_render( + nc_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer, save_layout_for_layer +): - bivariate_renderer = prepare_bivariate_renderer(nc_layer, - field1="AREA", - field2="PERIMETER", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + nc_layer, field1="AREA", field2="PERIMETER", color_ramp=BivariateColorRampGreenPink() + ) nc_layer.setRenderer(bivariate_renderer) @@ -381,8 +399,9 @@ def test_layer_bivariate_render(nc_layer, qgs_project, qgs_layout, prepare_defau @skip_setting -def test_generate_legend_white_spacer(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_legend_white_spacer( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -394,18 +413,19 @@ def test_generate_legend_white_spacer(qgis_countries_layer, qgs_project, qgs_lay assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() legend_renderer.add_colors_separators = True legend_renderer.color_separator_width_percent = 5 - legend_renderer.render(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -413,8 +433,9 @@ def test_generate_legend_white_spacer(qgis_countries_layer, qgs_project, qgs_lay @skip_setting -def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_legend_ticks_midpoints( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -426,9 +447,7 @@ def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") bivariate_renderer.color_mixing_method = ColorMixingMethodDirect() @@ -439,14 +458,18 @@ def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, legend_renderer.add_axes_ticks_texts = True legend_renderer.use_category_midpoints = True legend_renderer.texts_axis_x_ticks = BivariateRenderer.classes_to_legend_midpoints( - bivariate_renderer.field_1_classes) + bivariate_renderer.field_1_classes + ) legend_renderer.texts_axis_y_ticks = BivariateRenderer.classes_to_legend_midpoints( - bivariate_renderer.field_2_classes) + bivariate_renderer.field_2_classes + ) - legend_renderer.render(render_context, - image.width() / render_context.scaleFactor(), - image.width() / render_context.scaleFactor(), - bivariate_renderer.generate_legend_polygons()) + legend_renderer.render( + render_context, + image.width() / render_context.scaleFactor(), + image.width() / render_context.scaleFactor(), + bivariate_renderer.generate_legend_polygons(), + ) painter.end() @@ -454,8 +477,9 @@ def test_legend_ticks_midpoints(qgis_countries_layer, qgs_project, qgs_layout, @skip_setting -def test_generate_legend_empty_squares(qgis_countries_layer, qgs_project, qgs_layout, - prepare_default_QImage, prepare_bivariate_renderer): +def test_generate_legend_empty_squares( + qgis_countries_layer, qgs_project, qgs_layout, prepare_default_QImage, prepare_bivariate_renderer +): legend_size = 500 @@ -467,9 +491,7 @@ def test_generate_legend_empty_squares(qgis_countries_layer, qgs_project, qgs_la assert render_context - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid") + bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, field1="fid", field2="fid") legend_renderer = LegendRenderer() @@ -482,8 +504,12 @@ def test_generate_legend_empty_squares(qgis_countries_layer, qgs_project, qgs_la for feature in qgis_countries_layer.getFeatures(): bivariate_renderer.symbolForFeature(feature, QgsRenderContext()) - legend_renderer.render_legend(render_context, legend_size / render_context.scaleFactor(), - legend_size / render_context.scaleFactor(), bivariate_renderer) + legend_renderer.render_legend( + render_context, + legend_size / render_context.scaleFactor(), + legend_size / render_context.scaleFactor(), + bivariate_renderer, + ) painter.end() diff --git a/tests/tests_visual_result_generation/test_generate_widget_screeshots.py b/tests/tests_visual_result_generation/test_generate_widget_screeshots.py index 82ae4e1..b654715 100644 --- a/tests/tests_visual_result_generation/test_generate_widget_screeshots.py +++ b/tests/tests_visual_result_generation/test_generate_widget_screeshots.py @@ -1,6 +1,6 @@ import os -import pytest +import pytest from qgis.core import QgsVectorLayer from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink @@ -31,15 +31,15 @@ def test_generate_widget_renderer(nc_layer: QgsVectorLayer, prepare_bivariate_re @skip_setting -def test_generate_widget_layout_item(qgis_countries_layer: QgsVectorLayer, qgs_layout, qgis_parent, - qgs_project, prepare_bivariate_renderer): +def test_generate_widget_layout_item( + qgis_countries_layer: QgsVectorLayer, qgs_layout, qgis_parent, qgs_project, prepare_bivariate_renderer +): qgs_project.addMapLayer(qgis_countries_layer) - bivariate_renderer = prepare_bivariate_renderer(qgis_countries_layer, - field1="fid", - field2="fid", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + qgis_countries_layer, field1="fid", field2="fid", color_ramp=BivariateColorRampGreenPink() + ) qgis_countries_layer.setRenderer(bivariate_renderer) diff --git a/tests/tests_visual_result_generation/test_generate_xmls.py b/tests/tests_visual_result_generation/test_generate_xmls.py index e0e67c5..f961164 100644 --- a/tests/tests_visual_result_generation/test_generate_xmls.py +++ b/tests/tests_visual_result_generation/test_generate_xmls.py @@ -1,16 +1,14 @@ from qgis.core import QgsVectorLayer from BivariateRenderer.colorramps.bivariate_color_ramp import BivariateColorRampGreenPink - from tests import xml_string def test_generate_xml(nc_layer: QgsVectorLayer, prepare_bivariate_renderer): - bivariate_renderer = prepare_bivariate_renderer(nc_layer, - field1="AREA", - field2="PERIMETER", - color_ramps=BivariateColorRampGreenPink()) + bivariate_renderer = prepare_bivariate_renderer( + nc_layer, field1="AREA", field2="PERIMETER", color_ramp=BivariateColorRampGreenPink() + ) bivariate_renderer.generateCategories()