ArcMap批量出图的设计与实现(三)

该博客介绍了两个Python脚本和一个C#程序,用于解析地图文档,导出属性信息,居中显示要素,并将地图文档导出为图片。C#程序则用于替换xlsx表格内容并动态导出为图片。整个流程通过一个Python启动脚本协调执行。
Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

代码详解

代码主要包含:

Python部分2个文件,分别为:解析地图文档程序(导出文本、另存地图文档)、导出地图到图片的程序。

  • FastParseMapDocument.py
# -*- coding:utf8 -*-
import os
import arcpy
import sys

reload(sys)
sys.setdefaultencoding('utf8')


def parse_map_doc(doc_dir, doc_name, work_issue_prefix):
    """
    解析mxd文档,用途:
    1.创建工作目录
    2.复制一份文档,作为我们真正使用的(以防对原始文件造成修改或破坏)
    3.遍历目录图层,将各要素居中显示并导出属性、另存mxd文档
    :param doc_dir: 原始mxd文档所在目录
    :param doc_name: 原始mxd文档名称
    :param work_issue_prefix: 工作目录名称(不包含其上各层级目录)前缀
    :return:无
    """
    doc_path = os.path.join(doc_dir, doc_name)
    map_doc = arcpy.mapping.MapDocument(doc_path)
    work_dir = os.path.join(doc_dir, work_issue_prefix)
    if os.path.exists(work_dir):
        os.rmdir(work_dir)
    os.makedirs(work_dir)

    work_doc_name = work_issue_prefix + '_' + doc_name  # 真正使用的mxd
    work_doc_path = os.path.join(doc_dir, work_doc_name)
    if os.path.exists(work_doc_path):
        del work_doc_path
    map_doc.saveACopy(work_doc_path)
    del map_doc

    work_map_doc = arcpy.mapping.MapDocument(work_doc_path)
    data_frames = arcpy.mapping.ListDataFrames(work_map_doc)
    layers = arcpy.mapping.ListLayers(work_map_doc, None, data_frames[0])
    for layer in layers:
        if layer.name != u'RT地产用地':  # 目标图层名
            continue
        else:
            with arcpy.da.SearchCursor(layer, ['FID', 'Shape@', u'文件名称', u'宗地号', u'停尝编号2', u'坐落土地面', u'项目名称', u'项目地址',
                                               u'土地证_房']) as cursor:
                for row in cursor:
                    print u'FID = {0}, 项目地址:{1}'.format(row[0], row[7])
                    feature_values = [doc_name.split('.')[0], row[2],
                                      u'宗地号', row[3],
                                      u'宗地代码', row[4],
                                      u'宗地面积', row[5],
                                      u'所在位置', row[6],
                                      u'用地单位', row[7],
                                      u'用地合同号', row[8]]
                    data_frames[0].panToExtent(row[1].extent)  # 当前要素居中

                    feature_file_name = u'temp_feature_{0}.txt'.format(row[0])  # 保存到文本文件中
                    feature_file_path = os.path.join(work_dir, feature_file_name)
                    feature_file = open(feature_file_path, 'w')
                    for a_feature_value in feature_values:
                        feature_file.write(a_feature_value)
                        feature_file.writelines(u'\n')
                    feature_file.close()

                    a_work_file_name = 'temp_feature_' + str(row[0])
                    a_work_doc_path = os.path.join(work_dir, a_work_file_name + '.mxd')
                    work_map_doc.saveACopy(a_work_doc_path)  # 另存为地图文档
  • FastExportMapDocument.py
# -*- coding:utf8 -*-
import os
import arcpy
import sys

reload(sys)
sys.setdefaultencoding('utf8')


def export_map_doc(doc_dir, work_issue_prefix, resolution=512):
    """
    导出地图文档到JPG图片
    :param doc_dir: 原始mxd文档所在目录
    :param work_issue_prefix: 工作目录名称(不包含其上各层级目录)前缀
    :param resolution: 导出图片的分辨率
    :return:无
    """
    # doc_dir = u'D:\\A1_正在处理\\制图1116'
    work_dir = os.path.join(doc_dir, work_issue_prefix)
    print(u'工作目录: {0}'.format(work_dir))
    mxd_files = list(
        filter(lambda filename: os.path.splitext(filename)[1] == '.mxd',
               os.listdir(work_dir)))  # 遍历目录下的mxd文档
    row_index = 0
    for a_doc_file_path in mxd_files:
        row_index += 1
        print(u'{0}/{1} - 正在导出如下文件至图片: {2}'.format(row_index, len(mxd_files), a_doc_file_path))
        a_doc_file_name = os.path.basename(a_doc_file_path).split('.')[0]
        a_doc_full_path = os.path.join(work_dir, a_doc_file_path)
        a_map_doc = arcpy.mapping.MapDocument(a_doc_full_path)
        picture_element = arcpy.mapping.ListLayoutElements(a_map_doc, u'PICTURE_ELEMENT')[0]
        a_source_image_full_path = os.path.join(work_dir, u'{0}.jpg'.format(a_doc_file_name))  # 替换表格图片
        picture_element.sourceImage = a_source_image_full_path
        arcpy.mapping.ExportToJPEG(a_map_doc, u'e_{0}.jpg'.format(a_doc_file_name), resolution=resolution)
        print(u'{0}/{1} - 成功导出图片: {2}'.format(row_index, len(mxd_files), u'e_{0}.jpg'.format(a_doc_file_name)))
        del a_map_doc
        os.remove(a_doc_full_path)  # 删除过程文件
        del picture_element
        os.remove(a_source_image_full_path)  # 删除过程文件
    print(u'导出完毕!将打开结果目录...')
    cmd_param = u"explorer.exe \"%s\"" % work_dir
    os.system(cmd_param.decode('utf-8').encode('gbk'))

C#部分1个文件,即:通过文本替换xlsx表格中的内容,动态导出为图片(含图片白边裁切)。

  • Program.cs
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Spire.Xls;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;

namespace Text2Picture
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (null == args || 2 > args.Length)
                {
                    throw new Exception("参数有误!");
                }
                if (!Directory.Exists(args[0]))
                {
                    Console.WriteLine(args[0]);
                    throw new Exception("请传入工作目录并确保路径合法!");
                }
                if (!File.Exists(args[1]))
                {
                    Console.WriteLine(args[1]);
                    throw new Exception("请传入表格模板文件完整路径并确保路径合法!");
                }
                var sWorkDir = args[0];
                var sTemplatePath = args[1];
                using (var fsTemplate = File.OpenRead(sTemplatePath))
                {
                    //采用NPOI组件替换xlsx文件的内容并另存
                    IWorkbook pWorkbook = new XSSFWorkbook(fsTemplate);
                    if (null == pWorkbook)
                        throw new Exception("Template File Does Not Exist");

                    var pWorkSheet = pWorkbook.GetSheetAt(0);
                    var lstFileInfo = new DirectoryInfo(sWorkDir).GetFiles("*.txt", SearchOption.TopDirectoryOnly);
                    foreach (var aFileInfo in lstFileInfo)
                    {
                        Console.WriteLine($"----->开始干活: {aFileInfo.Name}");
                        using (var sr = aFileInfo.OpenText())
                        {
                            var sLine = string.Empty;
                            var nLineIndex = 0;
                            var nRowIndex = 0;
                            var nColumnIndex = 0;
                            while (null != (sLine = sr.ReadLine()))
                            {
                                Console.WriteLine($"第{nLineIndex + 1}个(行号{nRowIndex},列号C{nColumnIndex}), 值: {sLine}");
                                nRowIndex = nLineIndex / 2;
                                nColumnIndex = nLineIndex % 2;
                                nLineIndex++;
                                var row = pWorkSheet.GetRow(nRowIndex);
                                if (nRowIndex == 3 && nColumnIndex == 1)
                                {
                                    sLine += "m\x00B2";//平方米,其中目标用unicode编码表示
                                }
                                row.GetCell(nColumnIndex).SetCellValue(sLine);
                            }
                            sr.Close();
                        }

                        var sFilePathNoExt = Path.Combine(sWorkDir, aFileInfo.Name.Split('.')[0]);
                        var sNewFilePath = sFilePathNoExt + ".xlsx";
                        Console.WriteLine($"保存文件: {sNewFilePath}");
                        using (var sNewFileStream = new FileStream(sNewFilePath, FileMode.Create))
                        {
                            pWorkbook.Write(sNewFileStream);
                            sNewFileStream.Close();
                        }

                        //采用Spire.XLS组件将xlsx特定区域导出为图片
                        Workbook workbook = new Workbook();
                        workbook.LoadFromFile(sNewFilePath);
                        var worksheet = workbook.Worksheets[0];
                        worksheet.AllocatedRange["A1:B7"].AutoFitRows();
                        var image = worksheet.ToImage(0, 0, 7, 2);
                        var newImage = ClipImage(new Bitmap(image));
                        newImage.Save((sFilePathNoExt + ".jpg"));
                        Console.WriteLine($"导出图片: {sFilePathNoExt}.jpg");
                        File.Delete(aFileInfo.FullName);
                        File.Delete(sNewFilePath);
                        Console.WriteLine("完结撒花!<-----");
                    }
                    fsTemplate.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.WriteLine("0");
            }
        }

        /// <summary>
        /// 裁剪图片
        /// 使用默认导出的文件,上下左右各有约65像素的白边,
        /// 导入到地图文档中时,会遮盖地图,影响布局,
        /// 因此,在导出xlsx特定区域到图片文件前,先裁切白边
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="nBorderSize"></param>
        /// <returns></returns>
        private static Image ClipImage(Bitmap bmp, int nBorderSize = 65)
        {
            Bitmap newBmp = null;
            if (bmp.Height > 2 * nBorderSize && bmp.Width > 2 * nBorderSize)
            {
                newBmp = new Bitmap(bmp.Width - 2 * nBorderSize, bmp.Height - 2 * nBorderSize);
                var g = Graphics.FromImage(newBmp);
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.DrawImage(bmp,
                    new Rectangle(0, 0, bmp.Width - 2 * nBorderSize, bmp.Height - 2 * nBorderSize),
                    new Rectangle(nBorderSize, nBorderSize, bmp.Width - 2 * nBorderSize, bmp.Height - 2 * nBorderSize),
                    GraphicsUnit.Pixel);
                g.Dispose();
            }
            return newBmp;
        }
    }
}

程序封装

采用一个Python文件,通过少量几行代码,实现对Python代码、C#编译的可执行文件的调用。

  • Startup.py
# -*- coding:utf8 -*-
import os
import time
import sys
import arcpy

import FastParseMapDocument
import FastExportMapDocument

reload(sys)
sys.setdefaultencoding('utf8')

if __name__ == '__main__':
    mxd_full_path = u'{0}'.format(sys.argv[1].decode('gbk').encode('utf-8'))
    arcpy.AddMessage(u'输入的mxd文档路径为: {0}'.format(mxd_full_path))
    doc_dir = os.path.dirname(mxd_full_path)
    doc_name = os.path.basename(mxd_full_path)
    work_issue_prefix = 'T' + time.strftime("%Y%m%d%H%M%S", time.localtime())
    exe_bin_dir = os.path.join(os.path.abspath(os.curdir), u'bin')
    # exe_bin_dir = u'D:\\A15_Test\\FastExportMxd\\bin'
    template_xlsx_path = os.path.join(exe_bin_dir, u'data_template.xlsx')
    bat_file_path = os.path.join(exe_bin_dir, u'temp.bat')
    FastParseMapDocument.parse_map_doc(doc_dir, doc_name, work_issue_prefix)
    cmd_param = u"%s \"%s\" \"%s\"" % (bat_file_path, os.path.join(doc_dir, work_issue_prefix), template_xlsx_path)
    process_cmd = os.popen(cmd_param.decode('utf-8').encode('gbk'))
    print process_cmd.read()
    process_cmd.close()
    FastExportMapDocument.export_map_doc(doc_dir, work_issue_prefix)
  • temp.bat
set current_path=%~dp0
start %current_path%\Text2Picture.exe %1 %2

 

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

内容概要:本文介绍了一个基于Simulink的混合储能驱动永磁同步电机全系统仿真模型,涵盖了系统整体架构关键控制策略,重点实现了电流环的二阶滑模控制(STSMC)、有限集模型预测控制(FCS-MPC)和PI控制等多种先进控制方法。该模型集成了混合储能系统永磁同步电机驱动系统,能够模拟复杂工况下的动态响应、能量管理过程及多变量耦合特性,适用于高性能电机控制系统的设计、分析验证,尤其在新能源汽车、电动驱动系统和工业自动化等领域具有重要应用价值。; 适合人群:具备Simulink仿真基础、电力电子电机控制背景的高校研究生、科研人员及自动化、电气工程领域的研发工程师。; 使用场景及目标:①用于研究和对比不同电流控制策略(如STSMC、FCS-MPC、PI)在永磁同步电机系统中的动态性能、鲁棒性抗干扰能力;②支撑混合储能系统在电动驱动、新能源汽车、智能电网等领域的系统级仿真优化设计;③为先进控制算法的开发工程化落地提供高保真、模块化的仿真平台。; 阅读建议:建议结合Simulink模型相关控制理论进行对照学习,重点关注各功能模块之间的信号交互、控制逻辑设计及参数整定方法,可通过修改负载条件、切换控制模式等方式开展对比实验,深入理解系统动态行为控制效果差异。
软件概述 UG(Unigraphics NX)是一款由西门子(Siemens PLM Software)开发的交互式CAD/CAM/CAE系统。作为全球领先的产品工程解决方案,它集成了产品设计、工程仿真制造加工于一体。其功能强大且应用广泛,能够轻松实现各种复杂实体和造型的构造,为模具、汽车、航空航天及通用机械等行业提供了高性能的机械设计制图灵活性。 软件基础信息 • 支持系统: 64位 Windows 10、Windows 11 核心功能模块 一、创新设计:高效、灵活、无缝协同 全链路产品设计 涵盖从2D布局、3D建模、装配设计到图纸文档记录的各个环节,大幅提升设计吞吐量,缩短交付周期超35%。 强大的同步建模技术 打破数据壁垒,可无缝导入并直接修改来自其他CAD系统的几何模型,是跨平台协同设计的理想选择。 复杂装配管理 专为大型复杂产品打造,即使面对成千上万的零件也能从容应对,快速识别并解决数字样机中的干涉等问题。 集成设计验证 内置自动验证功能,实时监控设计是否符合公司及行业标准;结合PLM数据可视化合成,辅助工程师做出更明智的决策。 二、综合仿真(Simcenter 3D):精准预测,降低试错成本 极速前后处理 依托先进的几何引擎,将强大的分析命令几何编辑紧密集成,相比传统有限元工具,可缩短高达70%的仿真建模时间。 全方位结构分析 在同一环境中集成线性静力学、动态、疲劳及非线性分析,底层由业界顶尖的NX Nastran解算器提供支持,确保计算的高精度可靠性。 声学热管理分析 提供内外声学仿真以优化音质、降低噪音;具备一流的热传导仿真能力,帮助电子产品和工业机械实现最佳热管理方案。 多物理场耦合 简化了结构动力学、热传导、流体流动等复杂物理现象的模拟过程,消除外部数据传输错误,真实还原产品运行工况。 三、智能制造(CAM):打通从计划到车间的数字主线 全面的制造解决方案 提供从工装设计、CAM编程到机床控制器(如Sinumerik)的一体化支持,助力制定更科学的生产决策。 深度集成的PLM环境 借助Teamcenter实现数据和流程的统一管理,避免多数据库冲突,支持重用验证过的加工工艺刀具库。 车间级互联 通过DNC系统车间无缝对接,直接将加工数据和刀具清单下发至CNC机床,实现计划生产的紧密结合。 提质增效 优化NC编程刀具路径,提升表面精加工水平零件精度;减少人为错误,显著提高新机床部署成功率及制造资源利用率。 总结 UG NX 2023作为一款集成化的产品工程解决方案,通过其强大的设计、仿真和制造功能,为现代制造业提供了完整的数字化产品开发平台。无论是复杂产品的设计验证,还是精密制造的流程优化,UG NX 2023都能为工程师团队提供高效、可靠的解决方案,助力企业提升产品创新能力和市场竞争力。 适用领域 模具设计、汽车制造、航空航天、通用机械、消费电子等
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值