diff --git a/ui/main_dialog.py b/ui/main_dialog.py index 7e37fb8..ac8fb3a 100644 --- a/ui/main_dialog.py +++ b/ui/main_dialog.py @@ -22,7 +22,7 @@ from translator.vector.label import generate_label_vector from ui.progress_dialog import ProgressDialog from translator.thread import ProcessingThread -from utils import write_json, get_tempdir +from utils import write_json, get_tempdir, get_scale class MainDialog(QDialog): @@ -50,6 +50,11 @@ def init_ui(self): ] ) + # calculate export scale and show to ui + self._update_ui_scale() + # update export scale shown in ui when change map extent + iface.mapCanvas().extentsChanged.connect(self._update_ui_scale) + # close dialog when project cleared to avoid crash: Issue #55 QgsProject.instance().cleared.connect(self.close) @@ -138,7 +143,7 @@ def _run(self): self.ui.mExtentGroupBox.outputExtent().xMaximum(), self.ui.mExtentGroupBox.outputExtent().yMaximum(), ], - "scale": iface.mapCanvas().scale(), + "scale": get_scale(), "layers": layers_processed_successfully, # layer_0,2,5.. "assets_path": "assets", } @@ -272,3 +277,6 @@ def _process_node_recursive(self, node, parent_node): if child_type == "group": self._process_node_recursive(child, item) + + def _update_ui_scale(self): + self.ui.label_scale_value.setText(str(get_scale())) diff --git a/ui/main_dialog.ui b/ui/main_dialog.ui index 411453b..51e7274 100644 --- a/ui/main_dialog.ui +++ b/ui/main_dialog.ui @@ -46,6 +46,31 @@ + + + + + + 出力縮尺 + + + + + + + 1: + + + + + + + 1 + + + + + diff --git a/utils.py b/utils.py index 9da5903..ee9f7aa 100644 --- a/utils.py +++ b/utils.py @@ -3,7 +3,16 @@ from typing import Union -from qgis.core import QgsRenderContext, QgsUnitTypes +from qgis.core import ( + QgsRenderContext, + QgsUnitTypes, + QgsProject, + QgsRectangle, + QgsPoint, + QgsScaleCalculator, + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, +) from qgis.utils import iface @@ -52,3 +61,48 @@ def get_tempdir(output_dir: str) -> str: os.mkdir(os.path.join(output_dir, temp_dir_path)) return os.path.join(output_dir, temp_dir_path) + + +def get_scale() -> float: + """get scale from map canvas. + For web mercator projection (EPSG:3857) case, + calculate scale with map extent correction according to scale factor""" + + if QgsProject.instance().crs().authid() == "EPSG:3857": + canvas = iface.mapCanvas() + # get map canvas center coordinates in geographic + transform = QgsCoordinateTransform( + canvas.mapSettings().destinationCrs(), + QgsCoordinateReferenceSystem("EPSG:4326"), + QgsProject.instance(), + ) + center_geographic = transform.transform(canvas.center()) + center_point = QgsPoint(center_geographic.x(), center_geographic.y()) + + # calculate scale_factor from center_point + # https://en.wikipedia.org/wiki/Mercator_projection#Scale_factor + scale_factor_x = ( + QgsProject.instance().crs().factors(center_point).parallelScale() + ) + scale_factor_y = ( + QgsProject.instance().crs().factors(center_point).meridionalScale() + ) + + # determine extension corrected with scale factor + extent = canvas.extent() + delta_x = (extent.width() * scale_factor_x) - extent.width() + delta_y = (extent.height() * scale_factor_y) - extent.height() + corrected_extent = QgsRectangle( + extent.xMinimum() - delta_x / 2, + extent.yMinimum() - delta_y / 2, + extent.xMaximum() + delta_x / 2, + extent.yMaximum() + delta_y / 2, + ) + + # calculate scale based on corrected map extent + scale_calculator = QgsScaleCalculator( + canvas.mapSettings().outputDpi(), canvas.mapUnits() + ) + return scale_calculator.calculate(corrected_extent, canvas.size().width()) + else: + return iface.mapCanvas().scale()