Hello,
I am working on a scrip that create 2 aprx files ( by copying an existing one then change their names) and after that plot the shapefiles from 2 different gdb's to the corresponding aprx file and after that apply the symbology.
Is there a way I can do that in one script (running the code in Pyscripter not within the ArcGIS pro)
The scrip I created can copy the features to the gdb's, change their names and copy and rename the aprx files but when I open the aprx file it's empty with no layers inside it.
Note: When I run it in Arc GIS Pro it show the shapefiles and copy the symbology but in this case it do it in a different aprx file not the targeted one.
import arcpy
import os
import shutil
# Enable overwriting
arcpy.env.overwriteOutput = True
# Define the source folder and area name
source_folder = r'C:\Users\HusamOqer\Desktop\2D 3D script\PROJECTAREA37\FinalDelivery' # Update this with your source folder path
Area_Name = "Dorset_"
empty_project_path = os.path.join(source_folder, 'Symbology', 'Project.aprx')
# Function to copy and rename the project file
def copy_and_rename_project(original_path, new_folder, new_name):
new_path = os.path.join(new_folder, f'{new_name}.aprx')
shutil.copyfile(original_path, new_path)
return new_path
# Copy and rename the project file for 2D
aprx_2d_path = copy_and_rename_project(empty_project_path, os.path.join(source_folder, 'Geodatabase_2D'), Area_Name + '2D')
# Copy and rename the project file for 3D
aprx_3d_path = copy_and_rename_project(empty_project_path, os.path.join(source_folder, 'Geodatabase_3D'), Area_Name + '3D')
# Define paths
folder_2d_path = os.path.join(source_folder, 'SHPrenamed_2D')
folder_3d_path = os.path.join(source_folder, 'SHPrenamed_3D')
destination_gdb_2D = os.path.join(source_folder, 'Geodatabase_2D', Area_Name + '2D.gdb')
destination_gdb_3D = os.path.join(source_folder, 'Geodatabase_3D', Area_Name + '3D.gdb')
Symbology = os.path.join(source_folder, "Symbology")
# Function to import shapefiles into the specified geodatabase
def import_shapefiles(source, destination_gdb):
arcpy.env.workspace = destination_gdb
# Ensure the destination geodatabase exists
if not arcpy.Exists(destination_gdb):
arcpy.CreateFileGDB_management(os.path.dirname(destination_gdb), os.path.basename(destination_gdb))
for root, dirs, files in os.walk(source):
for file in files:
if file.lower().endswith('.shp'):
source_shapefile = os.path.join(root, file)
feature_class_name = os.path.splitext(file)[0]
# Ensure the output feature class does not already exist
output_feature_class = os.path.join(destination_gdb, feature_class_name)
if not arcpy.Exists(output_feature_class):
arcpy.FeatureClassToGeodatabase_conversion(source_shapefile, destination_gdb)
print(f"Imported {file} into {destination_gdb}/{feature_class_name}")
else:
print(f"Skipped {file} - Feature class already exists in {destination_gdb}")
# Import shapefiles from SHPrenamed_3D to Geodatabase_3D
import_shapefiles(folder_3d_path, destination_gdb_3D)
# Import shapefiles from SHPrenamed_2D to Geodatabase_2D
import_shapefiles(folder_2d_path, destination_gdb_2D)
# Rename the 3D geodatabase
new_destination_gdb_3D = os.path.join(os.path.dirname(destination_gdb_3D), Area_Name + '3D.gdb')
if not arcpy.Exists(new_destination_gdb_3D):
arcpy.management.Rename(destination_gdb_3D, new_destination_gdb_3D)
else:
print(f"The destination geodatabase {new_destination_gdb_3D} already exists. Skipping rename.")
# Rename the 2D geodatabase
new_destination_gdb_2D = os.path.join(os.path.dirname(destination_gdb_2D), Area_Name + '2D.gdb')
if not arcpy.Exists(new_destination_gdb_2D):
arcpy.management.Rename(destination_gdb_2D, new_destination_gdb_2D)
else:
print(f"The destination geodatabase {new_destination_gdb_2D} already exists. Skipping rename.")
# Function to add layers from a geodatabase to a map
def add_layers_to_map(aprx_path, gdb_path, symbology_folder, suffix):
aprx = arcpy.mp.ArcGISProject(aprx_path)
map_obj = aprx.listMaps()[0]
# Loop through the feature classes in the geodatabase
for dirpath, dirnames, filenames in arcpy.da.Walk(gdb_path, datatype="FeatureClass"):
for filename in filenames:
layerfile = os.path.join(dirpath, filename)
if filename == "PoleIDAnno":
temp_layer = "PoleIDAnno"
arcpy.management.MakeFeatureLayer(layerfile, temp_layer)
addlayer = os.path.abspath(temp_layer)
else:
addlayer = os.path.abspath(layerfile)
map_obj.addDataFromPath(addlayer)
# Loop through the .lyr and .lyrx files in the symbology folder
for file in os.listdir(symbology_folder):
if file.endswith((".lyr", ".lyrx")):
lyr_path = os.path.join(symbology_folder, file)
lyr_name = os.path.splitext(file)[0]
# Check if the .lyr or .lyrx file name matches any layer name in the map
for lyr in map_obj.listLayers():
if lyr_name in lyr.name and lyr.name.endswith(suffix): # Apply symbology only if the layer ends with suffix
print(f"Applying symbology from {lyr_path} to layer {lyr.name}")
arcpy.management.ApplySymbologyFromLayer(lyr, lyr_path)
print("Symbology applied!")
break # Exit loop after finding a match
# Save changes to the ArcGIS Pro project
aprx.save()
# Add layers and apply symbology to the 2D project
add_layers_to_map(aprx_2d_path, new_destination_gdb_2D, Symbology, '_2D')
# Add layers and apply symbology to the 3D project
add_layers_to_map(aprx_3d_path, new_destination_gdb_3D, Symbology, '_3D')
# Cleanup unnecessary geodatabases
def cleanup_geodatabases(source_folder):
for folder_name in ['Geodatabase_2D', 'Geodatabase_3D']:
full_folder_path = os.path.join(source_folder, folder_name)
for gdb_name in os.listdir(full_folder_path):
gdb_path = os.path.join(full_folder_path, gdb_name)
# Check if the gdb_name starts with the correct Area_Name
if gdb_name.startswith(Area_Name):
print(f"Keeping geodatabase: {gdb_path}")
else:
print(f"Deleting unnecessary geodatabase: {gdb_path}")
arcpy.management.Delete(gdb_path)
# Run cleanup
cleanup_geodatabases(source_folder)