# Importing packages
import arcpy
import os
from custom_tools.general_tools.study_area_selector import StudyAreaSelector
# Importing custom input files modules
from input_data import input_n50
from input_data import input_n100
from input_data import input_other
# Importing custom modules
from file_manager.n100.file_manager_roads import Road_N100
from env_setup import environment_setup
import config
from custom_tools.decorators.timing_decorator import timing_decorator
from custom_tools.general_tools import custom_arcpy
[docs]
def main():
environment_setup.main()
selecting_paths_and_nvdb_roads_in_studyarea()
merge_n50_and_nvdb()
multipart_to_singlepart()
merge_divided_roads()
thin_road_network_1()
collapse_road_detail()
thin_road_network_2()
thin_road_network_3()
spatial_join_between_functional_roadclass_and_roads()
calculate_new_hierarchy_based_on_functional_road_class()
thin_road_network_4()
remove_rundkjoring_that_survived_collapse_road_detail()
[docs]
@timing_decorator
def selecting_paths_and_nvdb_roads_in_studyarea():
selector = StudyAreaSelector(
input_output_file_dict={
Road_N100.data_preperation___paths_n50_with_calculated_fields___n100_road.value: Road_N100.first_generalization___paths_in_study_area___n100_road.value,
Road_N100.data_preperation___selecting_everything_but_rampe_with_calculated_fields_nvdb___n100_road.value: Road_N100.first_generalization____nvdb_roads_in_study_area___n100_road.value,
config.path_to_functional_road_class: Road_N100.data_preperation___functional_road_class_dataset___n100_road.value,
},
selecting_file=input_n100.AdminFlate,
selecting_sql_expression="navn IN ('Oslo')",
select_local=config.select_study_area,
)
selector.run()
[docs]
@timing_decorator
def merge_n50_and_nvdb():
# Merging paths and nvdb roads
arcpy.management.Merge(
inputs=[
Road_N100.first_generalization___paths_in_study_area___n100_road.value,
Road_N100.first_generalization____nvdb_roads_in_study_area___n100_road.value,
],
output=Road_N100.first_generalization____merged_roads_and_paths___n100_road.value,
)
[docs]
@timing_decorator
def multipart_to_singlepart():
arcpy.management.MultipartToSinglepart(
in_features=Road_N100.first_generalization____merged_roads_and_paths___n100_road.value,
out_feature_class=Road_N100.first_generalization____multipart_to_singlepart___n100_road.value,
)
[docs]
@timing_decorator
def merge_divided_roads():
# Execute Merge Divided Roads
arcpy.cartography.MergeDividedRoads(
in_features=Road_N100.first_generalization____multipart_to_singlepart___n100_road.value,
merge_field="VEGNUMMER",
merge_distance="50 Meters",
out_features=Road_N100.first_generalization____merge_divided_roads_features___n100_road.value,
out_displacement_features=Road_N100.first_generalization____merge_divided_roads_displacement_feature___n100_road.value,
character_field="characters",
)
[docs]
@timing_decorator
def thin_road_network_1():
arcpy.cartography.ThinRoadNetwork(
in_features=Road_N100.first_generalization____merge_divided_roads_features___n100_road.value,
minimum_length="500 Meters",
invisibility_field="invisibility_1",
hierarchy_field="hierarchy",
)
custom_arcpy.select_attribute_and_make_permanent_feature(
input_layer=Road_N100.first_generalization____merge_divided_roads_features___n100_road.value,
expression="invisibility_1 = 0",
output_name=Road_N100.first_generalization____visible_features_after_thin_road_network_1___n100_road.value,
selection_type=custom_arcpy.SelectionType.NEW_SELECTION,
)
[docs]
@timing_decorator
def collapse_road_detail():
arcpy.cartography.CollapseRoadDetail(
in_features=Road_N100.first_generalization____visible_features_after_thin_road_network_1___n100_road.value,
collapse_distance="90 Meters",
output_feature_class=Road_N100.first_generalization____collapse_road_detail___n100_road.value,
)
[docs]
@timing_decorator
def thin_road_network_2():
arcpy.cartography.ThinRoadNetwork(
in_features=Road_N100.first_generalization____collapse_road_detail___n100_road.value,
minimum_length="1000 Meters",
invisibility_field="invisibility_2",
hierarchy_field="hierarchy",
)
custom_arcpy.select_attribute_and_make_permanent_feature(
input_layer=Road_N100.first_generalization____collapse_road_detail___n100_road.value,
expression="invisibility_2 = 0",
output_name=Road_N100.first_generalization____visible_features_after_thin_road_network_2___n100_road.value,
selection_type=custom_arcpy.SelectionType.NEW_SELECTION,
)
[docs]
@timing_decorator
def thin_road_network_3():
arcpy.cartography.ThinRoadNetwork(
in_features=Road_N100.first_generalization____visible_features_after_thin_road_network_2___n100_road.value,
minimum_length="2000 Meters",
invisibility_field="invisibility_3",
hierarchy_field="hierarchy",
)
custom_arcpy.select_attribute_and_make_permanent_feature(
input_layer=Road_N100.first_generalization____visible_features_after_thin_road_network_2___n100_road.value,
expression="invisibility_3 = 0",
output_name=Road_N100.first_generalization____visible_features_after_thin_road_network_3___n100_road.value,
selection_type=custom_arcpy.SelectionType.NEW_SELECTION,
)
arcpy.management.CopyFeatures(
in_features=Road_N100.first_generalization____visible_features_after_thin_road_network_3___n100_road.value,
out_feature_class=Road_N100.data_preperation___going_into_spatial_join___n100_road.value,
)
[docs]
@timing_decorator
def spatial_join_between_functional_roadclass_and_roads():
# Create FieldMappings and FieldMap objects
field_mappings = arcpy.FieldMappings()
# Add all fields from the target features
field_mappings.addTable(
Road_N100.data_preperation___going_into_spatial_join___n100_road.value
)
# Create a FieldMap object for the VEGKLASSE field from join features
vegklasse_field_map = arcpy.FieldMap()
vegklasse_field_map.addInputField(
Road_N100.data_preperation___functional_road_class_dataset___n100_road.value,
"VEGKLASSE",
)
# Rename the field in case of conflicts or to ensure proper naming in output
output_field = vegklasse_field_map.outputField
output_field.name = "VEGKLASSE"
vegklasse_field_map.outputField = output_field
# Add the VEGKLASSE FieldMap to the FieldMappings
field_mappings.addFieldMap(vegklasse_field_map)
# Perform the Spatial Join with the custom FieldMappings
arcpy.analysis.SpatialJoin(
target_features=Road_N100.data_preperation___going_into_spatial_join___n100_road.value,
join_features=Road_N100.data_preperation___functional_road_class_dataset___n100_road.value,
out_feature_class=Road_N100.data_preperation___spatial_join_completed___n100_road.value,
join_operation="JOIN_ONE_TO_MANY",
join_type="KEEP_ALL",
field_mapping=field_mappings,
match_option="SHARE_A_LINE_SEGMENT_WITH",
)
"""
if vegklasse in ['0', '1']:
return 0
elif vegklasse in ['2', '3']:
return 1
elif vegklasse in ['4', '5']:
return 2
elif vegklasse == '6':
return 3
elif vegklasse == '7':
return 4
elif vegklasse in ['8', '9']:
return 5
elif vegklasse is None:
return 6"""
[docs]
@timing_decorator
def calculate_new_hierarchy_based_on_functional_road_class():
assign_hierarchy_based_on_functional_road_class = """
def Reclass(vegklasse):
if vegklasse == '0':
return 0
elif vegklasse == '1':
return 1
elif vegklasse == '2':
return 2
elif vegklasse == '3':
return 3
elif vegklasse == '4':
return 4
elif vegklasse == '5':
return 5
elif vegklasse == '6':
return 6
elif vegklasse == '7':
return 7
elif vegklasse == '8':
return 8
elif vegklasse == '9':
return 9
elif vegklasse is None:
return 10
"""
arcpy.management.AddField(
in_table=Road_N100.data_preperation___spatial_join_completed___n100_road.value,
field_name="functional_hierarchy",
field_type="SHORT",
)
arcpy.management.CalculateField(
in_table=Road_N100.data_preperation___spatial_join_completed___n100_road.value,
field="functional_hierarchy",
expression="Reclass(!VEGKLASSE!)",
expression_type="PYTHON3",
code_block=assign_hierarchy_based_on_functional_road_class,
)
[docs]
@timing_decorator
def thin_road_network_4():
arcpy.cartography.ThinRoadNetwork(
in_features=Road_N100.data_preperation___spatial_join_completed___n100_road.value,
minimum_length="2000 Meters",
invisibility_field="invisibility_4",
hierarchy_field="functional_hierarchy",
)
custom_arcpy.select_attribute_and_make_permanent_feature(
input_layer=Road_N100.data_preperation___spatial_join_completed___n100_road.value,
expression="invisibility_4 = 0",
output_name=Road_N100.first_generalization____visible_features_after_thin_road_network_4___n100_road.value,
selection_type=custom_arcpy.SelectionType.NEW_SELECTION,
)
[docs]
@timing_decorator
def remove_rundkjoring_that_survived_collapse_road_detail():
print("Starting the removal process for rundkjoring that survived collapse...")
# Select only rundkjoring parts
print("Selecting rundkjoring parts...")
custom_arcpy.select_attribute_and_make_permanent_feature(
input_layer=Road_N100.first_generalization____visible_features_after_thin_road_network_4___n100_road.value,
expression="TYPEVEG = 'rundkjøring'",
output_name=Road_N100.first_generalization____selecting_rundkjoring___n100_road.value,
selection_type=custom_arcpy.SelectionType.NEW_SELECTION,
)
print("Rundkjoring parts selected.")
# Dissolving rundkjoring features
print("Dissolving rundkjoring features...")
arcpy.management.Dissolve(
in_features=Road_N100.first_generalization____selecting_rundkjoring___n100_road.value,
out_feature_class=Road_N100.first_generalization____dissolving_rundkjoring___n100_road.value,
dissolve_field="TYPEVEG",
)
print("Rundkjoring features dissolved.")
# Selecting all road parts except for rundkjoring
print("Selecting all road parts except for rundkjoring...")
custom_arcpy.select_attribute_and_make_permanent_feature(
input_layer=Road_N100.data_preperation___spatial_join_completed___n100_road.value,
expression="TYPEVEG = 'rundkjøring'",
output_name=Road_N100.first_generalization____selecting_all_road_parts_except_rundkjoring___n100_road.value,
selection_type=custom_arcpy.SelectionType.NEW_SELECTION,
inverted=True,
)
print("All road parts except rundkjoring selected.")
# Copying the road class so no changes are made to the original
print("Copying the road feature class...")
arcpy.management.CopyFeatures(
in_features=Road_N100.first_generalization____selecting_all_road_parts_except_rundkjoring___n100_road.value,
out_feature_class=Road_N100.first_generalization____roads_going_into_extend_line___n100_road.value,
)
print("Road feature class copied.")
"""
arcpy.analysis.PairwiseBuffer(
in_features=Road_N100.first_generalization____dissolving_rundkjoring___n100_road.value,
out_feature_class=Road_N100.first_generalization____rundkjoring_buffer___n100_road.value,
buffer_distance_or_field="25 Meter",
dissolve_option="ALL",
)
arcpy.management.MultipartToSinglepart(
in_features=Road_N100.first_generalization____rundkjoring_buffer___n100_road.value,
out_feature_class=Road_N100.first_generalization____rundkjoring_buffer_multipart_to_singlepart___n100_road.value,
)
# Using the newly created polygons to create a point in the centroid
print("Converting polygons to points at centroid...")
arcpy.management.FeatureToPoint(
in_features=Road_N100.first_generalization____rundkjoring_buffer_multipart_to_singlepart___n100_road.value,
out_feature_class=Road_N100.first_generalization____feature_to_point___n100_road.value,
point_location="INSIDE",
)
# Copy the snapped road features
print("Copying snapped road features...")
arcpy.management.CopyFeatures(
in_features=Road_N100.first_generalization____roads_going_into_extend_line___n100_road.value,
out_feature_class=Road_N100.first_generalization____roads_after_snap___n100_road.value,
)
print("Snapped road features copied.")
print("Process completed.")
arcpy.edit.ExtendLine(
in_features=Road_N100.first_generalization____roads_going_into_extend_line___n100_road.value,
length="30 Meters",
extend_to=Road_N100.first_generalization____feature_to_point___n100_road.value,
)
# Create a new polygon feature class
print("Creating a new polygon feature class...")
out_path, out_name = os.path.split(
Road_N100.first_generalization____polygon_created_from_line___n100_road.value
)
arcpy.CreateFeatureclass_management(
out_path=out_path,
out_name=out_name,
geometry_type="POLYGON",
spatial_reference=Road_N100.first_generalization____dissolving_rundkjoring___n100_road.value,
)
print(f"New polygon feature class created: {os.path.join(out_path, out_name)}")
# Creating polygons from rundkjoring lines
print("Creating polygons from rundkjoring lines...")
with arcpy.da.InsertCursor(
Road_N100.first_generalization____polygon_created_from_line___n100_road.value,
["SHAPE@"],
) as cursor:
with arcpy.da.SearchCursor(
Road_N100.first_generalization____dissolving_rundkjoring___n100_road.value,
["SHAPE@"],
) as search_cursor:
for row in search_cursor:
line_geometry = row[0]
# Create a polygon from the line
polygon = arcpy.Polygon(line_geometry.getPart(0))
cursor.insertRow([polygon])
print("Polygons created from rundkjoring lines.")
print("Polygons converted to points.")
"""
if __name__ == "__main__":
main()