diff --git a/ORStools/gui/ORStoolsDialog.py b/ORStools/gui/ORStoolsDialog.py index 26816fd5..8d02c131 100644 --- a/ORStools/gui/ORStoolsDialog.py +++ b/ORStools/gui/ORStoolsDialog.py @@ -84,7 +84,7 @@ PROFILES, PREFERENCES, ) -from ORStools.utils import maptools, configmanager, transform, gui, exceptions +from ORStools.utils import maptools, configmanager, gui, exceptions from .ORStoolsDialogConfig import ORStoolsDialogConfigMain MAIN_WIDGET, _ = uic.loadUiType(gui.GuiUtils.get_ui_file_path("ORStoolsDialogUI.ui")) @@ -415,6 +415,9 @@ def __init__(self, iface: QgisInterface, parent=None) -> None: lambda: self.color_duplicate_items(self.routing_fromline_list) ) + self.last_crs = self.canvas.mapSettings().destinationCrs() + self.canvas.destinationCrsChanged.connect(self._on_crs_changed) + self.load_provider_combo_state() self.provider_combo.activated.connect(self.save_selected_provider_state) @@ -435,6 +438,7 @@ def _save_vertices_to_layer(self) -> None: self.routing_fromline_list.item(x).text() for x in range(self.routing_fromline_list.count()) ] + map_crs = self._iface.mapCanvas().mapSettings().destinationCrs() if len(items) > 0: timestamp = datetime.now().strftime("%Y-%m-%d_%H:%M:%S") @@ -450,6 +454,7 @@ def _save_vertices_to_layer(self) -> None: feature.setAttributes([idx]) point_layer.dataProvider().addFeature(feature) + point_layer.setCrs(map_crs) QgsProject.instance().addMapLayer(point_layer) self.canvas.refresh() @@ -530,11 +535,7 @@ def _on_linetool_init(self) -> None: def create_vertex(self, point, idx): """Adds an item to QgsListWidget and annotates the point in the map canvas""" - map_crs = self.canvas.mapSettings().destinationCrs() - - transformer = transform.transformToWGS(map_crs) - point_wgs = transformer.transform(point) - self.routing_fromline_list.addItem(f"Point {idx}: {point_wgs.x():.6f}, {point_wgs.y():.6f}") + self.routing_fromline_list.addItem(f"Point {idx}: {point.x():.6f}, {point.y():.6f}") crs = self.canvas.mapSettings().destinationCrs() annotation = self._linetool_annotate_point(point, idx, crs) @@ -549,17 +550,20 @@ def _reindex_list_items(self) -> None: ] self.routing_fromline_list.clear() self._clear_annotations() - crs = QgsCoordinateReferenceSystem(f"EPSG:{4326}") project_crs = self.canvas.mapSettings().destinationCrs() - for idx, x in enumerate(items): - coords = x.split(":")[1] - item = f"Point {idx}:{coords}" - x, y = (float(i) for i in coords.split(", ")) + for idx, origin in enumerate(items): + origin_coords = origin.split(":")[1] + x, y = (float(i) for i in origin_coords.split(", ")) point = QgsPointXY(x, y) - self.routing_fromline_list.addItem(item) - transform = QgsCoordinateTransform(crs, project_crs, QgsProject.instance()) + transform = QgsCoordinateTransform(self.last_crs, project_crs, QgsProject.instance()) + point = transform.transform(point) + + coords = f"{point.x():.6f}, {point.y():.6f}" + item = f"Point {idx}: {coords}" + self.routing_fromline_list.addItem(item) + annotation = self._linetool_annotate_point(point, idx) self.annotations.append(annotation) self.project.annotationManager().addAnnotation(annotation) @@ -606,3 +610,8 @@ def show(self): """Load the saved state when the window is shown""" super().show() self.load_provider_combo_state() + + def _on_crs_changed(self) -> None: + """Handle CRS change event.""" + self._reindex_list_items() + self.last_crs = self.canvas.mapSettings().destinationCrs() diff --git a/ORStools/gui/directions_gui.py b/ORStools/gui/directions_gui.py index bb5b440a..a307de0b 100644 --- a/ORStools/gui/directions_gui.py +++ b/ORStools/gui/directions_gui.py @@ -33,6 +33,8 @@ from ORStools.utils import transform +from qgis.core import QgsPointXY + def _get_avoid_polygons(layer): """ @@ -100,6 +102,9 @@ def get_request_line_feature(self): :returns: coordinate list of line :rtype: list """ + map_crs = self.dlg.canvas.mapSettings().destinationCrs() + transformer = transform.transformToWGS(map_crs) + coordinates = [] layers_list = self.dlg.routing_fromline_list for idx in range(layers_list.count()): @@ -108,7 +113,13 @@ def get_request_line_feature(self): coordinates.append([float(coord) for coord in coords.split(", ")]) - return [[round(x, 6), round(y, 6)] for x, y in coordinates] + transformed_coordinates = [] + for coord in coordinates: + point = QgsPointXY(coord[0], coord[1]) + transformed_point = transformer.transform(point) + transformed_coordinates.append([transformed_point.x(), transformed_point.y()]) + + return [[round(x, 6), round(y, 6)] for x, y in transformed_coordinates] def get_parameters(self): """ diff --git a/ORStools/utils/maptools.py b/ORStools/utils/maptools.py index 831fbf12..f21ed5a4 100644 --- a/ORStools/utils/maptools.py +++ b/ORStools/utils/maptools.py @@ -32,11 +32,8 @@ from qgis.gui import QgsMapToolEmitPoint, QgsRubberBand from qgis.core import ( - QgsProject, QgsPointXY, - QgsCoordinateReferenceSystem, Qgis, - QgsCoordinateTransform, QgsWkbTypes, QgsAnnotation, QgsMarkerSymbol, @@ -46,7 +43,7 @@ from qgis.PyQt.QtGui import QColor, QMouseEvent from ORStools import ROUTE_COLOR -from ORStools.utils import transform, router +from ORStools.utils import router from ORStools.utils.exceptions import ApiError @@ -188,17 +185,12 @@ def canvasReleaseEvent(self, event: QEvent) -> None: self.dlg.annotations.insert(self.move_i, annotation) self.dlg.project.annotationManager().addAnnotation(annotation) - transformer = transform.transformToWGS(crs) - point_wgs = transformer.transform(point) - items = [ self.dlg.routing_fromline_list.item(x).text() for x in range(self.dlg.routing_fromline_list.count()) ] backup = items.copy() - items[self.move_i] = ( - f"Point {self.move_i}: {point_wgs.x():.6f}, {point_wgs.y():.6f}" - ) + items[self.move_i] = f"Point {self.move_i}: {point.x():.6f}, {point.y():.6f}" self.dlg.routing_fromline_list.clear() for i, x in enumerate(items): @@ -291,9 +283,6 @@ def create_rubber_band(self) -> None: else: self.dlg._clear_annotations() else: - dest_crs = self.dlg.canvas.mapSettings().destinationCrs() - original_crs = QgsCoordinateReferenceSystem("EPSG:4326") - transform = QgsCoordinateTransform(original_crs, dest_crs, QgsProject.instance()) items = [ self.dlg.routing_fromline_list.item(x).text() for x in range(self.dlg.routing_fromline_list.count()) @@ -301,9 +290,8 @@ def create_rubber_band(self) -> None: split = [x.split(":")[1] for x in items] coords = [tuple(map(float, coord.split(", "))) for coord in split] points_xy = [QgsPointXY(x, y) for x, y in coords] - reprojected_point = [transform.transform(point) for point in points_xy] - for point in reprojected_point: - if point == reprojected_point[-1]: + for point in points_xy: + if point == points_xy[-1]: self.dlg.rubber_band.addPoint(point, True) else: self.dlg.rubber_band.addPoint(point, False) diff --git a/tests/test_gui.py b/tests/test_gui.py index 374122fc..06018420 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -69,7 +69,9 @@ def test_without_live_preview(self): self.assertTrue(dlg.isVisible()) # Check first item of list widget - self.assertEqual(dlg.routing_fromline_list.item(0).text(), "Point 0: -0.187575, 56.516620") + self.assertEqual( + dlg.routing_fromline_list.item(0).text(), "Point 0: -20880.750000, 7661955.000000" + ) # Check rubber band has only 2 vertices self.assertEqual(dlg.routing_fromline_list.count(), 2) @@ -114,7 +116,7 @@ def test_with_live_preview(self): dlg.line_tool.canvasReleaseEvent(self.map_release(10, 0, Qt.MouseButton.LeftButton)) self.assertEqual( - dlg.routing_fromline_list.item(0).text(), "Point 0: -123.384059, 48.448463" + dlg.routing_fromline_list.item(0).text(), "Point 0: -13735050.625000, 6181790.000000" ) # Check that the live preview rubber band has more than two vertices @@ -210,7 +212,7 @@ def test_drag_drop_with_live_preview(self): dlg.line_tool.canvasReleaseEvent(self.map_release(10, 5, Qt.MouseButton.LeftButton)) self.assertEqual(dlg.routing_fromline_list.count(), 4) self.assertEqual( - dlg.routing_fromline_list.item(3).text(), "Point 3: -123.375767, 48.445713" + dlg.routing_fromline_list.item(3).text(), "Point 3: -13734127.517857, 6181328.446429" ) # Press at previous position @@ -219,6 +221,17 @@ def test_drag_drop_with_live_preview(self): # Release somewhere else dlg.line_tool.canvasReleaseEvent(self.map_release(50, 10, Qt.MouseButton.LeftButton)) self.assertEqual(dlg.routing_fromline_list.count(), 4) + + self.assertEqual(dlg.routing_fromline_list.count(), 4) + + # Set project CRS to EPSG:4326 to force coordinate transformation + project_crs = QgsCoordinateReferenceSystem.fromEpsgId(4326) + self.assertEqual(dlg.last_crs.authid(), "EPSG:3857") + CANVAS.setDestinationCrs(project_crs) + self.assertEqual(dlg.canvas.mapSettings().destinationCrs().authid(), "EPSG:4326") + + self.assertEqual(dlg.routing_fromline_list.count(), 4) + # Check that the coordinates of the point at the same position in the list has changed self.assertEqual( dlg.routing_fromline_list.item(3).text(), "Point 3: -123.342597, 48.442962"