Skip to content

Commit

Permalink
formatting, remove some NULL
Browse files Browse the repository at this point in the history
  • Loading branch information
joshinils committed Mar 3, 2024
1 parent 0adfa40 commit ca8c65f
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 96 deletions.
70 changes: 44 additions & 26 deletions helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,50 @@
from qgis import *
from qgis.core import *
from qgis.PyQt.QtCore import *
from qgis.core import QgsFeature
from qgis.core import NULL

debug_warning_counter__derive_attribute = 0
debug_warning_counter__cast_to_float = 0
debug_warning_counter_max_val = 5

def deriveAttribute(feature, attribute_name, type, side, vartype):

def derive_attribute(feature: QgsFeature, attribute_name, way_type, side, vartype):
"""
derive cycleway and sidewalk attributes mapped on the centerline for transferring them to separate ways
"""

attribute = NULL
attribute = feature.attribute(str(type) + ':' + str(side) + ':' + str(attribute_name))
if not attribute:
attribute = feature.attribute(str(type) + ':both:' + str(attribute_name))
attribute = feature.attribute(str(way_type) + ':' + str(side) + ':' + str(attribute_name))

if not attribute:
attribute = feature.attribute(str(type) + ':' + str(attribute_name))
if attribute != NULL:
try:
if vartype == 'int':
attribute = int(attribute)
if vartype == 'float':
attribute = float(attribute)
if vartype == 'str':
attribute = str(attribute)
except TypeError:
attribute = NULL
return attribute


def deriveSeparation(feature, traffic_mode):
attribute = feature.attribute(str(way_type) + ':' + str(attribute_name))

if attribute is None:
return None

try:
if vartype == 'int':
return int(attribute)
if vartype == 'float':
return float(attribute)
if vartype == 'str':
return str(attribute)
except (TypeError, ValueError) as e:
global debug_warning_counter__derive_attribute
if debug_warning_counter__derive_attribute < 5:
print(f"derive_attribute: error, trying to cast type {type(attribute)} = {attribute} to {vartype}! ({e})")
debug_warning_counter__derive_attribute += 1
if debug_warning_counter__derive_attribute >= 5:
print("derive_attribute: this was the last warning, future warnings will be muted!")
return None


def derive_separation(feature, traffic_mode):
"""
derive separation on the side of a specific traffic mode (e.g. foot traffic usually on the right side)
"""

separation = NULL
separation = None
separation_left = feature.attribute('separation:left')
separation_right = feature.attribute('separation:right')
traffic_mode_left = feature.attribute('traffic_mode:left')
Expand All @@ -62,7 +73,7 @@ def deriveSeparation(feature, traffic_mode):
return separation


def getAccess(feature, access_key):
def get_access(feature, access_key):
"""
interpret access tags of a feature to get the access value for a specific traffic mode
"""
Expand All @@ -77,7 +88,7 @@ def getAccess(feature, access_key):
'psv': ['motor_vehicle', 'vehicle', 'access'],
'bus': ['psv', 'motor_vehicle', 'vehicle', 'access']
}
access_value = NULL
access_value = None
if feature.fields().indexOf(access_key) != -1:
access_value = feature.attribute(access_key)
if not access_value and access_key in access_dict:
Expand All @@ -91,8 +102,14 @@ def cast_to_float(value):
# return a value as a float
try:
return float(value)
except TypeError:
return None
except (TypeError, ValueError) as e:
global debug_warning_counter__cast_to_float
if debug_warning_counter__cast_to_float < 5:
print(f"cast_to_float: error, trying to cast type {type(value)} = {value} to float! ({e})")
debug_warning_counter__cast_to_float += 1
if debug_warning_counter__cast_to_float >= 5:
print("cast_to_float: this was the last warning, future warnings will be muted!")
return NULL


def get_weakest_surface_value(value_list):
Expand Down Expand Up @@ -144,10 +161,11 @@ def get_weakest_surface_value(value_list):
return value


def addDelimitedValue(var, value):
def add_delimited_value(var, value):
"""
add a value to a delimited string
"""

if var:
var += ';'
var += value
Expand Down
14 changes: 9 additions & 5 deletions script_main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import imp
import time
from os.path import exists
from typing import TYPE_CHECKING

import qgis.processing as processing
from qgis.core import (
if TYPE_CHECKING:
from pathlib import Path

import qgis.processing as processing # type: ignore
from qgis.core import ( # type: ignore
QgsCoordinateReferenceSystem, QgsField, QgsProject, QgsVectorLayer, edit
)
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtCore import QVariant # type: ignore

import helper_functions
import script_step_01
Expand All @@ -23,12 +27,12 @@
imp.reload(script_step_04)


def main(dir_input, dir_output):
def main(dir_input: Path, dir_output: Path) -> None:
print(time.strftime('%H:%M:%S', time.localtime()), 'Start processing:')

print(time.strftime('%H:%M:%S', time.localtime()), 'Read data...')
if not exists(dir_input):
print(time.strftime('%H:%M:%S', time.localtime()), '[!] Error: No valid input file at "' + dir_input + '".')
print(time.strftime('%H:%M:%S', time.localtime()), f'[!] Error: No valid input file at "{dir_input}".')
else:
layer_way_input = QgsVectorLayer(f"{dir_input}|geometrytype=LineString", 'way input', 'ogr')

Expand Down
19 changes: 13 additions & 6 deletions script_step_01.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
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 (
Expand Down Expand Up @@ -32,15 +36,14 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath):
}
)['OUTPUT']
# create road layer: extract all other highway types (except tracks)
layer_roads = processing.run(
layer_roads: QgsVectorLayer = processing.run(
'qgis:extractbyexpression',
{
'INPUT': layer,
'EXPRESSION': """"highway" IS NOT 'cycleway' AND "highway" IS NOT 'footway' AND "highway" IS NOT 'path' AND "highway" IS NOT 'bridleway' AND "highway" IS NOT 'steps' AND "highway" IS NOT 'track'""",
'OUTPUT': 'memory:'
}
)['OUTPUT']

print(time.strftime('%H:%M:%S', time.localtime()), ' Create check points...')

# create "check points" along each segment (to check for near/parallel highways at every checkpoint)
Expand Down Expand Up @@ -69,7 +72,7 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath):
)['OUTPUT']

# create "check buffers" (to check for near/parallel highways with in the given distance)
layer_path_points_buffers = processing.run(
layer_path_points_buffers: QgsVectorLayer = processing.run(
'native:buffer',
{
'INPUT': layer_path_points,
Expand All @@ -85,7 +88,6 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath):
sidepath_dict = {}
for buffer in layer_path_points_buffers.getFeatures():
buffer_id = buffer.attribute('id')
buffer_layer = buffer.attribute('layer')
if buffer_id not in sidepath_dict:
sidepath_dict[buffer_id] = {}
sidepath_dict[buffer_id]['checks'] = 1
Expand All @@ -111,15 +113,17 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath):
highway_list = []
name_list = []
maxspeed_dict = {}
road: QgsFeature
for road in layer_roads.selectedFeatures():
road_layer = road.attribute('layer')
if buffer_layer != road_layer:
if buffer.attribute('layer') != road.attribute('layer'):
# only consider geometries in the same layer
continue

road_id = road.attribute('id')
road_highway = road.attribute('highway')
road_name = road.attribute('name')
road_maxspeed = helper_functions.cast_to_float(road.attribute('maxspeed'))

if road_id not in id_list:
id_list.append(road_id)
if road_highway not in highway_list:
Expand All @@ -128,16 +132,19 @@ def step_01(layer, id_proc_highway, id_proc_maxspeed, id_proc_sidepath):
maxspeed_dict[road_highway] = road_maxspeed
if road_name not in name_list:
name_list.append(road_name)

for road_id in id_list:
if road_id in sidepath_dict[buffer_id]['id']:
sidepath_dict[buffer_id]['id'][road_id] += 1
else:
sidepath_dict[buffer_id]['id'][road_id] = 1

for road_highway in highway_list:
if road_highway in sidepath_dict[buffer_id]['highway']:
sidepath_dict[buffer_id]['highway'][road_highway] += 1
else:
sidepath_dict[buffer_id]['highway'][road_highway] = 1

for road_name in name_list:
if road_name in sidepath_dict[buffer_id]['name']:
sidepath_dict[buffer_id]['name'][road_name] += 1
Expand Down
44 changes: 22 additions & 22 deletions script_step_02.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def step_02(
'qgis:selectbyexpression',
{
'INPUT': layer,
'EXPRESSION': '\"offset_cycleway_left\" IS NOT NULL'
'EXPRESSION': '"offset_cycleway_left" IS NOT NULL'
}
)
offset_layer_dict["cycleway"]["left"] = processing.run(
Expand All @@ -115,7 +115,7 @@ def step_02(
'qgis:selectbyexpression',
{
'INPUT': layer,
'EXPRESSION': '\"offset_cycleway_right\" IS NOT NULL'
'EXPRESSION': '"offset_cycleway_right" IS NOT NULL'
}
)
offset_layer_dict["cycleway"]["right"] = processing.run(
Expand All @@ -130,7 +130,7 @@ def step_02(
'qgis:selectbyexpression',
{
'INPUT': layer,
'EXPRESSION': '\"offset_sidewalk_left\" IS NOT NULL'
'EXPRESSION': '"offset_sidewalk_left" IS NOT NULL'
}
)
offset_layer_dict["sidewalk"]["left"] = processing.run(
Expand All @@ -145,7 +145,7 @@ def step_02(
'qgis:selectbyexpression',
{
'INPUT': layer,
'EXPRESSION': '\"offset_sidewalk_right\" IS NOT NULL'
'EXPRESSION': '"offset_sidewalk_right" IS NOT NULL'
}
)
offset_layer_dict["sidewalk"]["right"] = processing.run(
Expand Down Expand Up @@ -176,10 +176,10 @@ def step_02(
offset_layer.changeAttributeValue(feature.id(), id_proc_highway, feature.attribute('highway'))
offset_layer.changeAttributeValue(feature.id(), id_proc_maxspeed, feature.attribute('maxspeed'))

offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('width'), helper_functions.deriveAttribute(feature, 'width', way_type, side, 'float'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('oneway'), helper_functions.deriveAttribute(feature, 'oneway', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('oneway:bicycle'), helper_functions.deriveAttribute(feature, 'oneway:bicycle', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_sign'), helper_functions.deriveAttribute(feature, 'traffic_sign', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('width'), helper_functions.derive_attribute(feature, 'width', way_type, side, 'float'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('oneway'), helper_functions.derive_attribute(feature, 'oneway', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('oneway:bicycle'), helper_functions.derive_attribute(feature, 'oneway:bicycle', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_sign'), helper_functions.derive_attribute(feature, 'traffic_sign', way_type, side, 'str'))

# surface and smoothness of cycle lanes are usually the same as on the road (if not explicitly tagged)
if (
Expand All @@ -197,7 +197,7 @@ def step_02(
)
)
):
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('surface'), helper_functions.deriveAttribute(feature, 'surface', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('surface'), helper_functions.derive_attribute(feature, 'surface', way_type, side, 'str'))
if (
way_type != 'cycleway'
or (
Expand All @@ -213,24 +213,24 @@ def step_02(
)
)
):
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('smoothness'), helper_functions.deriveAttribute(feature, 'smoothness', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('smoothness'), helper_functions.derive_attribute(feature, 'smoothness', way_type, side, 'str'))

if way_type == 'cycleway':
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation'), helper_functions.deriveAttribute(feature, 'separation', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation:both'), helper_functions.deriveAttribute(feature, 'separation:both', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation:left'), helper_functions.deriveAttribute(feature, 'separation:left', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation:right'), helper_functions.deriveAttribute(feature, 'separation:right', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation'), helper_functions.derive_attribute(feature, 'separation', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation:both'), helper_functions.derive_attribute(feature, 'separation:both', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation:left'), helper_functions.derive_attribute(feature, 'separation:left', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('separation:right'), helper_functions.derive_attribute(feature, 'separation:right', way_type, side, 'str'))

offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer'), helper_functions.deriveAttribute(feature, 'buffer', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer:both'), helper_functions.deriveAttribute(feature, 'buffer:both', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer:left'), helper_functions.deriveAttribute(feature, 'buffer:left', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer:right'), helper_functions.deriveAttribute(feature, 'buffer:right', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer'), helper_functions.derive_attribute(feature, 'buffer', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer:both'), helper_functions.derive_attribute(feature, 'buffer:both', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer:left'), helper_functions.derive_attribute(feature, 'buffer:left', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('buffer:right'), helper_functions.derive_attribute(feature, 'buffer:right', way_type, side, 'str'))

offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_mode:both'), helper_functions.deriveAttribute(feature, 'traffic_mode:both', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_mode:left'), helper_functions.deriveAttribute(feature, 'traffic_mode:left', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_mode:right'), helper_functions.deriveAttribute(feature, 'traffic_mode:right', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_mode:both'), helper_functions.derive_attribute(feature, 'traffic_mode:both', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_mode:left'), helper_functions.derive_attribute(feature, 'traffic_mode:left', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('traffic_mode:right'), helper_functions.derive_attribute(feature, 'traffic_mode:right', way_type, side, 'str'))

offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('surface:colour'), helper_functions.deriveAttribute(feature, 'surface:colour', way_type, side, 'str'))
offset_layer.changeAttributeValue(feature.id(), offset_layer.fields().indexOf('surface:colour'), helper_functions.derive_attribute(feature, 'surface:colour', way_type, side, 'str'))

# TODO: Attribute mit "both" auf left und right aufteilen?

Expand Down
Loading

0 comments on commit ca8c65f

Please sign in to comment.