From 85ebed2a2ec1f4de7274a316696e56f66004d6ff Mon Sep 17 00:00:00 2001
From: Till Frankenbach <81414045+merydian@users.noreply.github.com>
Date: Wed, 15 May 2024 10:38:18 -0400
Subject: [PATCH] feat: improve type hinting (#240)
---
CHANGELOG.md | 1 +
ORStools/ORStoolsPlugin.py | 7 ++-
ORStools/common/client.py | 16 ++++--
ORStools/common/directions_core.py | 35 +++++++-----
ORStools/common/isochrones_core.py | 22 ++++++--
ORStools/common/networkaccessmanager.py | 22 ++++----
ORStools/gui/ORStoolsDialog.py | 55 ++++++++++++-------
ORStools/gui/ORStoolsDialogConfig.py | 16 +++---
ORStools/proc/base_processing_algorithm.py | 12 ++--
ORStools/proc/directions_lines_proc.py | 30 ++++++----
ORStools/proc/directions_points_layer_proc.py | 29 ++++++----
.../proc/directions_points_layers_proc.py | 45 ++++++++++-----
ORStools/proc/isochrones_layer_proc.py | 32 +++++++----
ORStools/proc/isochrones_point_proc.py | 30 ++++++----
ORStools/proc/matrix_proc.py | 22 +++++---
ORStools/proc/provider.py | 12 ++--
ORStools/utils/configmanager.py | 6 +-
ORStools/utils/convert.py | 2 +-
ORStools/utils/logger.py | 2 +-
ORStools/utils/maptools.py | 13 +++--
ORStools/utils/transform.py | 2 +-
21 files changed, 251 insertions(+), 160 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd4fe703..2253c1dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -47,6 +47,7 @@ RELEASING:
- Vertices on canvas not depicted fully with n having more than one digit in length ([#235](https://github.com/GIScience/orstools-qgis-plugin/issues/235))
- Replace qt QSettings with QgsSettings for centralized configuration management ([#239](https://github.com/GIScience/orstools-qgis-plugin/issues/239))
- Fix: Point Annotations stay after saving project and not deleting them manually([#229](https://github.com/GIScience/orstools-qgis-plugin/issues/229))
+- Improved type hints
### Added
- Add support for decimal ranges with isochrones([#237](https://github.com/GIScience/orstools-qgis-plugin/issues/237))
diff --git a/ORStools/ORStoolsPlugin.py b/ORStools/ORStoolsPlugin.py
index b6cc99f6..e675f834 100644
--- a/ORStools/ORStoolsPlugin.py
+++ b/ORStools/ORStoolsPlugin.py
@@ -27,6 +27,7 @@
***************************************************************************/
"""
+from qgis.gui import QgisInterface
from qgis.core import QgsApplication, QgsSettings
from PyQt5.QtCore import QTranslator, qVersion, QCoreApplication
import os.path
@@ -40,7 +41,7 @@ class ORStools:
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
- def __init__(self, iface):
+ def __init__(self, iface: QgisInterface) -> None:
"""Constructor.
:param iface: An interface instance that will be passed to this class
@@ -65,13 +66,13 @@ def __init__(self, iface):
if qVersion() > "4.3.3":
QCoreApplication.installTranslator(self.translator)
- def initGui(self):
+ def initGui(self) -> None:
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
QgsApplication.processingRegistry().addProvider(self.provider)
self.dialog.initGui()
- def unload(self):
+ def unload(self) -> None:
"""remove menu entry and toolbar icons"""
QgsApplication.processingRegistry().removeProvider(self.provider)
self.dialog.unload()
diff --git a/ORStools/common/client.py b/ORStools/common/client.py
index b3115bc6..e4ff6821 100644
--- a/ORStools/common/client.py
+++ b/ORStools/common/client.py
@@ -31,6 +31,7 @@
import random
import time
from datetime import datetime, timedelta
+from typing import Union, Dict, List, Optional
from urllib.parse import urlencode
from PyQt5.QtCore import QObject, pyqtSignal
@@ -48,7 +49,7 @@
class Client(QObject):
"""Performs requests to the ORS API services."""
- def __init__(self, provider=None, agent=None):
+ def __init__(self, provider: Optional[dict] = None, agent: Optional[str] = None) -> None:
"""
:param provider: A openrouteservice provider from config.yml
:type provider: dict
@@ -87,7 +88,14 @@ def __init__(self, provider=None, agent=None):
overQueryLimit = pyqtSignal()
- def request(self, url, params, first_request_time=None, retry_counter=0, post_json=None):
+ def request(
+ self,
+ url: str,
+ params: dict,
+ first_request_time: Optional[datetime.time] = None,
+ retry_counter: int = 0,
+ post_json: Optional[dict] = None,
+ ):
"""Performs HTTP GET/POST with credentials, returning the body as
JSON.
@@ -194,7 +202,7 @@ def request(self, url, params, first_request_time=None, retry_counter=0, post_js
return json.loads(content.decode("utf-8"))
- def _check_status(self):
+ def _check_status(self) -> None:
"""
Casts JSON response to dict
@@ -231,7 +239,7 @@ def _check_status(self):
elif status_code != 200:
raise exceptions.GenericServerError(str(status_code), message)
- def _generate_auth_url(self, path, params):
+ def _generate_auth_url(self, path: str, params: Union[Dict, List]) -> str:
"""Returns the path and query string portion of the request URL, first
adding any necessary parameters.
diff --git a/ORStools/common/directions_core.py b/ORStools/common/directions_core.py
index e7496ac3..0f523045 100644
--- a/ORStools/common/directions_core.py
+++ b/ORStools/common/directions_core.py
@@ -29,14 +29,14 @@
from itertools import product
from qgis.core import QgsPoint, QgsPointXY, QgsGeometry, QgsFeature, QgsFields, QgsField
-from typing import List
+from typing import List, Generator, Tuple, Any, Optional
from PyQt5.QtCore import QVariant
from ORStools.utils import convert
-def get_request_point_features(route_dict, row_by_row):
+def get_request_point_features(route_dict: dict, row_by_row: str) -> Generator[List, Tuple, None]:
"""
Processes input point features depending on the layer to layer relation in directions settings
@@ -75,12 +75,12 @@ def get_request_point_features(route_dict, row_by_row):
def get_fields(
- from_type=QVariant.String,
- to_type=QVariant.String,
- from_name="FROM_ID",
- to_name="TO_ID",
- line=False,
-):
+ from_type: QVariant.Type = QVariant.String,
+ to_type: QVariant.Type = QVariant.String,
+ from_name: str = "FROM_ID",
+ to_name: str = "TO_ID",
+ line: bool = False,
+) -> QgsFields:
"""
Builds output fields for directions response layer.
@@ -117,8 +117,13 @@ def get_fields(
def get_output_feature_directions(
- response, profile, preference, options=None, from_value=None, to_value=None
-):
+ response: dict,
+ profile: str,
+ preference: str,
+ options: Optional[str] = None,
+ from_value: Any = None,
+ to_value: Any = None,
+) -> QgsFeature:
"""
Build output feature based on response attributes for directions endpoint.
@@ -165,7 +170,9 @@ def get_output_feature_directions(
return feat
-def get_output_features_optimization(response, profile, from_value=None):
+def get_output_features_optimization(
+ response: dict, profile: str, from_value: Any = None
+) -> QgsFeature:
"""
Build output feature based on response attributes for optimization endpoint.
@@ -205,9 +212,9 @@ def get_output_features_optimization(response, profile, from_value=None):
def build_default_parameters(
preference: str,
- point_list: List[QgsPointXY] = None,
- coordinates: list = None,
- options: dict = None,
+ point_list: Optional[List[QgsPointXY]] = None,
+ coordinates: Optional[list] = None,
+ options: Optional[dict] = None,
) -> dict:
"""
Build default parameters for directions endpoint. Either uses a list of QgsPointXY to create the coordinates
diff --git a/ORStools/common/isochrones_core.py b/ORStools/common/isochrones_core.py
index 39c90150..218f966c 100644
--- a/ORStools/common/isochrones_core.py
+++ b/ORStools/common/isochrones_core.py
@@ -27,6 +27,9 @@
***************************************************************************/
"""
+from typing import Any, Generator
+
+from qgis._core import QgsMapLayer
from qgis.core import (
QgsPointXY,
QgsFeature,
@@ -49,7 +52,7 @@
class Isochrones:
"""convenience class to build isochrones"""
- def __init__(self):
+ def __init__(self) -> None:
# Will all be set in self.set_parameters(), bcs Processing Algo has to initialize this class before it
# knows about its own parameters
self.profile = None
@@ -60,8 +63,13 @@ def __init__(self):
self.field_dimension_name = None
def set_parameters(
- self, profile, dimension, factor, id_field_type=QVariant.String, id_field_name="ID"
- ):
+ self,
+ profile: str,
+ dimension: str,
+ factor: int,
+ id_field_type: QVariant.String = QVariant.String,
+ id_field_name: str = "ID",
+ ) -> None:
"""
Sets all parameters defined in __init__, because processing algorithm calls this class when it doesn't know
its parameters yet.
@@ -89,7 +97,7 @@ def set_parameters(
self.field_dimension_name = "AA_MINS" if self.dimension == "time" else "AA_METERS"
- def get_fields(self):
+ def get_fields(self) -> QgsFields:
"""
Set all fields for output isochrone layer.
@@ -106,7 +114,9 @@ def get_fields(self):
return fields
- def get_features(self, response, id_field_value):
+ def get_features(
+ self, response: dict, id_field_value: Any
+ ) -> Generator[QgsFeature, None, None]:
"""
Generator to return output isochrone features from response.
@@ -158,7 +168,7 @@ def get_features(self, response, id_field_value):
#
# return dissolved
- def stylePoly(self, layer):
+ def stylePoly(self, layer: QgsMapLayer) -> None:
"""
Style isochrone polygon layer.
diff --git a/ORStools/common/networkaccessmanager.py b/ORStools/common/networkaccessmanager.py
index c2dd8132..a1cbc62b 100644
--- a/ORStools/common/networkaccessmanager.py
+++ b/ORStools/common/networkaccessmanager.py
@@ -153,7 +153,7 @@ def __init__(
exception_class=None,
debug=True,
timeout=60,
- ):
+ ) -> None:
self.disable_ssl_certificate_validation = disable_ssl_certificate_validation
self.authid = authid
self.reply = None
@@ -175,17 +175,19 @@ def __init__(
)
self.timeout = timeout
- def msg_log(self, msg):
+ def msg_log(self, msg: str) -> None:
if self.debug:
QgsMessageLog.logMessage(msg, "NetworkAccessManager")
- def httpResult(self):
+ def httpResult(self) -> None:
return self.http_call_result
- def auth_manager(self):
+ def auth_manager(self) -> None:
return QgsApplication.authManager()
- def request(self, url, method="GET", body=None, headers=None, blocking=True):
+ def request(
+ self, url: str, method: str = "GET", body=None, headers=None, blocking: bool = True
+ ):
"""
Make a network request by calling QgsNetworkAccessManager.
redirections argument is ignored and is here only for httplib2 compatibility.
@@ -279,19 +281,19 @@ def request(self, url, method="GET", body=None, headers=None, blocking=True):
return self.http_call_result, self.http_call_result.content
- def downloadProgress(self, bytesReceived, bytesTotal):
+ def downloadProgress(self, bytesReceived, bytesTotal) -> None:
"""Keep track of the download progress"""
# self.msg_log("downloadProgress %s of %s ..." % (bytesReceived, bytesTotal))
pass
# noinspection PyUnusedLocal
- def requestTimedOut(self, reply):
+ def requestTimedOut(self, reply) -> None:
"""Trap the timeout. In Async mode requestTimedOut is called after replyFinished"""
# adapt http_call_result basing on receiving qgs timer timout signal
self.exception_class = RequestsExceptionTimeout
self.http_call_result.exception = RequestsExceptionTimeout("Timeout error")
- def replyFinished(self):
+ def replyFinished(self) -> None:
err = self.reply.error()
httpStatus = self.reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
httpStatusMessage = self.reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute)
@@ -401,7 +403,7 @@ def replyFinished(self):
else:
self.msg_log("Reply was already deleted ...")
- def sslErrors(self, ssl_errors):
+ def sslErrors(self, ssl_errors) -> None:
"""
Handle SSL errors, logging them if debug is on and ignoring them
if disable_ssl_certificate_validation is set.
@@ -412,7 +414,7 @@ def sslErrors(self, ssl_errors):
if self.disable_ssl_certificate_validation:
self.reply.ignoreSslErrors()
- def abort(self):
+ def abort(self) -> None:
"""
Handle request to cancel HTTP call
"""
diff --git a/ORStools/gui/ORStoolsDialog.py b/ORStools/gui/ORStoolsDialog.py
index cce7e325..34ed9a5b 100644
--- a/ORStools/gui/ORStoolsDialog.py
+++ b/ORStools/gui/ORStoolsDialog.py
@@ -29,10 +29,13 @@
import json
import os
+from typing import Optional
+
import processing
import webbrowser
-from qgis._core import Qgis
+from qgis._core import Qgis, QgsAnnotation
+from qgis._gui import QgisInterface
from qgis.core import (
QgsProject,
QgsVectorLayer,
@@ -48,7 +51,15 @@
from PyQt5.QtCore import QSizeF, QPointF, QCoreApplication
from PyQt5.QtGui import QIcon, QTextDocument
-from PyQt5.QtWidgets import QAction, QDialog, QApplication, QMenu, QMessageBox, QDialogButtonBox
+from PyQt5.QtWidgets import (
+ QAction,
+ QDialog,
+ QApplication,
+ QMenu,
+ QMessageBox,
+ QDialogButtonBox,
+ QWidget,
+)
from ORStools import (
RESOURCE_PREFIX,
@@ -83,12 +94,12 @@ def on_config_click(parent):
config_dlg.exec_()
-def on_help_click():
+def on_help_click() -> None:
"""Open help URL from button/menu entry."""
webbrowser.open(__help__)
-def on_about_click(parent):
+def on_about_click(parent: QWidget) -> None:
"""Slot for click event of About button/menu entry."""
info = QCoreApplication.translate(
@@ -116,7 +127,7 @@ def on_about_click(parent):
class ORStoolsDialogMain:
"""Defines all mandatory QGIS things about dialog."""
- def __init__(self, iface):
+ def __init__(self, iface: QgisInterface) -> None:
"""
:param iface: the current QGIS interface
@@ -132,10 +143,10 @@ def __init__(self, iface):
self.actions = None
# noinspection PyUnresolvedReferences
- def initGui(self):
+ def initGui(self) -> None:
"""Called when plugin is activated (on QGIS startup or when activated in Plugin Manager)."""
- def create_icon(f):
+ def create_icon(f: str) -> QIcon:
"""
internal function to create action icons
@@ -187,7 +198,7 @@ def create_icon(f):
# Add keyboard shortcut
self.iface.registerMainWindowAction(self.actions[0], "Ctrl+R")
- def unload(self):
+ def unload(self) -> None:
"""Called when QGIS closes or plugin is deactivated in Plugin Manager"""
self.iface.webMenu().removeAction(self.menu.menuAction())
@@ -214,7 +225,7 @@ def unload(self):
# text.append(os.environ[var])
# return '/'.join(text)
- def _init_gui_control(self):
+ def _init_gui_control(self) -> None:
"""Slot for main plugin button. Initializes the GUI and shows it."""
# Only populate GUI if it's the first start of the plugin within the QGIS session
@@ -237,7 +248,7 @@ def _init_gui_control(self):
self.dlg.show()
- def run_gui_control(self):
+ def run_gui_control(self) -> None:
"""Slot function for OK button of main dialog."""
layer_out = QgsVectorLayer("LineString?crs=EPSG:4326", "Route_ORS", "memory")
@@ -404,14 +415,14 @@ def run_gui_control(self):
clnt_msg += f'{clnt.url}
Parameters:
{json.dumps(params, indent=2)}'
self.dlg.debug_text.setHtml(clnt_msg)
- def tr(self, string):
+ def tr(self, string: str) -> str:
return QCoreApplication.translate(str(self.__class__.__name__), string)
class ORStoolsDialog(QDialog, Ui_ORStoolsDialogBase):
"""Define the custom behaviour of Dialog"""
- def __init__(self, iface, parent=None):
+ def __init__(self, iface: QgisInterface, parent=None) -> None:
"""
:param iface: QGIS interface
:type iface: QgisInterface
@@ -481,7 +492,7 @@ def __init__(self, iface, parent=None):
self.annotation_canvas = self._iface.mapCanvas()
- def _save_vertices_to_layer(self):
+ def _save_vertices_to_layer(self) -> None:
"""Saves the vertices list to a temp layer"""
items = [
self.routing_fromline_list.item(x).text()
@@ -508,7 +519,7 @@ def _save_vertices_to_layer(self):
"Success", "Vertices saved to layer.", level=Qgis.Success
)
- def _on_prov_refresh_click(self):
+ def _on_prov_refresh_click(self) -> None:
"""Populates provider dropdown with fresh list from config.yml"""
providers = configmanager.read_config()["providers"]
@@ -516,7 +527,7 @@ def _on_prov_refresh_click(self):
for provider in providers:
self.provider_combo.addItem(provider["name"], provider)
- def _on_clear_listwidget_click(self):
+ def _on_clear_listwidget_click(self) -> None:
"""Clears the contents of the QgsListWidget and the annotations."""
items = self.routing_fromline_list.selectedItems()
if items:
@@ -535,7 +546,9 @@ def _on_clear_listwidget_click(self):
if self.line_tool:
self.line_tool.canvas.scene().removeItem(self.line_tool.rubberBand)
- def _linetool_annotate_point(self, point, idx, crs=None):
+ def _linetool_annotate_point(
+ self, point: QgsPointXY, idx: int, crs: Optional[QgsCoordinateReferenceSystem] = None
+ ) -> QgsAnnotation:
if not crs:
crs = self._iface.mapCanvas().mapSettings().destinationCrs()
@@ -554,7 +567,7 @@ def _linetool_annotate_point(self, point, idx, crs=None):
return QgsMapCanvasAnnotationItem(annotation, self.annotation_canvas).annotation()
- def _clear_annotations(self):
+ def _clear_annotations(self) -> None:
"""Clears annotations"""
for annotation_item in self.annotation_canvas.annotationItems():
annotation = annotation_item.annotation()
@@ -562,7 +575,7 @@ def _clear_annotations(self):
self.project.annotationManager().removeAnnotation(annotation)
self.annotations = []
- def _on_linetool_init(self):
+ def _on_linetool_init(self) -> None:
"""Hides GUI dialog, inits line maptool and add items to line list box."""
# Remove blue lines (rubber band)
if self.line_tool:
@@ -580,7 +593,7 @@ def _on_linetool_init(self):
)
self.line_tool.doubleClicked.connect(self._on_linetool_map_doubleclick)
- def _on_linetool_map_click(self, point, idx):
+ def _on_linetool_map_click(self, point: QgsPointXY, idx: int) -> None:
"""Adds an item to QgsListWidget and annotates the point in the map canvas"""
map_crs = self._iface.mapCanvas().mapSettings().destinationCrs()
@@ -591,7 +604,7 @@ def _on_linetool_map_click(self, point, idx):
annotation = self._linetool_annotate_point(point, idx)
self.project.annotationManager().addAnnotation(annotation)
- def _reindex_list_items(self):
+ def _reindex_list_items(self) -> None:
"""Resets the index when an item in the list is moved"""
items = [
self.routing_fromline_list.item(x).text()
@@ -610,7 +623,7 @@ def _reindex_list_items(self):
annotation = self._linetool_annotate_point(point, idx, crs)
self.project.annotationManager().addAnnotation(annotation)
- def _on_linetool_map_doubleclick(self):
+ def _on_linetool_map_doubleclick(self) -> None:
"""
Populate line list widget with coordinates, end line drawing and show dialog again.
"""
diff --git a/ORStools/gui/ORStoolsDialogConfig.py b/ORStools/gui/ORStoolsDialogConfig.py
index 8983a90b..ed2b15f6 100644
--- a/ORStools/gui/ORStoolsDialogConfig.py
+++ b/ORStools/gui/ORStoolsDialogConfig.py
@@ -41,7 +41,7 @@
class ORStoolsDialogConfigMain(QDialog, Ui_ORStoolsDialogConfigBase):
"""Builds provider config dialog."""
- def __init__(self, parent=None):
+ def __init__(self, parent=None) -> None:
"""
:param parent: Parent window for modality.
:type parent: QDialog
@@ -62,7 +62,7 @@ def __init__(self, parent=None):
# Change OK to Save in config window
self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Save"))
- def accept(self):
+ def accept(self) -> None:
"""When the OK Button is clicked, in-memory temp_config is updated and written to config.yml"""
collapsible_boxes = self.providers.findChildren(QgsCollapsibleGroupBox)
@@ -84,7 +84,7 @@ def accept(self):
self.close()
@staticmethod
- def _adjust_timeout_input(input_line_edit: QLineEdit):
+ def _adjust_timeout_input(input_line_edit: QLineEdit) -> None:
"""
Corrects the value of the input to the top or bottom value of
the specified range of the QIntValidator for the field.
@@ -100,7 +100,7 @@ def _adjust_timeout_input(input_line_edit: QLineEdit):
elif int(text) > val.top():
input_line_edit.setText(str(val.top()))
- def _build_ui(self):
+ def _build_ui(self) -> None:
"""Builds the UI on dialog startup."""
for provider_entry in self.temp_config["providers"]:
@@ -119,7 +119,7 @@ def _build_ui(self):
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
- def _add_provider(self):
+ def _add_provider(self) -> None:
"""Adds an empty provider box to be filled out by the user."""
self._collapse_boxes()
@@ -130,7 +130,7 @@ def _add_provider(self):
if ok:
self._add_box(provider_name, "http://localhost:8082/ors", "", 60, new=True)
- def _remove_provider(self):
+ def _remove_provider(self) -> None:
"""Remove list of providers from list."""
providers = [provider["name"] for provider in self.temp_config["providers"]]
@@ -152,13 +152,13 @@ def _remove_provider(self):
provider_id = providers.index(provider)
del self.temp_config["providers"][provider_id]
- def _collapse_boxes(self):
+ def _collapse_boxes(self) -> None:
"""Collapse all QgsCollapsibleGroupBoxes."""
collapsible_boxes = self.providers.findChildren(QgsCollapsibleGroupBox)
for box in collapsible_boxes:
box.setCollapsed(True)
- def _add_box(self, name, url, key, timeout, new=False):
+ def _add_box(self, name: str, url: str, key: str, timeout: int, new: bool = False) -> None:
"""
Adds a provider box to the QWidget layout and self.temp_config.
diff --git a/ORStools/proc/base_processing_algorithm.py b/ORStools/proc/base_processing_algorithm.py
index 47e136d3..61df4b88 100644
--- a/ORStools/proc/base_processing_algorithm.py
+++ b/ORStools/proc/base_processing_algorithm.py
@@ -40,7 +40,7 @@
QgsProcessingFeedback,
QgsSettings,
)
-from typing import Any
+from typing import Any, Dict
from PyQt5.QtGui import QIcon
@@ -55,7 +55,7 @@
class ORSBaseProcessingAlgorithm(QgsProcessingAlgorithm):
"""Base algorithm class for ORS algorithms"""
- def __init__(self):
+ def __init__(self) -> None:
"""
Default attributes used in all child classes
"""
@@ -92,7 +92,7 @@ def name(self) -> str:
"""
return self.ALGO_NAME
- def shortHelpString(self):
+ def shortHelpString(self) -> str:
"""
Displays the sidebar help in the algorithm window
"""
@@ -101,7 +101,7 @@ def shortHelpString(self):
return read_help_file(algorithm=self.ALGO_NAME, locale=locale)
@staticmethod
- def helpUrl():
+ def helpUrl() -> str:
"""
Will be connected to the Help button in the Algorithm window
"""
@@ -222,7 +222,7 @@ def parseOptions(self, parameters: dict, context: QgsProcessingContext) -> dict:
return options
# noinspection PyUnusedLocal
- def initAlgorithm(self, configuration):
+ def initAlgorithm(self, configuration: Dict) -> None:
"""
Combines default and algorithm parameters and adds them in order to the
algorithm dialog window.
@@ -244,6 +244,6 @@ def initAlgorithm(self, configuration):
self.addParameter(param)
- def tr(self, string, context=None):
+ def tr(self, string: str, context=None) -> str:
context = context or self.__class__.__name__
return QCoreApplication.translate(context, string)
diff --git a/ORStools/proc/directions_lines_proc.py b/ORStools/proc/directions_lines_proc.py
index 7398d194..24ec00b4 100644
--- a/ORStools/proc/directions_lines_proc.py
+++ b/ORStools/proc/directions_lines_proc.py
@@ -27,6 +27,8 @@
***************************************************************************/
"""
+from typing import List, Dict, Generator
+
from qgis._core import (
QgsFeature,
QgsVectorLayer,
@@ -42,6 +44,9 @@
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
QgsPointXY,
+ QgsProcessingFeatureSource,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
)
from ORStools.common import directions_core, PROFILES, PREFERENCES, OPTIMIZATION_MODES
@@ -56,15 +61,15 @@ class ORSDirectionsLinesAlgo(ORSBaseProcessingAlgorithm):
def __init__(self):
super().__init__()
- self.ALGO_NAME = "directions_from_polylines_layer"
- self.GROUP = "Directions"
- self.IN_LINES = "INPUT_LINE_LAYER"
- self.IN_FIELD = "INPUT_LAYER_FIELD"
- self.IN_PREFERENCE = "INPUT_PREFERENCE"
- self.IN_OPTIMIZE = "INPUT_OPTIMIZE"
- self.IN_MODE = "INPUT_MODE"
- self.EXPORT_ORDER = "EXPORT_ORDER"
- self.PARAMETERS = [
+ self.ALGO_NAME: str = "directions_from_polylines_layer"
+ self.GROUP: str = "Directions"
+ self.IN_LINES: str = "INPUT_LINE_LAYER"
+ self.IN_FIELD: str = "INPUT_LAYER_FIELD"
+ self.IN_PREFERENCE: str = "INPUT_PREFERENCE"
+ self.IN_OPTIMIZE: str = "INPUT_OPTIMIZE"
+ self.IN_MODE: str = "INPUT_MODE"
+ self.EXPORT_ORDER: str = "EXPORT_ORDER"
+ self.PARAMETERS: List = [
QgsProcessingParameterFeatureSource(
name=self.IN_LINES,
description=self.tr("Input Line layer"),
@@ -93,7 +98,9 @@ def __init__(self):
QgsProcessingParameterBoolean(self.EXPORT_ORDER, self.tr("Export order of jobs")),
]
- def processAlgorithm(self, parameters, context, feedback):
+ def processAlgorithm(
+ self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback)
profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]]
@@ -199,7 +206,7 @@ def processAlgorithm(self, parameters, context, feedback):
return {self.OUT: dest_id}
@staticmethod
- def _get_sorted_lines(layer, field_name):
+ def _get_sorted_lines(layer: QgsProcessingFeatureSource, field_name: str) -> Generator:
"""
Generator to yield geometry and ID value sorted by feature ID. Careful: feat.id() is not necessarily
permanent
@@ -229,7 +236,6 @@ def _get_sorted_lines(layer, field_name):
line = [
x_former.transform(QgsPointXY(point)) for point in feat.geometry().asPolyline()
]
-
yield line, field_value
def displayName(self) -> str:
diff --git a/ORStools/proc/directions_points_layer_proc.py b/ORStools/proc/directions_points_layer_proc.py
index 56030ceb..5d914476 100644
--- a/ORStools/proc/directions_points_layer_proc.py
+++ b/ORStools/proc/directions_points_layer_proc.py
@@ -27,6 +27,9 @@
***************************************************************************/
"""
+from typing import Dict, List
+
+
from qgis._core import (
QgsVectorLayer,
QgsFeature,
@@ -42,6 +45,8 @@
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
QgsPointXY,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
)
from ORStools.common import directions_core, PROFILES, PREFERENCES, OPTIMIZATION_MODES
@@ -56,16 +61,16 @@ class ORSDirectionsPointsLayerAlgo(ORSBaseProcessingAlgorithm):
def __init__(self):
super().__init__()
- self.ALGO_NAME = "directions_from_points_1_layer"
- self.GROUP = "Directions"
- self.IN_POINTS = "INPUT_POINT_LAYER"
- self.IN_FIELD = "INPUT_LAYER_FIELD"
- self.IN_PREFERENCE = "INPUT_PREFERENCE"
- self.IN_OPTIMIZE = "INPUT_OPTIMIZE"
- self.IN_MODE = "INPUT_MODE"
- self.IN_SORTBY = "INPUT_SORTBY"
- self.EXPORT_ORDER = "EXPORT_ORDER"
- self.PARAMETERS = [
+ self.ALGO_NAME: str = "directions_from_points_1_layer"
+ self.GROUP: str = "Directions"
+ self.IN_POINTS: str = "INPUT_POINT_LAYER"
+ self.IN_FIELD: str = "INPUT_LAYER_FIELD"
+ self.IN_PREFERENCE: str = "INPUT_PREFERENCE"
+ self.IN_OPTIMIZE: str = "INPUT_OPTIMIZE"
+ self.IN_MODE: str = "INPUT_MODE"
+ self.IN_SORTBY: str = "INPUT_SORTBY"
+ self.EXPORT_ORDER: str = "EXPORT_ORDER"
+ self.PARAMETERS: List = [
QgsProcessingParameterFeatureSource(
name=self.IN_POINTS,
description=self.tr("Input (Multi)Point layer"),
@@ -101,7 +106,9 @@ def __init__(self):
QgsProcessingParameterBoolean(self.EXPORT_ORDER, self.tr("Export order of jobs")),
]
- def processAlgorithm(self, parameters, context, feedback):
+ def processAlgorithm(
+ self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback)
profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]]
diff --git a/ORStools/proc/directions_points_layers_proc.py b/ORStools/proc/directions_points_layers_proc.py
index b7e00379..10634bb0 100644
--- a/ORStools/proc/directions_points_layers_proc.py
+++ b/ORStools/proc/directions_points_layers_proc.py
@@ -27,6 +27,9 @@
***************************************************************************/
"""
+from typing import Dict
+
+from qgis._core import QgsField
from qgis.core import (
QgsWkbTypes,
QgsCoordinateReferenceSystem,
@@ -34,6 +37,9 @@
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
+ QgsProcessingFeatureSource,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
)
from ORStools.common import directions_core, PROFILES, PREFERENCES
@@ -45,18 +51,18 @@
class ORSDirectionsPointsLayersAlgo(ORSBaseProcessingAlgorithm):
def __init__(self):
super().__init__()
- self.ALGO_NAME = "directions_from_points_2_layers"
- self.GROUP = "Directions"
+ self.ALGO_NAME: str = "directions_from_points_2_layers"
+ self.GROUP: str = "Directions"
self.MODE_SELECTION: list = ["Row-by-Row", "All-by-All"]
- self.IN_START = "INPUT_START_LAYER"
- self.IN_START_FIELD = "INPUT_START_FIELD"
- self.IN_SORT_START_BY = "INPUT_SORT_START_BY"
- self.IN_END = "INPUT_END_LAYER"
- self.IN_END_FIELD = "INPUT_END_FIELD"
- self.IN_SORT_END_BY = "INPUT_SORT_END_BY"
- self.IN_PREFERENCE = "INPUT_PREFERENCE"
- self.IN_MODE = "INPUT_MODE"
- self.PARAMETERS = [
+ self.IN_START: str = "INPUT_START_LAYER"
+ self.IN_START_FIELD: str = "INPUT_START_FIELD"
+ self.IN_SORT_START_BY: str = "INPUT_SORT_START_BY"
+ self.IN_END: str = "INPUT_END_LAYER"
+ self.IN_END_FIELD: str = "INPUT_END_FIELD"
+ self.IN_SORT_END_BY: str = "INPUT_SORT_END_BY"
+ self.IN_PREFERENCE: str = "INPUT_PREFERENCE"
+ self.IN_MODE: str = "INPUT_MODE"
+ self.PARAMETERS: list = [
QgsProcessingParameterFeatureSource(
name=self.IN_START,
description=self.tr("Input Start Point layer"),
@@ -111,7 +117,9 @@ def __init__(self):
# TODO: preprocess parameters to options the range cleanup below:
# https://www.qgis.org/pyqgis/master/core/Processing/QgsProcessingAlgorithm.html#qgis.core.QgsProcessingAlgorithm.preprocessParameters
- def processAlgorithm(self, parameters, context, feedback):
+ def processAlgorithm(
+ self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback)
profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]]
@@ -211,18 +219,25 @@ def sort_end(f):
return {self.OUT: dest_id}
@staticmethod
- def _get_route_dict(source, source_field, sort_start, destination, destination_field, sort_end):
+ def _get_route_dict(
+ source: QgsProcessingFeatureSource,
+ source_field: QgsField,
+ sort_start,
+ destination: QgsProcessingFeatureSource,
+ destination_field: QgsField,
+ sort_end,
+ ) -> dict:
"""
Compute route_dict from input layer.
:param source: Input from layer
- :type source: QgsProcessingParameterFeatureSource
+ :type source: QgsProcessingFeatureSource
:param source_field: ID field from layer.
:type source_field: QgsField
:param destination: Input to layer.
- :type destination: QgsProcessingParameterFeatureSource
+ :type destination: QgsProcessingFeatureSource
:param destination_field: ID field to layer.
:type destination_field: QgsField
diff --git a/ORStools/proc/isochrones_layer_proc.py b/ORStools/proc/isochrones_layer_proc.py
index 0ce3bc53..8577ee6b 100644
--- a/ORStools/proc/isochrones_layer_proc.py
+++ b/ORStools/proc/isochrones_layer_proc.py
@@ -27,6 +27,8 @@
***************************************************************************/
"""
+from typing import Dict
+
from qgis.core import (
QgsWkbTypes,
QgsCoordinateReferenceSystem,
@@ -38,6 +40,8 @@
QgsProcessingParameterString,
QgsProcessingParameterEnum,
QgsProcessingParameterNumber,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
)
from ORStools.common import isochrones_core, PROFILES, DIMENSIONS, LOCATION_TYPES
@@ -52,16 +56,16 @@ def __init__(self):
self.ALGO_NAME = "isochrones_from_layer"
self.GROUP = "Isochrones"
- self.IN_POINTS = "INPUT_POINT_LAYER"
- self.IN_FIELD = "INPUT_FIELD"
- self.IN_METRIC = "INPUT_METRIC"
- self.IN_RANGES = "INPUT_RANGES"
- self.IN_KEY = "INPUT_APIKEY"
- self.IN_DIFFERENCE = "INPUT_DIFFERENCE"
- self.USE_SMOOTHING = "USE_SMOOTHING"
- self.IN_SMOOTHING = "INPUT_SMOOTHING"
- self.LOCATION_TYPE = "LOCATION_TYPE"
- self.PARAMETERS = [
+ self.IN_POINTS: str = "INPUT_POINT_LAYER"
+ self.IN_FIELD: str = "INPUT_FIELD"
+ self.IN_METRIC: str = "INPUT_METRIC"
+ self.IN_RANGES: str = "INPUT_RANGES"
+ self.IN_KEY: str = "INPUT_APIKEY"
+ self.IN_DIFFERENCE: str = "INPUT_DIFFERENCE"
+ self.USE_SMOOTHING: str = "USE_SMOOTHING"
+ self.IN_SMOOTHING: str = "INPUT_SMOOTHING"
+ self.LOCATION_TYPE: str = "LOCATION_TYPE"
+ self.PARAMETERS: list = [
QgsProcessingParameterFeatureSource(
name=self.IN_POINTS,
description=self.tr("Input Point layer"),
@@ -113,7 +117,9 @@ def __init__(self):
# TODO: preprocess parameters to options the range cleanup below:
# https://www.qgis.org/pyqgis/master/core/Processing/QgsProcessingAlgorithm.html#qgis.core.QgsProcessingAlgorithm.prepareAlgorithm
- def processAlgorithm(self, parameters, context, feedback):
+ def processAlgorithm(
+ self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback)
profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]]
@@ -203,7 +209,9 @@ def processAlgorithm(self, parameters, context, feedback):
return {self.OUT: self.dest_id}
# noinspection PyUnusedLocal
- def postProcessAlgorithm(self, context, feedback):
+ def postProcessAlgorithm(
+ self, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
"""Style polygon layer in post-processing step."""
# processed_layer = self.isochrones.calculate_difference(self.dest_id, context)
processed_layer = QgsProcessingUtils.mapLayerFromString(self.dest_id, context)
diff --git a/ORStools/proc/isochrones_point_proc.py b/ORStools/proc/isochrones_point_proc.py
index 63b2a3cb..d9ced450 100644
--- a/ORStools/proc/isochrones_point_proc.py
+++ b/ORStools/proc/isochrones_point_proc.py
@@ -27,6 +27,8 @@
***************************************************************************/
"""
+from typing import Dict
+
from qgis.core import (
QgsWkbTypes,
QgsCoordinateReferenceSystem,
@@ -35,6 +37,8 @@
QgsProcessingParameterEnum,
QgsProcessingParameterPoint,
QgsProcessingParameterNumber,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
)
from ORStools.common import isochrones_core, PROFILES, DIMENSIONS, LOCATION_TYPES
@@ -46,16 +50,16 @@
class ORSIsochronesPointAlgo(ORSBaseProcessingAlgorithm):
def __init__(self):
super().__init__()
- self.ALGO_NAME = "isochrones_from_point"
- self.GROUP = "Isochrones"
- self.IN_POINT = "INPUT_POINT"
- self.IN_METRIC = "INPUT_METRIC"
- self.IN_RANGES = "INPUT_RANGES"
- self.IN_KEY = "INPUT_APIKEY"
- self.IN_DIFFERENCE = "INPUT_DIFFERENCE"
- self.IN_SMOOTHING = "INPUT_SMOOTHING"
- self.LOCATION_TYPE = "LOCATION_TYPE"
- self.PARAMETERS = [
+ self.ALGO_NAME: str = "isochrones_from_point"
+ self.GROUP: str = "Isochrones"
+ self.IN_POINT: str = "INPUT_POINT"
+ self.IN_METRIC: str = "INPUT_METRIC"
+ self.IN_RANGES: str = "INPUT_RANGES"
+ self.IN_KEY: str = "INPUT_APIKEY"
+ self.IN_DIFFERENCE: str = "INPUT_DIFFERENCE"
+ self.IN_SMOOTHING: str = "INPUT_SMOOTHING"
+ self.LOCATION_TYPE: str = "LOCATION_TYPE"
+ self.PARAMETERS: list = [
QgsProcessingParameterPoint(
name=self.IN_POINT,
description=self.tr(
@@ -99,7 +103,9 @@ def __init__(self):
# TODO: preprocess parameters to options the range cleanup below:
# https://www.qgis.org/pyqgis/master/core/Processing/QgsProcessingAlgorithm.html#qgis.core.QgsProcessingAlgorithm.preprocessParameters
- def processAlgorithm(self, parameters, context, feedback):
+ def processAlgorithm(
+ self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback)
profile = dict(enumerate(PROFILES))[parameters[self.IN_PROFILE]]
@@ -159,7 +165,7 @@ def processAlgorithm(self, parameters, context, feedback):
return {self.OUT: self.dest_id}
# noinspection PyUnusedLocal
- def postProcessAlgorithm(self, context, feedback):
+ def postProcessAlgorithm(self, context, feedback) -> Dict[str, str]:
"""Style polygon layer in post-processing step."""
processed_layer = QgsProcessingUtils.mapLayerFromString(self.dest_id, context)
self.isochrones.stylePoly(processed_layer)
diff --git a/ORStools/proc/matrix_proc.py b/ORStools/proc/matrix_proc.py
index 5a365fb2..7bb98998 100644
--- a/ORStools/proc/matrix_proc.py
+++ b/ORStools/proc/matrix_proc.py
@@ -27,6 +27,8 @@
***************************************************************************/
"""
+from typing import Dict
+
from qgis.core import (
QgsWkbTypes,
QgsFeature,
@@ -36,6 +38,8 @@
QgsProcessingException,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
)
from PyQt5.QtCore import QVariant
@@ -49,13 +53,13 @@
class ORSMatrixAlgo(ORSBaseProcessingAlgorithm):
def __init__(self):
super().__init__()
- self.ALGO_NAME = "matrix_from_layers"
- self.GROUP = "Matrix"
- self.IN_START = "INPUT_START_LAYER"
- self.IN_START_FIELD = "INPUT_START_FIELD"
- self.IN_END = "INPUT_END_LAYER"
- self.IN_END_FIELD = "INPUT_END_FIELD"
- self.PARAMETERS = [
+ self.ALGO_NAME: str = "matrix_from_layers"
+ self.GROUP: str = "Matrix"
+ self.IN_START: str = "INPUT_START_LAYER"
+ self.IN_START_FIELD: str = "INPUT_START_FIELD"
+ self.IN_END: str = "INPUT_END_LAYER"
+ self.IN_END_FIELD: str = "INPUT_END_FIELD"
+ self.PARAMETERS: list = [
QgsProcessingParameterFeatureSource(
name=self.IN_START,
description=self.tr("Input Start Point layer"),
@@ -82,7 +86,9 @@ def __init__(self):
),
]
- def processAlgorithm(self, parameters, context, feedback):
+ def processAlgorithm(
+ self, parameters: dict, context: QgsProcessingContext, feedback: QgsProcessingFeedback
+ ) -> Dict[str, str]:
ors_client = self._get_ors_client_from_provider(parameters[self.IN_PROVIDER], feedback)
# Get profile value
diff --git a/ORStools/proc/provider.py b/ORStools/proc/provider.py
index 324b2b58..0a10e029 100644
--- a/ORStools/proc/provider.py
+++ b/ORStools/proc/provider.py
@@ -44,7 +44,7 @@ class ORStoolsProvider(QgsProcessingProvider):
def __init__(self):
QgsProcessingProvider.__init__(self)
- def unload(self):
+ def unload(self) -> None:
"""
Unloads the provider. Any tear-down steps required by the provider
should be implemented here.
@@ -52,7 +52,7 @@ def unload(self):
pass
# noinspection PyPep8Naming
- def loadAlgorithms(self):
+ def loadAlgorithms(self) -> None:
"""
Loads all algorithms belonging to this provider.
"""
@@ -65,11 +65,11 @@ def loadAlgorithms(self):
self.addAlgorithm(ORSMatrixAlgo())
@staticmethod
- def icon():
+ def icon() -> QIcon:
return QIcon(RESOURCE_PREFIX + "icon_orstools.png")
@staticmethod
- def id():
+ def id() -> str:
"""
Returns the unique provider id, used for identifying the provider. This
string should be a unique, short, character only string, eg "qgis" or
@@ -78,7 +78,7 @@ def id():
return PLUGIN_NAME.strip()
@staticmethod
- def name():
+ def name() -> str:
"""
Returns the provider name, which is used to describe the provider
within the GUI.
@@ -89,7 +89,7 @@ def name():
# noinspection PyPep8Naming
@staticmethod
- def longName():
+ def longName() -> str:
"""
Returns the a longer version of the provider name, which can include
extra details such as version numbers. E.g. "Lastools LIDAR tools
diff --git a/ORStools/utils/configmanager.py b/ORStools/utils/configmanager.py
index 0005e0c4..e8d1c534 100644
--- a/ORStools/utils/configmanager.py
+++ b/ORStools/utils/configmanager.py
@@ -34,7 +34,7 @@
from ORStools import CONFIG_PATH
-def read_config():
+def read_config() -> dict:
"""
Reads config.yml from file and returns the parsed dict.
@@ -47,7 +47,7 @@ def read_config():
return doc
-def write_config(new_config):
+def write_config(new_config: dict) -> None:
"""
Dumps new config
@@ -58,7 +58,7 @@ def write_config(new_config):
yaml.safe_dump(new_config, f)
-def write_env_var(key, value):
+def write_env_var(key: str, value: str) -> None:
"""
Update quota env variables
diff --git a/ORStools/utils/convert.py b/ORStools/utils/convert.py
index 88de03db..1b6ab08f 100644
--- a/ORStools/utils/convert.py
+++ b/ORStools/utils/convert.py
@@ -28,7 +28,7 @@
"""
-def decode_polyline(polyline, is3d=False):
+def decode_polyline(polyline: str, is3d: bool = False) -> dict:
"""Decodes a Polyline string into a GeoJSON geometry.
:param polyline: An encoded polyline, only the geometry.
diff --git a/ORStools/utils/logger.py b/ORStools/utils/logger.py
index cd6bf301..b8926392 100644
--- a/ORStools/utils/logger.py
+++ b/ORStools/utils/logger.py
@@ -32,7 +32,7 @@
from ORStools import PLUGIN_NAME
-def log(message, level_in=0):
+def log(message: str, level_in: int = 0):
"""
Writes to QGIS inbuilt logger accessible through panel.
diff --git a/ORStools/utils/maptools.py b/ORStools/utils/maptools.py
index ae347d0b..ad0668b5 100644
--- a/ORStools/utils/maptools.py
+++ b/ORStools/utils/maptools.py
@@ -27,6 +27,7 @@
***************************************************************************/
"""
+from qgis._gui import QgsMapCanvas, QgsMapMouseEvent
from qgis.core import QgsWkbTypes
from qgis.gui import QgsMapToolEmitPoint, QgsRubberBand
@@ -39,7 +40,7 @@
class LineTool(QgsMapToolEmitPoint):
"""Line Map tool to capture mapped lines."""
- def __init__(self, canvas):
+ def __init__(self, canvas: QgsMapCanvas) -> None:
"""
:param canvas: current map canvas
:type canvas: QgsMapCanvas
@@ -58,7 +59,7 @@ def __init__(self, canvas):
self.points = []
self.reset()
- def reset(self):
+ def reset(self) -> None:
"""reset rubber band and captured points."""
self.points = []
@@ -66,7 +67,7 @@ def reset(self):
pointDrawn = pyqtSignal(["QgsPointXY", "int"])
- def canvasReleaseEvent(self, e):
+ def canvasReleaseEvent(self, e: QgsMapMouseEvent) -> None:
"""Add marker to canvas and shows line."""
new_point = self.toMapCoordinates(e.pos())
self.points.append(new_point)
@@ -75,7 +76,7 @@ def canvasReleaseEvent(self, e):
self.pointDrawn.emit(new_point, self.points.index(new_point))
self.showLine()
- def showLine(self):
+ def showLine(self) -> None:
"""Builds rubber band from all points and adds it to the map canvas."""
self.rubberBand.reset(geometryType=QgsWkbTypes.LineGeometry)
for point in self.points:
@@ -87,12 +88,12 @@ def showLine(self):
doubleClicked = pyqtSignal()
# noinspection PyUnusedLocal
- def canvasDoubleClickEvent(self, e):
+ def canvasDoubleClickEvent(self, e: QgsMapMouseEvent) -> None:
"""Ends line drawing and deletes rubber band and markers from map canvas."""
# noinspection PyUnresolvedReferences
self.doubleClicked.emit()
self.canvas.scene().removeItem(self.rubberBand)
- def deactivate(self):
+ def deactivate(self) -> None:
super(LineTool, self).deactivate()
self.deactivated.emit()
diff --git a/ORStools/utils/transform.py b/ORStools/utils/transform.py
index cd603e02..5fe5c20b 100644
--- a/ORStools/utils/transform.py
+++ b/ORStools/utils/transform.py
@@ -30,7 +30,7 @@
from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsProject
-def transformToWGS(old_crs):
+def transformToWGS(old_crs: QgsCoordinateReferenceSystem) -> QgsCoordinateTransform:
"""
Returns a transformer to WGS84