diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4ef25b2..e71b63e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,9 +26,9 @@ repos: hooks: - id: isort name: isort -# - repo: https://github.com/pre-commit/mirrors-mypy -# rev: 'v0.931' # Use the sha / tag you want to point at -# hooks: -# - id: mypy -# args: [--disallow-untyped-defs, --disallow-incomplete-defs] -# # args: [--disallow-untyped-defs, --disallow-incomplete-defs, --disallow-untyped-calls] +- repo: https://github.com/pre-commit/mirrors-mypy + rev: 'v0.931' # Use the sha / tag you want to point at + hooks: + - id: mypy + args: [--disallow-untyped-defs, --disallow-incomplete-defs] + # args: [--disallow-untyped-defs, --disallow-incomplete-defs, --disallow-untyped-calls] diff --git a/cycling_quality_index.py b/cycling_quality_index.py index fad8e54..6785d19 100755 --- a/cycling_quality_index.py +++ b/cycling_quality_index.py @@ -8,7 +8,6 @@ version/date: 2024-03-02 """ -import imp import imp import pathlib diff --git a/helper_functions.py b/helper_functions.py index 90d4986..467512a 100644 --- a/helper_functions.py +++ b/helper_functions.py @@ -2,11 +2,13 @@ functions used in multiple files to be imported """ +from typing import Any, List, Optional + from qgis import * from qgis.core import * +from qgis.core import NULL, QgsFeature from qgis.PyQt.QtCore import * -from qgis.core import QgsFeature -from qgis.core import NULL +from qgis.PyQt.QtCore import QVariant # type: ignore debug_warning_counter__derive_attribute = 0 debug_warning_counter__cast_to_float = 0 @@ -98,7 +100,7 @@ def get_access(feature, access_key): return access_value -def cast_to_float(value): +def cast_to_float(value: Any) -> QVariant | float: # return a value as a float try: return float(value) @@ -112,12 +114,12 @@ def cast_to_float(value): return NULL -def get_weakest_surface_value(value_list): +def get_weakest_surface_value(values: List[str]) -> Optional[str]: """ from a list of surface values, choose the weakest one """ - # surface values in descent order + # surface values in descending order surface_value_list = [ 'asphalt', 'paved', @@ -150,15 +152,12 @@ def get_weakest_surface_value(value_list): 'rock' ] - value = NULL - for i in range(len(value_list)): - if value_list[i] in surface_value_list: - if not value: - value = value_list[i] - else: - if surface_value_list.index(value_list[i]) > surface_value_list.index(value): - value = value_list[i] - return value + return_value = None + for value in values: + if value in surface_value_list: + if surface_value_list.index(value) > surface_value_list.index(value): + return_value = value + return return_value def add_delimited_value(var, value): diff --git a/script_main.py b/script_main.py index d042914..64e1fbb 100644 --- a/script_main.py +++ b/script_main.py @@ -1,10 +1,7 @@ import imp import time from os.path import exists -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from pathlib import Path +from pathlib import Path import qgis.processing as processing # type: ignore from qgis.core import ( # type: ignore @@ -37,7 +34,7 @@ def main(dir_input: Path, dir_output: Path) -> None: layer_way_input = QgsVectorLayer(f"{dir_input}|geometrytype=LineString", 'way input', 'ogr') print(time.strftime('%H:%M:%S', time.localtime()), 'Reproject data...') - layer = processing.run( + layer_1: QgsVectorLayer = processing.run( 'native:reprojectlayer', { 'INPUT': layer_way_input, @@ -244,10 +241,10 @@ def main(dir_input: Path, dir_output: Path) -> None: 'crossing', 'crossing:markings' ] - layer = processing.run( + layer: QgsVectorLayer = processing.run( 'native:retainfields', { - 'INPUT': layer, + 'INPUT': layer_1, 'FIELDS': attributes_list, 'OUTPUT': 'memory:' } diff --git a/script_step_01.py b/script_step_01.py index 982232f..fbc26a8 100644 --- a/script_step_01.py +++ b/script_step_01.py @@ -1,14 +1,12 @@ import imp import time -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from qgis.core import QgsFeature, QgsVectorLayer import qgis.processing as processing from qgis.core import ( - NULL, QgsProcessingFeatureSourceDefinition, QgsProject, edit + NULL, QgsFeature, QgsProcessingFeatureSourceDefinition, QgsProject, + QgsVectorLayer, edit ) +from qgis.PyQt.QtCore import QVariant # type: ignore import helper_functions import vars_settings @@ -17,7 +15,12 @@ imp.reload(helper_functions) -def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath): +def step_01( + layer: QgsVectorLayer, + id_proc_highway: int, + id_proc_maxspeed: int, + id_proc_sidepath: int, +): """ Check paths whether they are sidepath (a path along a road) """ @@ -161,7 +164,7 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath): with edit(layer): for feature in layer.getFeatures(): hw = feature.attribute('highway') - maxspeed = feature.attribute('maxspeed') + maxspeed: QVariant = feature.attribute('maxspeed') if maxspeed == 'walk': maxspeed = 10 else: @@ -171,10 +174,10 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath): layer.changeAttributeValue(feature.id(), id_proc_maxspeed, maxspeed) continue id = feature.attribute('id') - is_sidepath = feature.attribute('is_sidepath') + is_sidepath: QVariant = feature.attribute('is_sidepath') if feature.attribute('footway') == 'sidewalk': is_sidepath = 'yes' - is_sidepath_of = feature.attribute('is_sidepath:of') + is_sidepath_of: QVariant = feature.attribute('is_sidepath:of') checks = sidepath_dict[id]['checks'] if not is_sidepath: diff --git a/script_step_02.py b/script_step_02.py index 2045799..e827cbd 100644 --- a/script_step_02.py +++ b/script_step_02.py @@ -6,6 +6,7 @@ from qgis.core import ( NULL, QgsProcessingFeatureSourceDefinition, QgsProperty, edit ) +from qgis.PyQt.QtCore import QVariant # type: ignore import helper_functions import vars_settings @@ -36,8 +37,8 @@ def step_02( with edit(layer): for feature in layer.getFeatures(): highway = feature.attribute('highway') - cycleway = feature.attribute('cycleway') - cycleway_both = feature.attribute('cycleway:both') + cycleway: QVariant = feature.attribute('cycleway') + cycleway_both: QVariant = feature.attribute('cycleway:both') cycleway_left = feature.attribute('cycleway:left') cycleway_right = feature.attribute('cycleway:right') sidewalk_bicycle = feature.attribute('sidewalk:bicycle') diff --git a/script_step_04.py b/script_step_04.py index 3d297d0..1fa1133 100644 --- a/script_step_04.py +++ b/script_step_04.py @@ -1,7 +1,9 @@ import imp import time +from typing import Optional, Tuple -from qgis.core import NULL, edit +from qgis.core import NULL, QgsFeature, QgsVectorLayer, edit +from qgis.PyQt.QtCore import QVariant # type: ignore import helper_functions import script_step_05 @@ -13,22 +15,22 @@ def function_40( - feature, + feature: QgsFeature, way_type, side, layer, id_proc_oneway, -): +) -> Tuple[QVariant | str | None, QVariant]: """ Derive oneway status. Can be one of the values in oneway_value_list (oneway applies to all vehicles, also for bicycles) or '*_motor_vehicles' (value applies to motor vehicles only) """ oneway_value_list = ['yes', 'no', '-1', 'alternating', 'reversible'] - proc_oneway = NULL - oneway = feature.attribute('oneway') - oneway_bicycle = feature.attribute('oneway:bicycle') - cycleway_oneway = feature.attribute('cycleway:oneway') + proc_oneway: QVariant | None = None + oneway: QVariant = feature.attribute('oneway') + oneway_bicycle: QVariant = feature.attribute('oneway:bicycle') + cycleway_oneway: QVariant = feature.attribute('cycleway:oneway') if way_type in ['cycle path', 'cycle track', 'shared path', 'segregated path', 'shared footway', 'crossing', 'link', 'cycle lane (advisory)', 'cycle lane (exclusive)', 'cycle lane (protected)', 'cycle lane (central)']: if oneway in oneway_value_list: proc_oneway = oneway @@ -67,11 +69,11 @@ def function_40( def function_41( way_type, - feature, + feature: QgsFeature, proc_oneway, side, oneway, - data_missing, + data_missing: str, ): """ Derive width. @@ -335,10 +337,10 @@ def function_41( def function_42( - feature, - way_type, - data_missing, -): + feature: QgsFeature, + way_type: QVariant, + data_missing: str, +) -> Tuple[Optional[str | QVariant], QVariant]: """ Derive surface and smoothness. """ @@ -379,7 +381,6 @@ def function_42( proc_smoothness = smoothness else: data_missing = helper_functions.add_delimited_value(data_missing, 'smoothness') - else: # surface and smoothness for cycle lanes and sidewalks have already been derived from original tags when calculating way offsets proc_surface = feature.attribute('surface') @@ -410,26 +411,26 @@ def function_42( if ';' in proc_surface: proc_surface = helper_functions.get_weakest_surface_value(proc_surface.split(';')) if proc_surface not in vars_settings.surface_factor_dict: - proc_surface = NULL + proc_surface = None if proc_smoothness not in vars_settings.smoothness_factor_dict: proc_smoothness = NULL return proc_surface, proc_smoothness def function_43( - way_type, - feature, - is_sidepath, - side, -): + way_type: QVariant, + feature: QgsFeature, + is_sidepath: QVariant, + side: QVariant, +) -> Tuple[QVariant | str, str | QVariant, QVariant | str, QVariant | str, QVariant | float, QVariant | float]: """ Derive (physical) separation and buffer. """ - traffic_mode_left = NULL - traffic_mode_right = NULL - separation_left = NULL - separation_right = NULL + traffic_mode_left: QVariant | str = NULL + traffic_mode_right: str | QVariant = NULL + separation_left: QVariant | str = NULL + separation_right: QVariant | str = NULL buffer_left = NULL buffer_right = NULL @@ -538,23 +539,22 @@ def function_43( def function_44( - feature, - way_type, - proc_oneway, - is_sidepath, -): + feature: QgsFeature, + way_type: str, + proc_oneway: QVariant | str | None, + is_sidepath: QVariant, +) -> Tuple[QVariant | str, QVariant, QVariant, QVariant, QVariant, QVariant, QVariant]: """ Derive mandatory use as an extra information (not used for index calculation). """ proc_mandatory = NULL - proc_traffic_sign = NULL - - cycleway = feature.attribute('cycleway') - cycleway_both = feature.attribute('cycleway:both') - cycleway_left = feature.attribute('cycleway:left') - cycleway_right = feature.attribute('cycleway:right') - bicycle = feature.attribute('bicycle') - traffic_sign: str = feature.attribute('traffic_sign') + + cycleway: QVariant = feature.attribute('cycleway') + cycleway_both: QVariant = feature.attribute('cycleway:both') + cycleway_left: QVariant = feature.attribute('cycleway:left') + cycleway_right: QVariant = feature.attribute('cycleway:right') + bicycle: QVariant = feature.attribute('bicycle') + traffic_sign: QVariant = feature.attribute('traffic_sign') proc_traffic_sign = traffic_sign if way_type in ['bicycle road', 'shared road', 'shared traffic lane', 'track or service']: @@ -588,40 +588,40 @@ def function_44( def step_04( - layer, - id_proc_oneway, - id_proc_width, - id_proc_surface, - id_proc_smoothness, - id_proc_traffic_mode_left, - id_proc_traffic_mode_right, - id_proc_separation_left, - id_proc_separation_right, - id_proc_buffer_left, - id_proc_buffer_right, - id_proc_mandatory, - id_proc_traffic_sign, - id_base_index, - id_fac_width, - id_fac_surface, - id_fac_highway, - id_fac_maxspeed, - id_fac_1, - id_fac_2, - id_fac_3, - id_fac_4, - id_index, - id_data_missing, - id_data_bonus, - id_data_malus, - id_data_incompleteness, - id_fac_protection_level, - id_prot_level_separation_left, - id_prot_level_separation_right, - id_prot_level_buffer_left, - id_prot_level_buffer_right, - id_prot_level_left, - id_prot_level_right, + layer: QgsVectorLayer, + id_proc_oneway: int, + id_proc_width: int, + id_proc_surface: int, + id_proc_smoothness: int, + id_proc_traffic_mode_left: int, + id_proc_traffic_mode_right: int, + id_proc_separation_left: int, + id_proc_separation_right: int, + id_proc_buffer_left: int, + id_proc_buffer_right: int, + id_proc_mandatory: int, + id_proc_traffic_sign: int, + id_base_index: int, + id_fac_width: int, + id_fac_surface: int, + id_fac_highway: int, + id_fac_maxspeed: int, + id_fac_1: int, + id_fac_2: int, + id_fac_3: int, + id_fac_4: int, + id_index: int, + id_data_missing: int, + id_data_bonus: int, + id_data_malus: int, + id_data_incompleteness: int, + id_fac_protection_level: int, + id_prot_level_separation_left: int, + id_prot_level_separation_right: int, + id_prot_level_buffer_left: int, + id_prot_level_buffer_right: int, + id_prot_level_left: int, + id_prot_level_right: int, ) -> None: """ 4: Derive relevant attributes for index and factors @@ -630,10 +630,10 @@ def step_04( print(time.strftime('%H:%M:%S', time.localtime()), 'Derive attributes...') with edit(layer): for feature in layer.getFeatures(): - way_type = feature.attribute('way_type') - side = feature.attribute('side') - is_sidepath = feature.attribute('proc_sidepath') - data_missing = '' + way_type: QVariant = feature.attribute('way_type') + side: QVariant = feature.attribute('side') + is_sidepath: QVariant = feature.attribute('proc_sidepath') + data_missing: str = '' proc_oneway, oneway = function_40( feature, diff --git a/vars_settings.py b/vars_settings.py index 24f9999..856b11a 100644 --- a/vars_settings.py +++ b/vars_settings.py @@ -3,8 +3,9 @@ """ from collections import defaultdict +from typing import Dict -from qgis.core import ( +from qgis.core import ( # type: ignore NULL, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsCoordinateTransformContext, QgsProject, QgsVectorFileWriter ) @@ -27,7 +28,7 @@ cycling_highway_prohibition_list = ['motorway', 'motorway_link', 'trunk', 'trunk_link'] -default_highway_width_dict = defaultdict(lambda: 11) # Default values for road/way width +default_highway_width_dict: Dict[str, float] = defaultdict(lambda: 11.0) # Default values for road/way width for key, value in { 'motorway': 15, 'motorway_link': 6, @@ -101,7 +102,7 @@ 'grade5': 'grass' } -surface_factor_dict = { +surface_factor_dict: Dict[str, float] = { 'asphalt': 1, 'paved': 1, 'concrete': 1,