论文部分内容阅读
摘要:本文主要講述了在CAD平台下,利用Auto LISP编程语言,实现对DEM数据接边情况的批量检查,并将检查的结果以图形和报表两种形式反馈给用户,提高DEM数据接边检查的效率。
关键词: AutoCAD;Auto LISP;DEM
中图分类号:TP313 文献标识码:A 文章编号:
在制作辽宁省1:10000万DEM基础数据时,经常需要对分幅制作的DEM进行接边检查,在以往的过程中都是利用Virtouzo本身提供的功能进行两幅间的接边检查,这种方法虽然也能达到检查的目的,但效率较低。尤其是当对大量的DEM进行接边检查时,更是让人感到繁琐。为提高检查的作业效率,减少作业员的劳动强度,本人编写了这个对DEM进行自动批量检查的程序。
1 软件的运行平台及开发语言的简介
AutoCAD是美国Autodesk公司推出的通用计算机绘图软件,它以其强大的绘图功能和良好的开发环境,广泛应用于机械、电子、化工、建筑、测量与勘察等行业。对AutoCAD进行二次开发的手段很多,例如Auto LISP、ADS、ARX、VBA等,本程序使用的是Auto LISP编程语言,它已被嵌入CAD中。Auto LISP具有语法简单、功能强大、易学易用的特点,它的数据类型相当随意,可以组织处理不同长度和结构的数据类型,用户可以按要求和最佳结构设计使用自定义的结构类型数据,而不会感到组织数据结构上的困难。另外,Auto LISP擅长人机交互操作的过程,对用户输入的接受、错误识别、恢复操作等方面的优秀功能,是其它语言难以比及的。
2 程序具体实现
2.1 设计思路
由于每幅DEM都由超过百万的栅格点组成,如果在检查时对每个栅格点的高程值进行比较检查,那程序将运行很慢,也做了很多无用功。我们在进行接边检查时,可以只比较每幅DEM边缘一定范围内的栅格点的高程值,就可以达到接边检查的效果。另外,在对每幅DEM进行接边检查时,如果对其周围的八幅都进行比较检查,在整个检查的过程中也将做很多重复的比较工作,我们可以选定其中连续的三幅进行比较检查,例如:“上幅、右上幅、右幅”或者“右幅、右下幅、下幅”,那么对于整个检查不但对每条边都进行了接边检查,还减少很多重复的比较。本程序选定的是上幅、右上幅和右幅这三幅进行比较检查的。
为提高程序的运行速度,在存储数据时本程序还使用了分块存储的方式,即将每幅检查图的上边缘提取的接边数据存储到一个变量中,右上角的接边数据存储到一个变量中,右边的接边数据存储到一个变量中。这样有些情况,可以只比较其中的部分数据就可以完成比较工作。
在了解了数据的提取和存储方式后,我们介绍一下程序的设计运行线路。运行程序首先提示用户选取要接边文件所在的文件夹中的任意一幅DEM文件,当用户选定后,程序将自动提取该文件夹下所有后缀为“.dem”的文件名称。程序将根据提取的文件名自动生成图幅结合表,并判断存储每幅图的接边情况。按照接边情况依次对每幅图进行接边检查,将检查的结果输出到“c:/DemCheckResult.txt”文件中。此文件是检查的中间成果,如果运行后发现此文件中有错误记录,那么根据图示,用户再运行“cdr”命令,程序将生产检查成果图和检查成果报告“c:/一万DEM分幅检查成果.txt”。在生成的DWG成果图中,将给出图幅结合表和错误点的点位,对于不接边的点我们将一目了然。在生成的检查报告中,将给出每幅图的所有临幅图的检查情况。
2.2 程序原代码
(defun c:jcdem()
(setvar "CMDECHO" 0)
(setq pf (getfiled "选择DEM文件夹下的任意一个文件" "" "dem" 8))
(if pf (progn
(setq FilesPath (vl-filename-directory pf))
(setq filelp (vl-directory-files FilesPath "*.dem"));;文件夹下存储的dem文件名列表
(princ "\n")
(princ filelp)
(setq write_fp1 (open "c:/DemCheckResult.txt" "w"))
(setq write_fp2 (open "c:/JSTMPsystem.txt" "w"))
;;------------------------- 计算图幅相邻关系 -------------------------
(setq files_long (length filelp))
(setq YON_Y_BL nil YON_S_BL nil YON_D_BL nil)
(setq LFTH_Y nil LFTH_S nil LFTH_D nil)
(setq i 0)
(repeat files_long
(setq Tqbtmp (nth i filelp))
(setq TqbtmpN (vl-filename-base Tqbtmp))
(setq TFH_Name_Y (Get_right_tfname TqbtmpN))
(setq TFH_Name_S (Get_upside_tfname TqbtmpN))
(setq TFH_Name_D (Get_Rrelative_tfname TqbtmpN))
(setq j_1 0)
(setq flag_pdtfh_y 0)
(while (and (= flag_pdtfh_y 0) (< j_1 files_long))
(if (= (vl-filename-base (nth j_1 filelp)) TFH_Name_Y) (progn
(setq flag_pdtfh_y 1)
))
(setq j_1 (+ j_1 1))
)
(setq YON_Y_BL (cons flag_pdtfh_y YON_Y_BL))
(if (= flag_pdtfh_y 1)
(setq LFTH_Y (cons TFH_Name_Y LFTH_Y))
(setq LFTH_Y (cons 'KONG LFTH_Y))
)
(setq j_2 0)
(setq flag_pdtfh_s 0)
(while (and (= flag_pdtfh_s 0) (< j_2 files_long))
(if (= (vl-filename-base (nth j_2 filelp)) TFH_Name_S) (progn
(setq flag_pdtfh_s 1)
))
(setq j_2 (+ j_2 1))
)
(setq YON_S_BL (cons flag_pdtfh_s YON_S_BL))
(if (= flag_pdtfh_s 1)
(setq LFTH_S (cons TFH_Name_S LFTH_S))
(setq LFTH_S (cons 'KONG LFTH_S))
)
(setq j_3 0)
(setq flag_pdtfh_d 0)
(while (and (= flag_pdtfh_d 0) (< j_3 files_long))
(if (= (vl-filename-base (nth j_3 filelp)) TFH_Name_D) (progn
(setq flag_pdtfh_d 1)
))
(setq j_3 (+ j_3 1))
)
(setq YON_D_BL (cons flag_pdtfh_d YON_D_BL))
(if (= flag_pdtfh_d 1)
(setq LFTH_D (cons TFH_Name_D LFTH_D))
(setq LFTH_D (cons 'KONG LFTH_D))
)
(setq i (+ i 1))
)
(setq YON_Y_BL (reverse YON_Y_BL));;与文件名列表顺序对应的临幅关系表
(setq YON_S_BL (reverse YON_S_BL))
(setq YON_D_BL (reverse YON_D_BL))
(setq LFTH_Y (reverse LFTH_Y));;与文件名列表顺序对应的临幅图幅号表
(setq LFTH_S (reverse LFTH_S))
(setq LFTH_D (reverse LFTH_D))
;;------------------------- 计算图幅相邻关系 -------------------------
;;------------------------ 输出DEM结合表文件 ------------------------
(setq OPUT_JHB_i 0)
(repeat files_long
(setq OPUT_TF_path_full (strcat FilesPath "\\" (nth OPUT_JHB_i filelp)))
(setq OPUT_fp_B (open OPUT_TF_path_full "r"))
(setq OPUT_reco_B (read-line OPUT_fp_B))
(setq OPUT_sxb_B (flz OPUT_reco_B))
(setq OPUT_B_jdy (nth 0 OPUT_sxb_B) OPUT_B_jdx (nth 1 OPUT_sxb_B) OPUT_B_gwd (nth 3 OPUT_sxb_B) OPUT_B_column (nth 5 OPUT_sxb_B) OPUT_B_row (nth 6 OPUT_sxb_B))
(setq OPUT_TK_W (+ (atoi OPUT_B_jdy) (* (- (atoi OPUT_B_column) 1) (atoi OPUT_B_gwd))))
(setq OPUT_TK_H (+ (atoi OPUT_B_jdx) (* (- (atoi OPUT_B_row) 1) (atoi OPUT_B_gwd))))
(setq OPUT_TK_WB (+ OPUT_TK_W 2.5))
(setq OPUT_TK_HB (+ OPUT_TK_H 2.5))
(setq OPUT_B_jdyB (- (atof OPUT_B_jdy) 2.5))
(setq OPUT_B_jdxB (- (atof OPUT_B_jdx) 2.5))
(setq OPUT_TK_name (vl-filename-base (nth OPUT_JHB_i filelp)))
(setq OPUT_WriteString2 (strcat OPUT_TK_name " " (rtos OPUT_B_jdyB) " " (rtos OPUT_B_jdxB) " " (rtos OPUT_TK_WB) " " (rtos OPUT_TK_HB)))
(write-line OPUT_WriteString2 write_fp2)
(setq OPUT_JHB_i (+ OPUT_JHB_i 1))
)
;;------------------------ 输出DEM结合表文件 ------------------------
...
;;------------------------ 释放主内存区域 -----------------------------
(setq YON_Y_BL nil YON_S_BL nil YON_D_BL nil)
(setq LFTH_Y nil LFTH_S nil LFTH_D nil)
(close write_fp1)
(close write_fp2)
;;------------------------ 釋放主内存区域 ------------------------------
(princ "\n程序运行完毕,请查看成果文件!")
(princ "\n要生成检查成果图和分幅成果表,请运行< cdr >命令!")
))
(princ)
)
3 结束语
本程序是为格网间距为5米的1万DEM数据接边检查编写的,因为万图是梯形分幅,依照我省万图的具体情况边缘取值范围设为300米内的网格点为接边检查范围点。在检查其他格网间距值的DEM时,只需修改间距值变量和取值范围变量即可使用本程序。由于篇幅所限本文仅列出了主程序模块的部分原代码,有编写繁琐之处敬请批评指正。
参考文献
[1] 康博.中文版AutoCAD2000/2002 Visual LISP开发指南[M],北京:清华大学出版社,2001.8
[2] 唐亮,等.AutoCAD2002开发教程[M],北京:北京希望电子出版社,2002.8
关键词: AutoCAD;Auto LISP;DEM
中图分类号:TP313 文献标识码:A 文章编号:
在制作辽宁省1:10000万DEM基础数据时,经常需要对分幅制作的DEM进行接边检查,在以往的过程中都是利用Virtouzo本身提供的功能进行两幅间的接边检查,这种方法虽然也能达到检查的目的,但效率较低。尤其是当对大量的DEM进行接边检查时,更是让人感到繁琐。为提高检查的作业效率,减少作业员的劳动强度,本人编写了这个对DEM进行自动批量检查的程序。
1 软件的运行平台及开发语言的简介
AutoCAD是美国Autodesk公司推出的通用计算机绘图软件,它以其强大的绘图功能和良好的开发环境,广泛应用于机械、电子、化工、建筑、测量与勘察等行业。对AutoCAD进行二次开发的手段很多,例如Auto LISP、ADS、ARX、VBA等,本程序使用的是Auto LISP编程语言,它已被嵌入CAD中。Auto LISP具有语法简单、功能强大、易学易用的特点,它的数据类型相当随意,可以组织处理不同长度和结构的数据类型,用户可以按要求和最佳结构设计使用自定义的结构类型数据,而不会感到组织数据结构上的困难。另外,Auto LISP擅长人机交互操作的过程,对用户输入的接受、错误识别、恢复操作等方面的优秀功能,是其它语言难以比及的。
2 程序具体实现
2.1 设计思路
由于每幅DEM都由超过百万的栅格点组成,如果在检查时对每个栅格点的高程值进行比较检查,那程序将运行很慢,也做了很多无用功。我们在进行接边检查时,可以只比较每幅DEM边缘一定范围内的栅格点的高程值,就可以达到接边检查的效果。另外,在对每幅DEM进行接边检查时,如果对其周围的八幅都进行比较检查,在整个检查的过程中也将做很多重复的比较工作,我们可以选定其中连续的三幅进行比较检查,例如:“上幅、右上幅、右幅”或者“右幅、右下幅、下幅”,那么对于整个检查不但对每条边都进行了接边检查,还减少很多重复的比较。本程序选定的是上幅、右上幅和右幅这三幅进行比较检查的。
为提高程序的运行速度,在存储数据时本程序还使用了分块存储的方式,即将每幅检查图的上边缘提取的接边数据存储到一个变量中,右上角的接边数据存储到一个变量中,右边的接边数据存储到一个变量中。这样有些情况,可以只比较其中的部分数据就可以完成比较工作。
在了解了数据的提取和存储方式后,我们介绍一下程序的设计运行线路。运行程序首先提示用户选取要接边文件所在的文件夹中的任意一幅DEM文件,当用户选定后,程序将自动提取该文件夹下所有后缀为“.dem”的文件名称。程序将根据提取的文件名自动生成图幅结合表,并判断存储每幅图的接边情况。按照接边情况依次对每幅图进行接边检查,将检查的结果输出到“c:/DemCheckResult.txt”文件中。此文件是检查的中间成果,如果运行后发现此文件中有错误记录,那么根据图示,用户再运行“cdr”命令,程序将生产检查成果图和检查成果报告“c:/一万DEM分幅检查成果.txt”。在生成的DWG成果图中,将给出图幅结合表和错误点的点位,对于不接边的点我们将一目了然。在生成的检查报告中,将给出每幅图的所有临幅图的检查情况。
2.2 程序原代码
(defun c:jcdem()
(setvar "CMDECHO" 0)
(setq pf (getfiled "选择DEM文件夹下的任意一个文件" "" "dem" 8))
(if pf (progn
(setq FilesPath (vl-filename-directory pf))
(setq filelp (vl-directory-files FilesPath "*.dem"));;文件夹下存储的dem文件名列表
(princ "\n")
(princ filelp)
(setq write_fp1 (open "c:/DemCheckResult.txt" "w"))
(setq write_fp2 (open "c:/JSTMPsystem.txt" "w"))
;;------------------------- 计算图幅相邻关系 -------------------------
(setq files_long (length filelp))
(setq YON_Y_BL nil YON_S_BL nil YON_D_BL nil)
(setq LFTH_Y nil LFTH_S nil LFTH_D nil)
(setq i 0)
(repeat files_long
(setq Tqbtmp (nth i filelp))
(setq TqbtmpN (vl-filename-base Tqbtmp))
(setq TFH_Name_Y (Get_right_tfname TqbtmpN))
(setq TFH_Name_S (Get_upside_tfname TqbtmpN))
(setq TFH_Name_D (Get_Rrelative_tfname TqbtmpN))
(setq j_1 0)
(setq flag_pdtfh_y 0)
(while (and (= flag_pdtfh_y 0) (< j_1 files_long))
(if (= (vl-filename-base (nth j_1 filelp)) TFH_Name_Y) (progn
(setq flag_pdtfh_y 1)
))
(setq j_1 (+ j_1 1))
)
(setq YON_Y_BL (cons flag_pdtfh_y YON_Y_BL))
(if (= flag_pdtfh_y 1)
(setq LFTH_Y (cons TFH_Name_Y LFTH_Y))
(setq LFTH_Y (cons 'KONG LFTH_Y))
)
(setq j_2 0)
(setq flag_pdtfh_s 0)
(while (and (= flag_pdtfh_s 0) (< j_2 files_long))
(if (= (vl-filename-base (nth j_2 filelp)) TFH_Name_S) (progn
(setq flag_pdtfh_s 1)
))
(setq j_2 (+ j_2 1))
)
(setq YON_S_BL (cons flag_pdtfh_s YON_S_BL))
(if (= flag_pdtfh_s 1)
(setq LFTH_S (cons TFH_Name_S LFTH_S))
(setq LFTH_S (cons 'KONG LFTH_S))
)
(setq j_3 0)
(setq flag_pdtfh_d 0)
(while (and (= flag_pdtfh_d 0) (< j_3 files_long))
(if (= (vl-filename-base (nth j_3 filelp)) TFH_Name_D) (progn
(setq flag_pdtfh_d 1)
))
(setq j_3 (+ j_3 1))
)
(setq YON_D_BL (cons flag_pdtfh_d YON_D_BL))
(if (= flag_pdtfh_d 1)
(setq LFTH_D (cons TFH_Name_D LFTH_D))
(setq LFTH_D (cons 'KONG LFTH_D))
)
(setq i (+ i 1))
)
(setq YON_Y_BL (reverse YON_Y_BL));;与文件名列表顺序对应的临幅关系表
(setq YON_S_BL (reverse YON_S_BL))
(setq YON_D_BL (reverse YON_D_BL))
(setq LFTH_Y (reverse LFTH_Y));;与文件名列表顺序对应的临幅图幅号表
(setq LFTH_S (reverse LFTH_S))
(setq LFTH_D (reverse LFTH_D))
;;------------------------- 计算图幅相邻关系 -------------------------
;;------------------------ 输出DEM结合表文件 ------------------------
(setq OPUT_JHB_i 0)
(repeat files_long
(setq OPUT_TF_path_full (strcat FilesPath "\\" (nth OPUT_JHB_i filelp)))
(setq OPUT_fp_B (open OPUT_TF_path_full "r"))
(setq OPUT_reco_B (read-line OPUT_fp_B))
(setq OPUT_sxb_B (flz OPUT_reco_B))
(setq OPUT_B_jdy (nth 0 OPUT_sxb_B) OPUT_B_jdx (nth 1 OPUT_sxb_B) OPUT_B_gwd (nth 3 OPUT_sxb_B) OPUT_B_column (nth 5 OPUT_sxb_B) OPUT_B_row (nth 6 OPUT_sxb_B))
(setq OPUT_TK_W (+ (atoi OPUT_B_jdy) (* (- (atoi OPUT_B_column) 1) (atoi OPUT_B_gwd))))
(setq OPUT_TK_H (+ (atoi OPUT_B_jdx) (* (- (atoi OPUT_B_row) 1) (atoi OPUT_B_gwd))))
(setq OPUT_TK_WB (+ OPUT_TK_W 2.5))
(setq OPUT_TK_HB (+ OPUT_TK_H 2.5))
(setq OPUT_B_jdyB (- (atof OPUT_B_jdy) 2.5))
(setq OPUT_B_jdxB (- (atof OPUT_B_jdx) 2.5))
(setq OPUT_TK_name (vl-filename-base (nth OPUT_JHB_i filelp)))
(setq OPUT_WriteString2 (strcat OPUT_TK_name " " (rtos OPUT_B_jdyB) " " (rtos OPUT_B_jdxB) " " (rtos OPUT_TK_WB) " " (rtos OPUT_TK_HB)))
(write-line OPUT_WriteString2 write_fp2)
(setq OPUT_JHB_i (+ OPUT_JHB_i 1))
)
;;------------------------ 输出DEM结合表文件 ------------------------
...
;;------------------------ 释放主内存区域 -----------------------------
(setq YON_Y_BL nil YON_S_BL nil YON_D_BL nil)
(setq LFTH_Y nil LFTH_S nil LFTH_D nil)
(close write_fp1)
(close write_fp2)
;;------------------------ 釋放主内存区域 ------------------------------
(princ "\n程序运行完毕,请查看成果文件!")
(princ "\n要生成检查成果图和分幅成果表,请运行< cdr >命令!")
))
(princ)
)
3 结束语
本程序是为格网间距为5米的1万DEM数据接边检查编写的,因为万图是梯形分幅,依照我省万图的具体情况边缘取值范围设为300米内的网格点为接边检查范围点。在检查其他格网间距值的DEM时,只需修改间距值变量和取值范围变量即可使用本程序。由于篇幅所限本文仅列出了主程序模块的部分原代码,有编写繁琐之处敬请批评指正。
参考文献
[1] 康博.中文版AutoCAD2000/2002 Visual LISP开发指南[M],北京:清华大学出版社,2001.8
[2] 唐亮,等.AutoCAD2002开发教程[M],北京:北京希望电子出版社,2002.8