Source code for generalization.n100.building.calculate_point_values

# Importing custom files relative to the root path
from custom_tools.general_tools import custom_arcpy
from env_setup import environment_setup
from file_manager.n100.file_manager_buildings import Building_N100
from constants.n100_constants import N100_SQLResources

# Importing general packages
import arcpy
from collections import Counter

# Importing timing decorator
from custom_tools.decorators.timing_decorator import timing_decorator


[docs] @timing_decorator def main(): """ What: Adds required fields for building point for symbology and resolves building conflicts: angle, hierarchy, and invisibility. How: reclassifying_hospital_and_church_points_from_matrikkel: Reclassifies hospitals and churches in the matrikkel dataset to a new NBR value ("Other buildings" / "Andre bygg"). adding_original_source_to_points: Adds a field to point features to indicate their original source: `0` for points from merged sources and `1` for points resulting from building polygons. merge_matrikkel_n50_touristcabins_with_points_from_grunnriss: Merges points from the `matrikkel_n50_touristcabins` dataset with points created from building polygons. Adds a field to the merged points to determine and assign a symbol value based on their NBR code. find_undefined_nbr_values: Selects building points with an undefined NBR value (symbol value of -99) from the dataset, and logs it. Then reclassify their NBR values and symbol_val values. calculate_angle_and_visibility: Adds angle and visibility fields, and sets their value to 0 calculate_hierarchy: Calculates the hierarchy field based on symbol_val values Why: A lot of field values is required in future processing, this makes sure that all fields are added and populated with the required values. """ """ Summary: Adds required fields for building point for symbology and resolves building conflicts: angle, hierarchy, and invisibility. """ environment_setup.main() reclassifying_hospital_and_church_points_from_matrikkel() adding_original_source_to_points() merge_matrikkel_n50_touristcabins_with_points_from_grunnriss() find_undefined_nbr_values() calculate_angle_and_visibility() calculate_hierarchy()
[docs] @timing_decorator def reclassifying_hospital_and_church_points_from_matrikkel(): """ Reclassifies hospitals and churches in the matrikkel dataset to a new NBR value ("Other buildings" / "Andre bygg"). """ # Reclassify hospitals and churches from matrikken to another NBR value ("Other buildings" / "Andre bygg") code_block_hospital_church = ( "def reclassify(nbr):\n" " mapping = {970: 729, 719: 729, 671: 729}\n" " return mapping.get(nbr, nbr)" ) arcpy.CalculateField_management( in_table=Building_N100.data_preparation___matrikkel_points___n100_building.value, field="byggtyp_nbr", expression="reclassify(!byggtyp_nbr!)", expression_type="PYTHON3", code_block=code_block_hospital_church, )
[docs] @timing_decorator def adding_original_source_to_points(): """ Adds a field to point features to indicate their original source: `0` for points from merged sources and `1` for points resulting from building polygons. """ # Adding a field to indicate that the merged building point and matrikkel does not come from building_polygon arcpy.AddField_management( in_table=Building_N100.data_preparation___merged_building_points___n100_building.value, field_name="building_polygon", field_type="LONG", ) arcpy.CalculateField_management( in_table=Building_N100.data_preparation___merged_building_points___n100_building.value, field="building_polygon", expression="0", ) # Adding a field to indicate that points resulting from building_polygon is tracked arcpy.AddField_management( in_table=Building_N100.polygon_to_point___merged_points_final___n100_building.value, field_name="building_polygon", field_type="LONG", ) arcpy.CalculateField_management( in_table=Building_N100.polygon_to_point___merged_points_final___n100_building.value, field="building_polygon", expression="1", )
[docs] @timing_decorator def merge_matrikkel_n50_touristcabins_with_points_from_grunnriss(): """ Merges points from the `matrikkel_n50_touristcabins` dataset with points created from building polygons. Adds a field to the merged points to determine and assign a symbol value based on their NBR code. """ # Merge the merged building point from n50 and matrikkel with points created from building_polygon arcpy.management.Merge( inputs=[ Building_N100.data_preparation___merged_building_points___n100_building.value, Building_N100.polygon_to_point___merged_points_final___n100_building.value, ], output=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, ) arcpy.AddField_management( in_table=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, field_name="symbol_val", field_type="SHORT", ) # Determining and assigning symbol val arcpy.CalculateField_management( in_table=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, field="symbol_val", expression="determineVal(!byggtyp_nbr!)", expression_type="PYTHON3", code_block=N100_SQLResources.nbr_symbol_val_code_block.value, )
[docs] @timing_decorator def find_undefined_nbr_values(): """ Selects building points with an undefined NBR value (symbol value of -99) from the dataset, and logs it. Then reclassify their NBR values and symbol_val values. """ custom_arcpy.select_attribute_and_make_feature_layer( input_layer=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, expression="symbol_val = -99", output_name=Building_N100.calculate_point_values___selection_building_points_with_undefined_nbr_values___n100_building.value, ) # Counter to store the count of each unique byggtyp_nbr nbr_counter = Counter() # Iterate over the rows in the feature class with arcpy.da.SearchCursor( Building_N100.calculate_point_values___selection_building_points_with_undefined_nbr_values___n100_building.value, ["byggtyp_nbr", "symbol_val"], ) as cursor: for nbr, symbol_val in cursor: if symbol_val == -99: nbr_counter[nbr] += 1 # Calculate the total count total_count = sum(nbr_counter.values()) # Writing the counts to a log file with open( Building_N100.calculate_point_values___building_points_with_undefined_nbr_values___n100_building.value, "w", ) as log_file: for nbr, count in nbr_counter.items(): log_file.write(f"byggtyp_nbr: {nbr}, Count: {count}\n") # Write the total count at the end log_file.write(f"Total Rows without defined symbology: {total_count}\n") print( f"Log file created at: {Building_N100.calculate_point_values___building_points_with_undefined_nbr_values___n100_building.value}" ) # Code block to transform byggtyp_nbr values without symbology to other buildings (729) code_block_symbol_val_to_nbr = ( "def symbol_val_to_nbr(symbol_val, byggtyp_nbr):\n" " if symbol_val == -99:\n" " return 729\n" " return byggtyp_nbr" ) # Code block to update the symbol_val to reflect the new byggtyp_nbr code_block_update_symbol_val = ( "def update_symbol_val(symbol_val):\n" " if symbol_val == -99:\n" " return 8\n" " return symbol_val" ) # Applying the symbol_val_to_nbr logic arcpy.CalculateField_management( in_table=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, field="byggtyp_nbr", expression="symbol_val_to_nbr(!symbol_val!, !byggtyp_nbr!)", expression_type="PYTHON3", code_block=code_block_symbol_val_to_nbr, ) # Applying the update_symbol_val logic arcpy.CalculateField_management( in_table=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, field="symbol_val", expression="update_symbol_val(!symbol_val!)", expression_type="PYTHON3", code_block=code_block_update_symbol_val, )
[docs] @timing_decorator def calculate_angle_and_visibility(): """ Adds angle and visibility fields, and sets their value to 0 """ # Feature class to check fields existence point_feature_class = ( Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value ) # List of fields to add and calculate fields_to_add = [["angle", "LONG"], ["invisibility", "LONG"]] fields_to_calculate = [["angle", "0"], ["invisibility", "0"]] # Check if the fields exist in the feature class existing_fields = [field.name for field in arcpy.ListFields(point_feature_class)] # Add fields if they don't exist for field_name, field_type in fields_to_add: if field_name not in existing_fields: arcpy.AddField_management(point_feature_class, field_name, field_type) # Calculate values for each field for field_name, field_value in fields_to_calculate: arcpy.management.CalculateField( in_table=point_feature_class, field=field_name, expression=field_value, expression_type="PYTHON3", )
[docs] @timing_decorator def calculate_hierarchy(): """ Calculates the hierarchy field based on symbol_val values """ # Then run CalculateField with the new code block arcpy.management.CalculateField( in_table=Building_N100.calculate_point_values___points_going_into_propagate_displacement___n100_building.value, field="hierarchy", expression="determineHierarchy(!symbol_val!)", expression_type="PYTHON3", code_block=N100_SQLResources.symbol_val_to_hierarchy.value, )
if __name__ == "__main__": main()