把我做完的一个脚本完全分享给大家,包含GUI。相关黑臭水体项目的处理人员可以先用着。帮着挂属性的。
import arcpy
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
def check_coordinate_system(shapefile):
coordinate_system = arcpy.Describe(shapefile).spatialReference
return coordinate_system.type == "Geographic"
def process_shapefile(workspace, shapefile, coordinate_system_epsg=4549):
arcpy.env.workspace = workspace
original_full_path = os.path.join(workspace, shapefile)
new_shapefile_name = "BaseAttr_" + os.path.splitext(shapefile)[0] + ".shp"
your_path = os.path.join(workspace, new_shapefile_name)
arcpy.CopyFeatures_management(original_full_path, your_path)
if not check_coordinate_system(your_path):
messagebox.showerror("错误", "当前要素并非地理坐标系")
return
try:
add_fields(your_path)
add_lat_long(your_path)
calculate_area_length_width(your_path, coordinate_system_epsg)
update_type_field(your_path)
messagebox.showinfo("完成", f"所有操作已完成。生成的文件为:{your_path}")
except Exception as e:
messagebox.showerror("错误", f"处理过程中发生错误: {e}")
def add_fields(shapefile):
existing_fields = {field.name for field in arcpy.ListFields(shapefile)}
new_fields = [
("序号", "LONG"), ("ID", "LONG"), ("市级", "TEXT"), ("县级", "TEXT"),
("乡镇", "TEXT"), ("村名", "TEXT"), ("名称", "TEXT"), ("类型", "TEXT"),
("经度X", "DOUBLE"), ("纬度Y", "DOUBLE"), ("面积", "DOUBLE"),
("长度L", "DOUBLE"), ("宽度W", "DOUBLE"), ("等级", "TEXT"),
("核查", "TEXT"), ("快检", "TEXT"), ("黑臭", "TEXT"), ("污染源", "TEXT")
]
for field_name, field_type in new_fields:
if field_name not in existing_fields:
arcpy.AddField_management(shapefile, field_name, field_type)
fields_to_delete = ["Shape_Length", "Shape_Area"]
for field_name in fields_to_delete:
if field_name in existing_fields:
arcpy.DeleteField_management(shapefile, field_name)
def add_lat_long(shapefile):
with arcpy.da.UpdateCursor(shapefile, ["OID@", "Shape@", "经度X", "纬度Y"]) as cursor:
for row in cursor:
point = row[1].centroid
row[2] = point.X
row[3] = point.Y
cursor.updateRow(row)
# 凸包
def calculate_area_length_width(shapefile, epsg_code):
output_coordinate_system = arcpy.SpatialReference(epsg_code)
projected_temp_file = os.path.join(arcpy.env.workspace, "temp_projected.shp")
arcpy.Project_management(shapefile, projected_temp_file, output_coordinate_system)
with arcpy.da.UpdateCursor(projected_temp_file, ["Shape@", "面积", "长度L", "宽度W"]) as cursor:
for row in cursor:
row[1] = row[0].getArea("PLANAR", "SQUAREMETERS")
geom = row[0]
convex_hull = geom.convexHull()
extent = convex_hull.extent
length = extent.XMax - extent.XMin
width = extent.YMax - extent.YMin
row[2] = max(length, width)
row[3] = min(length, width)
cursor.updateRow(row)
arcpy.Delete_management(shapefile)
arcpy.Rename_management(projected_temp_file, shapefile)
def update_type_field(shapefile):
with arcpy.da.UpdateCursor(shapefile, ["Shape@", "长度L", "宽度W", "类型"]) as cursor:
for row in cursor:
geometry = row[0]
length, width = row[1], row[2]
area = geometry.getArea("PLANAR", "SQUAREMETERS")
perimeter = geometry.length
compactness = (4 * 3.14159 * area) / (perimeter ** 2)
if compactness > 0.31: # 紧凑度越接近1,越圆
row[3] = "坑塘"
else:
row[3] = "沟渠"
cursor.updateRow(row)
# GUI Functions
def select_workspace():
path = filedialog.askdirectory()
workspace_entry.delete(0, tk.END)
workspace_entry.insert(0, path)
def select_shapefile():
file_path = filedialog.askopenfilename(filetypes=[("Shapefiles", "*.shp")])
shapefile_entry.delete(0, tk.END)
shapefile_entry.insert(0, os.path.basename(file_path))
def run_process():
workspace = workspace_entry.get()
shapefile = shapefile_entry.get()
if not workspace or not shapefile:
messagebox.showwarning("输入错误", "请选择工作区路径和Shapefile文件。")
return
process_shapefile(workspace, shapefile)
def black_water_gui():
global workspace_entry, shapefile_entry
sub_root = tk.Toplevel()
sub_root.title("黑臭水体治理项目")
sub_root.geometry("700x400")
sub_root.configure(bg='#f0f0f0')
title_frame = tk.Frame(sub_root, bg='#f0f0f0')
title_frame.pack(pady=10)
title_label = tk.Label(title_frame, text="黑臭水体解译程序", font=("Microsoft YaHei", 20, "bold"), bg='#f0f0f0')
title_label.pack()
main_frame = tk.Frame(sub_root, padx=20, pady=20, bg='#f0f0f0')
main_frame.pack(pady=20)
tk.Label(main_frame, text="选择工作区路径:", font=("Microsoft YaHei", 12), bg='#f0f0f0').grid(row=0, column=0, padx=10, pady=10, sticky='w')
workspace_entry = tk.Entry(main_frame, width=40, font=("Microsoft YaHei", 12))
workspace_entry.grid(row=0, column=1, padx=10, pady=10)
tk.Button(main_frame, text="选择路径", command=select_workspace, font=("Microsoft YaHei", 12), bg='#4CAF50', fg='white').grid(row=0, column=2, padx=10, pady=10)
tk.Label(main_frame, text="选择Shapefile文件:", font=("Microsoft YaHei", 12), bg='#f0f0f0').grid(row=1, column=0, padx=10, pady=10, sticky='w')
shapefile_entry = tk.Entry(main_frame, width=40, font=("Microsoft YaHei", 12))
shapefile_entry.grid(row=1, column=1, padx=10, pady=10)
tk.Button(main_frame, text="选择文件", command=select_shapefile, font=("Microsoft YaHei", 12), bg='#4CAF50', fg='white').grid(row=1, column=2, padx=10, pady=10)
run_button = tk.Button(main_frame, text="运行", command=run_process, font=("Microsoft YaHei", 14, "bold"), bg='#FF5722', fg='white', width=15)
run_button.grid(row=2, column=1, pady=20)
footer_frame = tk.Frame(sub_root, bg='#f0f0f0')
footer_frame.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=10)
copyright_label = tk.Label(footer_frame, text="© 唐山市环境规划科学研究院—双碳中心", font=("Microsoft YaHei", 10), fg='#888888', bg='#f0f0f0')
copyright_label.pack(anchor='e')
sub_root.update_idletasks()
screen_width = sub_root.winfo_screenwidth()
screen_height = sub_root.winfo_screenheight()
x = (screen_width - sub_root.winfo_width()) // 2
y = (screen_height - sub_root.winfo_height()) // 2
sub_root.geometry(f"+{x}+{y}")
# Main GUI Code
root = tk.Tk()
root.title("唐山市环境规划科学研究院-双碳研究中心")
root.geometry("500x300")
root.configure(bg='#f0f0f0')
title_frame = tk.Frame(root, bg='#f0f0f0')
title_frame.pack(pady=10)
title_label = tk.Label(title_frame, text="双碳研究中心自动化工作台", font=("Microsoft YaHei", 20, "bold"), bg='#f0f0f0')
title_label.pack()
button_frame = tk.Frame(root, bg='#f0f0f0')
button_frame.pack(pady=20)
def show_unlock_message():
messagebox.showinfo("功能需要联系我", "联系moonless0222@gmail.com")
style = ttk.Style()
style.configure("TButton", padding=5, relief="raised", background="#4CAF50", foreground="black")
style.map("TButton", background=[("active", "#3e8e41"), ("disabled", "#a2a2a2")], foreground=[("active", "blue"), ("disabled", "grey")])
buttons = [
("黑臭水体", black_water_gui),
("数据处理", show_unlock_message),
("深度学习", show_unlock_message),
("后续项目", show_unlock_message),
("后续项目", show_unlock_message),
("后续项目", show_unlock_message),
("后续项目", show_unlock_message),
("后续项目", show_unlock_message),
("后续项目", show_unlock_message)
]
for i, (text, command) in enumerate(buttons):
row = i // 3
col = i % 3
btn = ttk.Button(button_frame, text=text, command=command, style="TButton")
btn.grid(row=row, column=col, padx=15, pady=15, sticky="nsew")
for i in range(3):
button_frame.grid_rowconfigure(i, weight=1)
button_frame.grid_columnconfigure(i, weight=1)
root.update_idletasks()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width - root.winfo_width()) // 2
y = (screen_height - root.winfo_height()) // 2
root.geometry(f"+{x}+{y}")
root.mainloop()