You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用Python扩展徕卡P40扫描目标程序:从Excel匹配坐标写入TXT

解决方案技术方向与实现代码

核心思路

用pandas库实现类VLOOKUP的坐标匹配功能,把现有代码生成的格式化目标名和CSV/XLSX中的坐标数据关联,最终输出带坐标的TXT文件。同时优化原代码中目标名格式化的逻辑,用正则表达式替代冗余的条件判断,提升代码健壮性。

步骤拆解与实现

1. 安装依赖库

需要pandas处理表格数据,读取XLSX文件还需openpyxl:

pip install pandas openpyxl

2. 优化目标名格式化逻辑

针对控制点格式LL.LLNN.L(n/x),用正则匹配替代多分支判断,更简洁准确:

import re

def format_target_name(raw_name):
    # 截取文件名前半部分(去掉末尾9位)
    target = raw_name[:-9]
    # 正则匹配无分隔符的控制点名称,补全标准分隔符
    pattern = r'^([A-Za-z]{2})([A-Za-z]{2})(\d{2})([A-Za-z])([nx]?)$'
    match = re.match(pattern, target)
    if match:
        parts = match.groups()
        # 拼接成标准格式:LL.LLNN.L(n/x)
        formatted = f"{parts[0]}.{parts[1]}{parts[2]}.{parts[3]}{parts[4]}"
        return formatted
    return target  # 匹配失败则返回原处理后的名称

3. 读取坐标文件并匹配

用pandas加载CSV/XLSX,以目标名为键做左连接(保留所有提取的目标名,匹配不到坐标则显示空值):

import pandas as pd

def load_coords(coords_path):
    # 根据文件后缀选择读取方式
    if coords_path.endswith('.xlsx'):
        df = pd.read_excel(coords_path, dtype={'控制点名称': str})  # 强制名称为字符串,避免数字转换导致匹配失败
    elif coords_path.endswith('.csv'):
        df = pd.read_csv(coords_path, dtype={'控制点名称': str})
    else:
        raise ValueError("仅支持CSV/XLSX格式的坐标文件")
    # 假设坐标文件列名为:控制点名称, X, Y, Z,需根据实际修改
    return df[['控制点名称', 'X', 'Y', 'Z']]

def match_targets_with_coords(targets_list, coords_df):
    # 将目标名列表转为DataFrame
    targets_df = pd.DataFrame({'控制点名称': targets_list})
    # 左连接实现类VLOOKUP精确匹配
    merged_df = pd.merge(targets_df, coords_df, on='控制点名称', how='left')
    return merged_df

4. 写入带坐标的TXT文件

将匹配结果按目标名,X,Y,Z格式写入文件,空坐标用NA标记:

def write_targets_with_coords(merged_df, output_path):
    with open(output_path, 'w', encoding='utf-8') as f:
        # 写入表头(可选,若不需要可删除)
        f.write("控制点名称,X,Y,Z\n")
        for _, row in merged_df.iterrows():
            target = row['控制点名称']
            x = row['X'] if pd.notna(row['X']) else 'NA'
            y = row['Y'] if pd.notna(row['Y']) else 'NA'
            z = row['Z'] if pd.notna(row['Z']) else 'NA'
            f.write(f"{target},{x},{y},{z}\n")

完整整合代码

import os
import re
import pandas as pd

def format_target_name(raw_name):
    target = raw_name[:-9]
    pattern = r'^([A-Za-z]{2})([A-Za-z]{2})(\d{2})([A-Za-z])([nx]?)$'
    match = re.match(pattern, target)
    if match:
        parts = match.groups()
        formatted = f"{parts[0]}.{parts[1]}{parts[2]}.{parts[3]}{parts[4]}"
        return formatted
    return target

def load_coords(coords_path):
    if coords_path.endswith('.xlsx'):
        df = pd.read_excel(coords_path, dtype={'控制点名称': str})
    elif coords_path.endswith('.csv'):
        df = pd.read_csv(coords_path, dtype={'控制点名称': str})
    else:
        raise ValueError("仅支持CSV/XLSX格式的坐标文件")
    return df[['控制点名称', 'X', 'Y', 'Z']]

def match_targets_with_coords(targets_list, coords_df):
    targets_df = pd.DataFrame({'控制点名称': targets_list})
    merged_df = pd.merge(targets_df, coords_df, on='控制点名称', how='left')
    return merged_df

def write_targets_with_coords(merged_df, output_path):
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write("控制点名称,X,Y,Z\n")
        for _, row in merged_df.iterrows():
            target = row['控制点名称']
            x = row['X'] if pd.notna(row['X']) else 'NA'
            y = row['Y'] if pd.notna(row['Y']) else 'NA'
            z = row['Z'] if pd.notna(row['Z']) else 'NA'
            f.write(f"{target},{x},{y},{z}\n")

if __name__ == "__main__":
    # 输入路径
    p = input("请输入原始扫描数据文件夹路径:")
    controlpath = input("请输入输出文件保存路径:")
    coords_path = input("请输入坐标文件(CSV/XLSX)路径:")
    
    # 提取并去重目标文件名
    targets = []
    for root, directories, contents in os.walk(p, topdown=False):
        for name in contents:
            # 过滤不需要的文件
            if "Scan" in name or len(name) < 13 or "Project" in name:
                continue
            if name not in targets:
                targets.append(name)
    
    # 格式化目标名
    formatted_targets = [format_target_name(target) for target in targets]
    
    # 加载坐标并匹配
    coords_df = load_coords(coords_path)
    merged_df = match_targets_with_coords(formatted_targets, coords_df)
    
    # 写入带坐标的TXT
    output_file = os.path.join(controlpath, "control_with_coords.txt")
    write_targets_with_coords(merged_df, output_file)
    print(f"带坐标的控制点文件已生成:{output_file}")

关键注意事项

  • 确保坐标文件中的控制点名称列名与代码中的控制点名称一致,若实际列名不同,需修改代码中对应的列名。
  • 正则表达式可根据实际控制点格式调整,若存在特殊格式,可扩展正则规则。
  • 匹配时强制名称为字符串类型,避免数字型名称被自动转换导致匹配失败。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:30:42