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 #26

Merged
merged 11 commits into from
Sep 18, 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
5 changes: 2 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
"svg.preview.background": "dark-transparent",
"python.testing.pytestArgs": [
"tests",
"--cov=los_tools",
"--cov-report=term-missing:skip-covered",
"-rP",
"-s"
"-s",
"--no-cov"
],
"python.testing.pytestEnabled": true,
"[python]": {
Expand Down
9 changes: 5 additions & 4 deletions los_tools/classes/list_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ def validate_crs(rasters: List[QgsMapLayer], crs: QgsCoordinateReferenceSystem =

for raster in rasters:
if not first_raster_crs == raster.crs():
msg = "All CRS for all rasters must be equal. " "Right now they are not."
msg = "All CRS for all rasters must be equal. Right now they are not."

return False, msg

if not raster.crs() == crs:
msg = "Provided crs template and raster layers crs must be equal. " "Right now they are not."
msg = "Provided crs template and raster layers crs must be equal. Right now they are not."

return False, msg

Expand All @@ -79,7 +79,8 @@ def validate_ordering(rasters: List[QgsMapLayer]) -> Tuple[bool, str]:
return (
False,
"Raster cell sizes must be unique to form complete ordering. "
"Rasters are order strictly by cell size, same cell size for multiple rasters does not allow strict ordering. "
"Rasters are order strictly by cell size, "
"same cell size for multiple rasters does not allow strict ordering. "
f"The values [{','.join([str(x) for x in values])}] are not unique.",
)

Expand Down Expand Up @@ -149,7 +150,7 @@ def rasters_dp(self) -> List[QgsRasterDataProvider]:
return [x.dataProvider() for x in self.rasters]

def maximal_diagonal_size(self) -> float:
extent: QgsRectangle = None
extent: Optional[QgsRectangle] = None

for raster in self.rasters:
if extent is None:
Expand Down
1 change: 0 additions & 1 deletion los_tools/classes/sampling_distance_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ def next_distance(self, current_distance: float) -> float:
return current_distance + value_to_add

def build_line(self, origin_point: QgsPoint, direction_point: QgsPoint) -> QgsLineString:
line: Union[QgsLineString, QgsGeometry]

lines = []

Expand Down
5 changes: 5 additions & 0 deletions los_tools/gui/create_los_tool/create_los_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def set_los_layer(self, layer: QgsVectorLayer) -> None:
self._los_layer = layer

def create_widget(self):
if not self._widget:
self._widget = LoSInputWidget()

super().create_widget()

self._widget.valuesChanged.connect(partial(self.draw_los, None))
Expand All @@ -72,6 +75,8 @@ def clean(self) -> None:
self._start_point = None

def canvasReleaseEvent(self, e: QgsMapMouseEvent) -> None:
if e.button() == Qt.RightButton and self._start_point is None and self._los_rubber_band.size() == 0:
self.deactivate()
if e.button() == Qt.RightButton:
self.clean()
elif e.button() == Qt.LeftButton:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def delete_widget(self):

def clean(self) -> None:
self.snap_marker.setVisible(False)
self._los_rubber_band.hide()
self._los_rubber_band.reset()

def keyPressEvent(self, e: QKeyEvent) -> None:
if e.key() == Qt.Key_Escape or e.key() == Qt.Key_Backspace:
Expand Down
88 changes: 48 additions & 40 deletions los_tools/gui/dialog_raster_validations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Dict, List
from typing import List

from qgis.core import QgsPointXY, QgsProject, QgsRasterLayer, QgsUnitTypes
from qgis.gui import QgsMapToolEmitPoint
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import (
QDialog,
Expand All @@ -16,7 +17,6 @@
)

from ..classes.list_raster import ListOfRasters
from .dialog_tool_set_camera import PointCaptureMapTool


class RasterValidations(QDialog):
Expand All @@ -29,12 +29,9 @@ def __init__(self, iface=None) -> None:
self._point = None
self._point_crs = None

self.map_tool = PointCaptureMapTool(self._canvas)
self.map_tool = QgsMapToolEmitPoint(self._canvas)
self.map_tool.canvasClicked.connect(self.update_test_point)

self.rasters: List[QgsRasterLayer] = []
self.rasters_selected: Dict[str, bool] = {}

self.init_gui()

def init_gui(self):
Expand All @@ -61,7 +58,6 @@ def init_gui(self):

self._rasters_view.itemChanged.connect(self.validate)
self._rasters_view.itemChanged.connect(self.test_interpolated_value_at_point)
self._rasters_view.itemChanged.connect(self.update_selected_rasters)

self.select_point = QPushButton()
self.select_point.setText("Choose sample point on the map")
Expand Down Expand Up @@ -90,18 +86,36 @@ def init_gui(self):
layout.addRow(group_box)

def _populate_raster_view(self) -> None:
self._rasters_view.clear()

items_to_remove = []
for i in range(self._rasters_view.topLevelItemCount()):
item = self._rasters_view.topLevelItem(i)
raster_id: str = item.data(0, Qt.UserRole)
layer = QgsProject.instance().mapLayer(raster_id)
if layer is None:
items_to_remove.append(item)

for item in items_to_remove:
self._rasters_view.invisibleRootItem().removeChild(item)

for raster in self.rasters:
item_name = raster.name()

if raster.providerType() == "wms":
break

if self._rasters_view.findItems(item_name, Qt.MatchFlag.MatchExactly):
continue

layer_tree_root = QgsProject.instance().layerTreeRoot()
tree_layer = layer_tree_root.findLayer(raster.id())

item = QTreeWidgetItem()
item.setText(0, raster.name())
item.setData(0, Qt.UserRole, raster)
if self.rasters_selected.get(raster.id()) is not None:
if self.rasters_selected.get(raster.id()):
item.setCheckState(0, Qt.CheckState.Checked)
else:
item.setCheckState(0, Qt.CheckState.Unchecked)
item.setData(0, Qt.UserRole, raster.id())

if tree_layer.isVisible():
item.setCheckState(0, Qt.CheckState.Checked)
else:
item.setCheckState(0, Qt.CheckState.Unchecked)

Expand All @@ -110,57 +124,53 @@ def _populate_raster_view(self) -> None:

item.setText(
1,
"{} {} - {} {}".format(
round(raster.extent().width() / raster.width(), 3),
distance_unit,
round(raster.extent().height() / raster.height(), 3),
distance_unit,
),
f"{round(raster.extent().width() / raster.width(), 3)} {distance_unit}"
" - "
f"{round(raster.extent().height() / raster.height(), 3)} {distance_unit}",
)
item.setData(1, Qt.UserRole, raster.extent().width() / raster.width())

self._rasters_view.addTopLevelItem(item)

def _raster_layers(self) -> List[QgsRasterLayer]:
@property
def rasters(self) -> List[QgsRasterLayer]:
project = QgsProject.instance()
rasters_tmp = []
for layerId in self._raster_layers_ids():
for layerId in self._layers_ids():
layer = project.mapLayer(layerId)
if isinstance(layer, QgsRasterLayer):
rasters_tmp.append(layer)

return rasters_tmp

def _raster_layers_ids(self) -> List[str]:
def _layers_ids(self) -> List[str]:
project = QgsProject.instance()
layers = [x for x in project.mapLayers(True)]
return layers

def _data_reset(self) -> None:
def _default_tools(self) -> None:
self._prev_map_tool = self._canvas.mapTool()
self._prev_cursor = self._canvas.cursor()

rasters_tmp = self._raster_layers()

if self.rasters != rasters_tmp:
self.rasters = rasters_tmp
self._populate_raster_view()

def open(self) -> None:
self._data_reset()
self._default_tools()
self._populate_raster_view()
self.validate()
super().open()

def exec(self) -> int:
self._data_reset()
self._default_tools()
self._populate_raster_view()
self.validate()
return super().exec()

def select_sample_point(self) -> None:
self._canvas.setMapTool(self.map_tool)
self.close()
self.hide()

def update_test_point(self, point):
self.restore_canvas_tools()
self.open()
self.show()
canvas_crs = self._canvas.mapSettings().destinationCrs()
text_point = "{:.3f};{:.3f}[{}]".format(point.x(), point.y(), canvas_crs.authid())
self.point_coordinate.setText(text_point)
Expand All @@ -172,11 +182,6 @@ def restore_canvas_tools(self) -> None:
self._canvas.setMapTool(self._prev_map_tool)
self._canvas.setCursor(self._prev_cursor)

def update_selected_rasters(self, item: QTreeWidgetItem, column: int) -> None:
raster: QgsRasterLayer = item.data(0, Qt.UserRole)
self.rasters_selected[raster.id()] = item.checkState(0) == Qt.CheckState.Checked
self.select_point.setEnabled(not self.listOfRasters.is_empty())

@property
def listOfRasters(self) -> ListOfRasters:
try:
Expand Down Expand Up @@ -206,7 +211,8 @@ def list_of_selected_rasters(self) -> List[QgsRasterLayer]:
for i in range(self._rasters_view.topLevelItemCount()):
item = self._rasters_view.topLevelItem(i)
if item.checkState(0) == Qt.CheckState.Checked:
rasters_selected.append(item.data(0, Qt.UserRole))
layer: QgsRasterLayer = QgsProject.instance().mapLayer(item.data(0, Qt.UserRole))
rasters_selected.append(layer)

return rasters_selected

Expand Down Expand Up @@ -239,3 +245,5 @@ def validate(self):
self.text.setText("\n\n".join(all_msgs))
else:
self.text.setText("Selection is valid and can be used in LoS creation tools.")

self.select_point.setEnabled(not self.listOfRasters.is_empty())
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ def __init__(self, iface: QgisInterface) -> None:
self._widget.hide()

def create_widget(self):
if not self._widget:
self._widget = LoSNoTargetInputWidget()
super().create_widget()

self._widget.valuesChanged.connect(self.draw_los)

def canvasReleaseEvent(self, e: QgsMapMouseEvent) -> None:
if e.button() == Qt.RightButton and self._los_rubber_band.size() == 0:
self.deactivate()
if e.button() == Qt.RightButton:
self.clean()
if e.button() == Qt.LeftButton:
self.draw_los()

Expand Down
6 changes: 4 additions & 2 deletions los_tools/metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
name=LoS Tools
qgisMinimumVersion=3.30
description=This plugin creates and analyzes lines-of-sight (LoS) and also provides supporting tools.
version=1.1.1
version=1.1.2
author=Jan Caha
[email protected]

Expand All @@ -20,7 +20,9 @@ repository=https://github.com/JanCaha/qgis_los_tools

hasProcessingProvider=yes
# Uncomment the following line and add your changelog:
changelog=1.1.1
changelog=1.1.2
- fix issue with interactive tools not opening properly after closing
<p>1.1.1
- simplify inner working of GUI tools
- fix `Set Camera` GUI tool
<p>1.1
Expand Down
Binary file modified tests/_data/project.qgz
Binary file not shown.