Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development #24

Merged
merged 28 commits into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/codestyle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Code Style for Plugin LoS Tools

on: push

jobs:

Codestyle-for-Plugin-LoS-Tools:

runs-on: ubuntu-latest

permissions:
contents: write

steps:

- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'

- name: Install Python packages
run: pip install black isort

- name: Black
run: black .

- name: Isort
run: isort .

- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: Black and isort formatting
36 changes: 19 additions & 17 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,29 @@
"/usr/share/qgis/python/plugins",
"/usr/share/qgis/python"
],
"svg.preview.background": "dark-transparent",
"python.testing.pytestArgs": [
"tests",
"--cov=los_tools",
"--cov-report=term-missing:skip-covered",
"-rP",
"-s"
],
"python.testing.pytestEnabled": true,
"[python]": {
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true,
},
"pylint.args": [
"--ignore=W293,W504",
"--disable=E0611",
"--max-line-length=160"
"--disable= redefined-outer-name,no-name-in-module,missing-function-docstring,missing-class-docstring,missing-module-docstring,invalid-name,too-many-arguments,attribute-defined-outside-init",
"--max-line-length=120"
],
"flake8.args": [
"--ignore=W293,W504",
"--max-line-length",
"160"
],
"mypy-type-checker.args": [
"--follow-imports=silent",
"--ignore-missing-imports",
"--show-column-numbers",
"--no-pretty",
"--no-strict-optional"
"120"
],
"isort.args": [
"--profile",
Expand All @@ -38,9 +45,4 @@
"--line-length",
"120"
],
"svg.preview.background": "dark-transparent",
"python.testing.pytestArgs": [
"tests"
],
"python.testing.pytestEnabled": true
}
14 changes: 0 additions & 14 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,6 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "2.0.0",
"tasks": [
{
"label": "Run Pytest tests",
"type": "shell",
"command": "pytest tests --cov=los_tools --cov-report=term-missing:skip-covered -rP -s",
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Show website",
"type": "shell",
Expand Down
2 changes: 1 addition & 1 deletion dev/load_markdown_table_to_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def extract_table(file: Path) -> dict:

previous_line_table = False

with open(file) as f:
with open(file, encoding="utf-8") as f:

for line in f.readlines():

Expand Down
25 changes: 10 additions & 15 deletions los_tools/classes/classes_los.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ def __parse_points(self, points: List[List[float]]) -> None:
target_distance = calculate_distance(first_point_x, first_point_y, self.target_x, self.target_y)
sampling_distance = calculate_distance(points[0][0], points[0][1], points[1][0], points[1][1])

for i in range(0, len(points)):
point_x = points[i][0]
point_y = points[i][1]
point_z = points[i][2]
for i, point in enumerate(points):
point_x = point[0]
point_y = point[1]
point_z = point[2]

distance = calculate_distance(first_point_x, first_point_y, point_x, point_y)

Expand Down Expand Up @@ -137,15 +137,10 @@ def __parse_points(self, points: List[List[float]]) -> None:

def __str__(self):
string = ""
for i in range(0, len(self.points)):
string += "{} - {} {} {} (prev. {}) - vis. {} hor. {} \n".format(
i,
self.points[i][self.DISTANCE],
self.points[i][self.Z],
self.points[i][self.VERTICAL_ANGLE],
self.previous_max_angle[i],
self.visible[i],
self.horizon[i],
for i, point in enumerate(self.points):
string += (
f"{i} - {point[self.DISTANCE]} {point[self.Z]} {point[self.VERTICAL_ANGLE]} "
f"(prev. {self.previous_max_angle[i]}) - vis. {self.visible[i]} hor. {self.horizon[i]} \n"
)
return string

Expand All @@ -171,8 +166,8 @@ def get_geom_at_index(self, index: int) -> QgsPoint:
def get_horizons(self) -> List[QgsPoint]:
points: List[QgsPoint] = []

for i in range(0, len(self.horizon)):
if self.horizon[i]:
for i, horizon in enumerate(self.horizon):
if horizon:
points.append(self.get_geom_at_index(i))

return points
Expand Down
81 changes: 17 additions & 64 deletions los_tools/gui/create_los_tool/create_los_tool.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
from functools import partial

import numpy as np
from qgis.core import Qgis, QgsGeometry, QgsPoint, QgsPointLocator, QgsPointXY, QgsVectorLayer, QgsVertexId, QgsWkbTypes
from qgis.gui import QgisInterface, QgsMapMouseEvent, QgsMapToolAdvancedDigitizing, QgsSnapIndicator
from qgis.core import Qgis, QgsGeometry, QgsPoint, QgsPointLocator, QgsPointXY, QgsVectorLayer, QgsVertexId
from qgis.gui import QgisInterface, QgsMapMouseEvent
from qgis.PyQt.QtCore import Qt, pyqtSignal
from qgis.PyQt.QtGui import QKeyEvent
from qgis.PyQt.QtWidgets import QAction, QWidget
from qgis.PyQt.QtGui import QAction

from los_tools.classes.list_raster import ListOfRasters
from los_tools.gui.create_los_tool.create_los_widget import LoSInputWidget
from los_tools.gui.create_los_tool.los_digitizing_tool_with_widget import LoSDigitizingToolWithWidget
from los_tools.gui.dialog_los_settings import LoSSettings
from los_tools.gui.dialog_raster_validations import RasterValidations
from los_tools.processing.tools.util_functions import get_max_decimal_numbers, round_all_values

from .create_los_widget import LoSNoTargetInputWidget
from .los_tasks import LoSExtractionTaskManager, PrepareLoSTask, PrepareLoSWithoutTargetTask


class CreateLoSMapTool(QgsMapToolAdvancedDigitizing):
class CreateLoSMapTool(LoSDigitizingToolWithWidget):
featuresAdded = pyqtSignal()

def __init__(
Expand All @@ -27,9 +27,7 @@ def __init__(
los_layer: QgsVectorLayer = None,
add_result_action: QAction = None,
) -> None:
super().__init__(iface.mapCanvas(), iface.cadDockWidget())
self._iface = iface
self._canvas = self._iface.mapCanvas()
super().__init__(iface)

self.task_manager = LoSExtractionTaskManager()

Expand All @@ -44,67 +42,35 @@ def __init__(

self._last_towards_point: QgsPointXY = None

self._snapper = self._canvas.snappingUtils()
self.snap_marker = QgsSnapIndicator(self._canvas)

self._los_rubber_band = self.createRubberBand(QgsWkbTypes.LineGeometry)

self._widget: QWidget = None
self._widget = LoSInputWidget()
self._widget.hide()

def set_los_layer(self, layer: QgsVectorLayer) -> None:
self._los_layer = layer

def create_widget(self):
self.delete_widget()

self._widget = LoSNoTargetInputWidget()
self._iface.addUserInputWidget(self._widget)
self._widget.setFocus(Qt.TabFocusReason)
super().create_widget()

self._widget.valuesChanged.connect(partial(self.draw_los, None))
self._widget.saveToLayerClicked.connect(self.add_los_to_layer)

def delete_widget(self):
if self._widget:
self._widget.releaseKeyboard()
self._widget.deleteLater()
self._widget = None

def activate(self) -> None:
super(CreateLoSMapTool, self).activate()
self.create_widget()
self.messageDiscarded.emit()
self._canvas = self._iface.mapCanvas()
self._snapper = self._canvas.snappingUtils()
if self._canvas.mapSettings().destinationCrs().isGeographic():
self.messageEmitted.emit(
"Tool only works if canvas is in projected CRS. Currently canvas is in geographic CRS.",
Qgis.Critical,
)
self.hide_widgets()
self.deactivate()
return
super().activate()

if not ListOfRasters.validate(self._raster_validation_dialog.list_of_selected_rasters):
self.messageEmitted.emit(
"Tool needs valid setup in `Raster Validatations` dialog.",
"Tool needs valid setup in `Raster Validations` dialog.",
Qgis.Critical,
)
self.deactivate()
return

def clean(self) -> None:
super().clean()
if self._widget:
self._widget.disableAddLos()
self.snap_marker.setVisible(False)
self._los_rubber_band.hide()
self._start_point = None

def deactivate(self) -> None:
self.clean()
self.delete_widget()
self._iface.mapCanvas().unsetMapTool(self)
super(CreateLoSMapTool, self).deactivate()

def canvasReleaseEvent(self, e: QgsMapMouseEvent) -> None:
if e.button() == Qt.RightButton:
self.clean()
Expand All @@ -130,24 +96,11 @@ def canvasMoveEvent(self, event: QgsMapMouseEvent) -> None:
if self._start_point is not None:
self.draw_los(self._snap_point)

def keyPressEvent(self, e: QKeyEvent) -> None:
if e.key() == Qt.Key_Escape:
self.deactivate()
self._iface.mapCanvas().unsetMapTool(self)
return super().keyPressEvent(e)

def draw_los(self, towards_point: QgsPointXY):
if towards_point is None:
towards_point = self._last_towards_point

canvas_crs = self._canvas.mapSettings().destinationCrs()

if canvas_crs.isGeographic():
self._iface.messageBar().pushMessage(
"LoS can be drawn only for projected CRS. Canvas is currently in geographic CRS.",
Qgis.Critical,
duration=5,
)
if not self.canvas_crs_is_projected():
return

if self._start_point and towards_point:
Expand Down Expand Up @@ -264,9 +217,9 @@ def task_finished(self) -> None:
if self.task_manager.all_los_tasks_finished():
self.set_result_action_active(True)

def task_finished_message(self, miliseconds: int) -> None:
def task_finished_message(self, milliseconds: int) -> None:
self._iface.messageBar().pushMessage(
"LoS Processing Finished. Lasted {} seconds.".format(miliseconds / 1000),
f"LoS Processing Finished. Lasted {milliseconds / 1000} seconds.",
Qgis.MessageLevel.Info,
2,
)
2 changes: 1 addition & 1 deletion los_tools/gui/create_los_tool/create_los_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from los_tools.gui.custom_classes import Distance, DistanceWidget


class LoSNoTargetInputWidget(QWidget):
class LoSInputWidget(QWidget):
valuesChanged = pyqtSignal()
saveToLayerClicked = pyqtSignal()

Expand Down
Loading