Skip to content

Commit

Permalink
Merge pull request #222 from kartverket/nvdb_source_building_adjustment
Browse files Browse the repository at this point in the history
Nvdb source building adjustment
  • Loading branch information
EllingOftedalKV authored Dec 10, 2024
2 parents 251aed6 + 9a3487e commit aedf602
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 36 deletions.
11 changes: 11 additions & 0 deletions constants/n100_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ class N100_SQLResources(Enum):
""": 8,
}

new_road_symbology_size_sql_selection = {
"""(subtypekode = 2 And motorvegtype = 'Motorveg')
Or (subtypekode = 4 And motorvegtype = 'Motorveg')""": 47.5, # Red and Yellow lines
"""(subtypekode = 2 And motorvegtype <> 'Motorveg')
Or (subtypekode = 4 And motorvegtype <> 'Motorveg')
Or subtypekode = 3""": 32.5, # Red lines
"subtypekode = 1": 30, # Orange with black outline
"subtypekode IN (5, 6, 9)": 25, # White lines
"subtypekode IN (8,7,10,11)": 7.5, # Thin black lines
}

urban_areas = "objtype = 'Tettbebyggelse' Or objtype = 'Industriområde' Or objtype = 'BymessigBebyggelse'"


Expand Down
83 changes: 62 additions & 21 deletions custom_tools/general_tools/custom_arcpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ def apply_symbology(
input_layer,
in_symbology_layer,
output_name,
grouped_lyrx=False,
target_layer_name=None,
):
"""
Summary:
Expand All @@ -360,6 +362,8 @@ def apply_symbology(
input_layer (str): The path or name of the input feature layer to which symbology will be applied.
in_symbology_layer (str): The path to the layer file (.lyrx) containing the desired symbology settings.
output_name (str): The name (including path) for the output layer file (.lyrx) with the applied symbology.
grouped_lyrx (bool, optional): If True, the symbology is applied to the entire layer group. Defaults to False.
target_layer_name (str, optional): The name of the target layer within the layer group to which symbology is applied. Defaults to None.
Example:
>>> custom_arcpy.apply_symbology_to_the_layers(
Expand All @@ -369,25 +373,62 @@ def apply_symbology(
... )
'apply_symbology_to_layers__building_polygon__n100__lyrx.lyrx file created.'
"""
arcpy.management.MakeFeatureLayer(
in_features=input_layer,
out_layer=f"{input_layer}_tmp",
)

arcpy.management.ApplySymbologyFromLayer(
in_layer=f"{input_layer}_tmp",
in_symbology_layer=in_symbology_layer,
update_symbology="MAINTAIN",
)

arcpy.management.SaveToLayerFile(
in_layer=f"{input_layer}_tmp",
out_layer=output_name,
is_relative_path="ABSOLUTE",
)

arcpy.management.Delete(
f"{input_layer}_tmp",
)

print(f"{output_name} lyrx file created.")
def apply_symbology_to_single_layer(
target_layer,
apply_symbology_layer,
created_lrx_file_name,
):
arcpy.management.MakeFeatureLayer(
in_features=target_layer,
out_layer=f"{input_layer}_tmp",
)

arcpy.management.ApplySymbologyFromLayer(
in_layer=f"{target_layer}_tmp",
in_symbology_layer=apply_symbology_layer,
update_symbology="MAINTAIN",
)

arcpy.management.SaveToLayerFile(
in_layer=f"{target_layer}_tmp",
out_layer=output_name,
is_relative_path="ABSOLUTE",
)

arcpy.management.Delete(
f"{target_layer}_tmp",
)

print(f"{created_lrx_file_name} lyrx file created.")

if not grouped_lyrx:
apply_symbology_to_single_layer(
target_layer=input_layer,
apply_symbology_layer=in_symbology_layer,
created_lrx_file_name=output_name,
)

elif grouped_lyrx and target_layer_name is None:
raise Exception("This feature has not been implemented please do not use yet")

elif grouped_lyrx and target_layer_name is not None:
group_lyrx_layer_file = arcpy.mp.LayerFile(in_symbology_layer)
listed_layers = group_lyrx_layer_file.listLayers()
symbology_layer = None

for layer in listed_layers:
if layer.name == target_layer_name:
symbology_layer = layer
print(f"Layer {target_layer_name} found in {in_symbology_layer}.")
break

if symbology_layer is None:
print(f"Layer {target_layer_name} not found in {in_symbology_layer}.")
return None

apply_symbology_to_single_layer(
target_layer=input_layer,
apply_symbology_layer=symbology_layer,
created_lrx_file_name=output_name,
)
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ def apply_symbology_to_the_layers(self):
"output_name": self.railway_stations_with_lyrx,
},
]
print(f"Features for applying symbology: {features_for_apply_symbology}\n")

# Loop over the symbology configurations and apply the function
for symbology_config in features_for_apply_symbology:
Expand Down Expand Up @@ -272,7 +273,13 @@ def barriers_for_rbc(self):
"false",
f"{self.railway_barrier_gap} Meters",
],
[
self.road_barrier_lyrx,
"false",
f"{self.road_barrier_gap} Meters",
],
]
print(f"Input barriers for RBC: {input_barriers_for_rbc}\n")

return input_barriers_for_rbc

Expand All @@ -287,6 +294,7 @@ def resolve_building_conflicts_1(self):
self.polygons_with_lyrx,
self.building_squares_with_lyrx,
]
print(f"Input buildings for RBC 1: {input_buildings_rbc_1}\n")
arcpy.cartography.ResolveBuildingConflicts(
in_buildings=input_buildings_rbc_1,
invisibility_field="invisibility",
Expand Down
86 changes: 86 additions & 0 deletions custom_tools/generalization_tools/road/resolve_road_conflicts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import arcpy
from typing import Union, List, Dict, Tuple

from custom_tools.general_tools.file_utilities import WorkFileManager
from env_setup import environment_setup
from custom_tools.general_tools import custom_arcpy
from file_manager.n100.file_manager_roads import Road_N100
from file_manager.n100.file_manager_buildings import Building_N100


class ResolveRoadConflicts:
def __init__(
self,
input_feature_file_lyrx_dict: Dict[str, List[str]],
output_road_feature: str,
output_displacement_feature: str,
root_file: str = None,
hierarchy_field: str = "hierarchy",
map_scale: str = "100000",
write_work_files_to_memory: bool = True,
keep_work_files: bool = False,
):
self.input_line_dictionary = input_feature_file_lyrx_dict
self.root_path = root_file

self.map_scale = map_scale
self.hierarchy_field = hierarchy_field

self.selection_copy = None
for feature, input_layer in self.input_line_dictionary.items():
line_feature, _ = input_layer
self.selection_copy = ""

self.work_file_manager = WorkFileManager(
unique_id=id(self),
root_file=root_file,
write_to_memory=write_work_files_to_memory,
keep_files=keep_work_files,
)

def copy_input_layers(self):
for feature, input_layer in self.input_line_dictionary.items():
line_feature, _ = input_layer
_, lyrx_feature = input_layer

feature_name = f"{self.root_path}_{feature}"
lyrx_name = f"{self.root_path}_{lyrx_feature}"
print(f"Feature feature is:\n{line_feature}")

print(f"Lyrx feature is:\n{lyrx_feature}")

def resolve_road_conflicts(self):
arcpy.cartography.ResolveRoadConflicts(
in_layers=[
Road_N100.testing_file___roads_area_lyrx___n100_road.value,
Road_N100.testing_file___railway_area_lyrx___n100_road.value,
Road_N100.testing_file___begrensningskurve_water_area_lyrx___n100_road.value,
],
hierarchy_field=self.hierarchy_field,
out_displacement_features=Road_N100.testing_file___displacement_feature_after_resolve_road_conflict___n100_road.value,
)

def run(self):
arcpy.env.referenceScale = self.map_scale
environment_setup.main()
self.resolve_road_conflicts()


if __name__ == "__main__":
# environment_setup.main()
resolve_road_conflicts = ResolveRoadConflicts(
input_feature_file_lyrx_dict={
"feature_name": [
Road_N100.testing_file___roads_area___n100_road.value,
Road_N100.testing_file___roads_area_lyrx___n100_road.value,
],
"feature_name_2": [
Road_N100.testing_file___roads_area___n100_road.value,
Road_N100.testing_file___roads_area_lyrx___n100_road.value,
],
},
root_file=Building_N100.data_preparation___root_file_line_symbology___n100_building.value,
output_road_feature=Road_N100.testing_file___roads_area_lyrx___n100_road.value,
output_displacement_feature=Road_N100.testing_file___displacement_feature_after_resolve_road_conflict___n100_road.value,
)
resolve_road_conflicts.copy_input_layers()
15 changes: 14 additions & 1 deletion file_manager/n100/file_manager_roads.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ class Road_N100(Enum):
)
)

data_selection___new_road_symbology___n100_road_lyrx = (
file_manager.generate_file_name_lyrx(
script_source_name=data_selection,
description="new_road_symbology",
)
)

data_preparation___geometry_validation___n100_road = (
file_manager.generate_file_name_gdb(
script_source_name=data_preparation,
Expand Down Expand Up @@ -168,6 +175,13 @@ class Road_N100(Enum):
)
)

data_preparation___collapse_road_detail___n100_road = (
file_manager.generate_file_name_gdb(
script_source_name=data_preparation,
description="collapse_road_detail",
)
)

data_preparation___thin_road_network_selection___n100_road = (
file_manager.generate_file_name_gdb(
script_source_name=data_preparation,
Expand Down Expand Up @@ -801,7 +815,6 @@ class Road_N100(Enum):
description="veg100_troms_m2",
)


# ========================================
# TESTING FILE
# ========================================
Expand Down
19 changes: 14 additions & 5 deletions generalization/n100/building/data_preparation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from input_data import input_n50
from input_data import input_n100
from input_data import input_other
from input_data import input_roads

# Importing custom modules
from file_manager.n100.file_manager_buildings import Building_N100
Expand Down Expand Up @@ -84,10 +85,11 @@ def data_selection():
Makes sure that the input data is never modified, and that all future I/O's use the same paths regardless if
the script is run for global data or smaller subselection for logic testing.
"""
print(input_roads.road_output_1)
input_output_file_dict = {
input_n100.BegrensningsKurve: Building_N100.data_selection___begrensningskurve_n100_input_data___n100_building.value,
input_n100.ArealdekkeFlate: Building_N100.data_selection___land_cover_n100_input_data___n100_building.value,
input_n100.VegSti: Building_N100.data_selection___road_n100_input_data___n100_building.value,
input_roads.road_output_1: Building_N100.data_selection___road_n100_input_data___n100_building.value,
input_n100.JernbaneStasjon: Building_N100.data_selection___railroad_stations_n100_input_data___n100_building.value,
input_n100.Bane: Building_N100.data_selection___railroad_tracks_n100_input_data___n100_building.value,
input_n50.ArealdekkeFlate: Building_N100.data_selection___land_cover_n50_input_data___n100_building.value,
Expand All @@ -98,10 +100,12 @@ def data_selection():
config.displacement_feature: Building_N100.data_selection___displacement_feature___n100_building.value,
}

small_local_selection = "navn IN ('Asker', 'Oslo', 'Ringerike')"

selector = StudyAreaSelector(
input_output_file_dict=input_output_file_dict,
selecting_file=input_n100.AdminFlate,
selecting_sql_expression="navn IN ('Asker', 'Oslo', 'Trondheim', 'Ringerike')",
selecting_sql_expression="navn IN ('Asker', 'Bærum', 'Drammen', 'Frogn', 'Hole', 'Holmestrand', 'Horten', 'Jevnaker', 'Kongsberg', 'Larvik', 'Lier', 'Lunner', 'Modum', 'Nesodden', 'Oslo', 'Ringerike', 'Tønsberg', 'Øvre Eiker')",
select_local=config.select_study_area,
)

Expand Down Expand Up @@ -285,15 +289,20 @@ def unsplit_roads_and_make_buffer():
Unsplits the road feature to reduce the number of objects, reducing processing time.
"""

arcpy.UnsplitLine_management(
arcpy.CopyFeatures_management(
in_features=Building_N100.data_selection___road_n100_input_data___n100_building.value,
out_feature_class=Building_N100.data_preparation___unsplit_roads___n100_building.value,
dissolve_field=["subtypekode", "motorvegtype", "uttegning"],
)
#
# arcpy.UnsplitLine_management(
# in_features=Building_N100.data_selection___road_n100_input_data___n100_building.value,
# out_feature_class=Building_N100.data_preparation___unsplit_roads___n100_building.value,
# dissolve_field=["subtypekode", "motorvegtype", "uttegning"],
# )

road_lines_to_buffer_symbology = LineToBufferSymbology(
input_road_lines=Building_N100.data_preparation___unsplit_roads___n100_building.value,
sql_selection_query=N100_SQLResources.road_symbology_size_sql_selection.value,
sql_selection_query=N100_SQLResources.new_road_symbology_size_sql_selection.value,
output_road_buffer=Building_N100.data_preparation___road_symbology_buffers___n100_building.value,
write_work_files_to_memory=False,
keep_work_files=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def resolve_building_conflicts():
],
road: [
"context",
Building_N100.data_preparation___unsplit_roads___n100_building.value,
Building_N100.data_preparation___road_symbology_buffers___n100_building.value,
],
railway: [
"context",
Expand Down Expand Up @@ -157,7 +157,7 @@ def resolve_building_conflicts():
],
road_lyrx: [
"reference",
input_symbology.SymbologyN100.road.value,
input_symbology.SymbologyN100.road_buffer.value,
],
railway_station_lyrx: [
"reference",
Expand Down Expand Up @@ -230,7 +230,7 @@ def resolve_building_conflicts():
custom_functions=[resolve_building_conflicts_config],
root_file_partition_iterator=Building_N100.point_resolve_building_conflicts___root_file___n100_building.value,
dictionary_documentation_path=Building_N100.point_resolve_building_conflicts___documentation___building_n100.value,
feature_count="100000",
feature_count="500000",
)

resolve_building_conflicts_partition_iteration.run()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def roads_and_water_barriers_500_m_from_building_polygons():

# Selecting roads 500 meters from building polygons
custom_arcpy.select_location_and_make_permanent_feature(
input_layer=Building_N100.data_preparation___unsplit_roads___n100_building.value,
input_layer=Building_N100.data_preparation___road_symbology_buffers___n100_building.value,
overlap_type=custom_arcpy.OverlapType.WITHIN_A_DISTANCE,
select_features=Building_N100.polygon_propogate_displacement___building_polygons_after_displacement___n100_building.value,
output_name=Building_N100.polygon_resolve_building_conflicts___roads_500m_from_displaced_polygon___n100_building.value,
Expand Down Expand Up @@ -154,7 +154,7 @@ def apply_symbology_to_layers():
# Applying symbology to roads
custom_arcpy.apply_symbology(
input_layer=Building_N100.polygon_resolve_building_conflicts___roads_500m_from_displaced_polygon___n100_building.value,
in_symbology_layer=input_symbology.SymbologyN100.road.value,
in_symbology_layer=input_symbology.SymbologyN100.road_buffer.value,
output_name=Building_N100.polygon_resolve_building_conflicts___roads___n100_building_lyrx.value,
)

Expand Down
Loading

0 comments on commit aedf602

Please sign in to comment.