EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

EaBIM

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 2323|回复: 25
打印 上一主题 下一主题

[资料] 开发基于AutoCAD 2000平台的数字测图软件若干技术

[复制链接]

1514

主题

7465

帖子

1万

积分

admin

Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10

积分
12406

社区QQ达人

跳转到指定楼层
F
发表于 2014-1-8 16:18:45 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
【摘要】AutoCAD 2000是CAD工业的旗舰产品,具有强大的图形编辑功能和开放性。本文主要介绍利用AutoCAD 2000提供的二次开发工具:ActiveX Automation和ObjectARX,采用Visual C++ 6.0开发数字测图软件的若干技术。
【关键词】AutoCAD 2000  ObjectARX  ActiveX Automation  面向GIS
一、引言
AutoCAD是最为流行的计算机辅助绘图软件包,深得广大测绘人员的喜爱,几乎所有商业化测图软件选择AutoCAD作为开发平台或提供与之交互的接口。AutoCAD 2000是美国Autodesk 公司于1999年推出的最新版本,相对于上一个版本AutoCAD R14增加了很多新特性,提供非常开放的可定制特性和二次开发环境,尤其适合开发新一代功能强大、面向GIS的智能化数字测图软件。
Visual C++是由微软公司推出的开发Windows9X和Windows NT操作系统下32位应用程序开发工具,是汇集微软公司技术精华的主流产品,也是目前功能最强、最复杂的编程系统之一。最新版本VC 6.0是开发AutoCAD2000 ObjectARX应用程序的唯一支持编译器。
二、几种常用AutoCAD 2000开发工具简介
AutoCAD 2000提供了AutoLISP/Visual LISP,VBA,ActiveX Automation及ObjectARX等手段进行二次开发。
AutoLISP作为AutoCAD的二次开发工具已经很久了,是一种嵌入在AutoCAD内部的LISP编程语言,其特点是程序和数据都采用符号表达式形式,使用起来十分方便灵活,但只能被解释执行,运行效率低且保密性差。1998年推出的Visual LISP是一个可视化的LISP语言开发环境,它是AutoLISP语言的扩展和延伸,在很大程度上克服了AutoLISP原来的效率低和保密性差等缺陷,适合开发一些中小型规模的应用软件。
把VBA(Microsoft Visual Basic for Applications)集成到AutoCAD 2000为定制AutoCAD提供了一种易于使用的可视化工具。用VBA编程需要对ActiveX Automation接口有基本的了解。VBA在进程内运行速度比AutoLISP应用程序快。与AutoLISP相比,VBA更适合于开发用户界面占主体的应用软件。
ActiveX Automation是微软公司基于COM(部件对象模型)体系结构开发的一项技术,是AutoCAD的新编程接口。用户可以用它来自定义AutoCAD,与其他应用程序共享图形数据并自动化任务。通过Automation,AutoCAD提供了由AutoCAD对象模型描述的可编程对象。这些可编程对象可由其他应用程序创建、编辑和操纵。可以访问AutoCAD对象模型的应用程序是Automation控制程序,使用Automation操纵另一个应用程序的最常用工具是VBA。用户可以使用这些应用程序或其他Automation控制程序(如Visual Basic、C++、Delphi和Java)来驱动AutoCAD。
ObjectARX(AutoCAD 运行时扩展)是一种用来开发 AutoCAD 应用程序的编译语言编程环境。它使用面向对象的C++应用程序开发机制,以动态链接库形式和 AutoCAD 运行在相同的地址空间并且直接操作 AutoCAD 数据结构和代码,其创建的新命令的操作方式与AutoCAD基本命令操作方式相同。ObjectARX库可以和其他AutoCAD编程接口(比如AutoLISP或VBA)结合使用,从而可以跨API集成。ObjectARX是对AutoCAD进行二次开发的最强有力的工具。
本文将着重就后两种开发工具,叙述用Visual C++ 6.0开发测图软件的若干技术。
三、开发基于AutoCAD 2000的数字测图软件
1. 建立地物地貌符号、线型库
1.1  建立符号库
可以按照《图式》标准将大量独立地物符号和植被符号制做成符号库,即AutoCAD的形文件〔*.shp〕。虽然制作块(block)要简单一些,但形(shape)比块占用更小的磁盘空间,可以缩短读存盘的时间;另外块在图形编辑过程中容易被炸碎,不利于和GIS交换信息。
形是一种用直线段、弧段和圆来定义的特殊图元。形定义文件的每一行最多可包含 128 个字符,超过此长度的行不能编译。AutoCAD 忽略空行和分号右边的文字。利用分号可以在形定义文件中包含注释。每个形说明都有一个标题行,以及一行或多行定义字节。这些定义字节之间用逗号分隔,最后以0结束。一个形格式如下:
*形编号,字节数,型名
字节1,字节2,字节3,...,0
简单的形定义字节在一个定义字节中包含矢量长度和方向的编码。每个矢量的长度和方向代码是一个三字符的字符串。第一个字符必须为0,用于指示AutoCAD将后面的两个字符解释为十六进制值。第二个字符指定矢量的长度。有效的十六进制值包括从1(一单位长度)到F(十五单位长度)。第三个字符指定矢量的方向。
除定义矢量之外,定义字节也可用下列特殊代码创建其他格式、指定特定操作。要使用特殊代码,三字符串中的第二个字符(矢量长度定义)必须为 0,或者也可直接指定代码数字(例如,008 和 8 都是有效的特殊代码定义)。
下面举一个阀门的形定义为例:
*553,19,FM
003,20,002,008,(-5,22),001,0A0,002,058,001,0EC,00A,(8,-024),00A,(8,-064),0
1.2  建立线型库
AutoCAD 2000提供了单线型、复合线型和平行线线型定义,可以参照《图式》自如地制作各类线状地物地貌的线型库(*.lin和*.mln)。
各类道路和界线可以采用单线型定义。格式如下:
*线型名[,说明部分]
A,笔画—1,笔画—2,…
每个笔画—n 字段指定组成线型的一个线段的长度。长度为正时,画一条实线段;长度为负时,画一条空线段;长度为 0 时,画一个点。每个线型至多可以有 12 个线段长度定义,但这些定义必须在一行中,并且总长度不能超过 80 个字符。以小路的线型定义为例:
*小路,__ __ __ __ __ __ __ __ __ __ __
A,2.0,-0.5
较为复杂的地物、地貌(如栅栏、篱笆、陡坎等)可采用复杂线型加以定义。复杂线型的语法与简单线型的语法相似,形和文字对象也可作为复杂线型的图案说明单元。格式如下:
*线型名[,说明部分]
A,笔画—1,[型名,型文件名,S=缩放比例,R=相对旋转,A=绝对旋转,X=X偏移,Y=Y偏移],笔画—2,…
这里以栅栏定义为例:
*栅栏,栅栏
A,4,[SL_CIRCLE,map.shx,s=.1],-.1,4,[SL_LINE,map.shx,s=.1],0
值得一提的是建立符号库和线型库是一项繁琐的工作,需要多次调试直至满足要求为止,AutoCAD 2000提供了自动生成形和线型的工具,在下拉菜单项[快捷工具]→[工具]即可找到[制作线型]和[制作形]子菜单,只须按提示操作即可完成形的制作。
实际上建立了符号库、线型库后就可以采用AutoCAD的操作命令如LOAD、SHAPE、LINETYPE以及各种画图和编辑命令绘制图形了,由于操作步骤仍然太多,需要进一步定制用户界面和开发应用程序以提高成图效率。
2. 定制用户界面
用户界面主要包括菜单、工具栏、状态栏、键盘宏、对话框以及帮助文件等。
菜单类型有屏幕菜单、下拉菜单、图标菜单、快捷菜单、数字化仪菜单以及辅助菜单等。定制菜单一般方法是修改AutoCAD的标准菜单文件,也可以采用开发ObjectARX或ActiveX Automation控制程序创建自己的菜单。在定制数字测图软件的菜单时,一般将下拉菜单列出主要功能命令,屏幕菜单提供了常用功能的快捷方式,绘制房屋等地形、地物的功能则采用图标菜单直观实现。
标准菜单文件ACAD.MNU划分为与AutoCAD界面的特定区域相关的几个部分。按照其功能,每个菜单区域可由一个或多个部分定义。每个部分中都包含菜单项,它为与菜单选项相关的外观和操作提供指示。菜单项由下列元素组成:名称标记、标签和菜单宏。菜单文件不要求包括所有的菜单部分,而只需要适用于应用程序的菜单部分。
修改标准菜单文件需要了解AutoLISP或Diesel语言,举一个下拉菜单定制的例子:
***POP13                                     //下拉菜单定义
**测算法                                        //菜单别名
M_CSF [测算法(&C)]                             //下拉菜单标题
M_LoadCSF[加载测算法 (&L)]^C^C(arxload "c:/program files/ACAD2000/csf.arx") //菜单项
M_UnloadCSF[卸载测算法(&U)] ^C^C(arxunload "csf")               
[--]                                              //分隔线
M_Polar  [极坐标(&undefined)]^C^CCSFpolar
……
M_LoadCSF 是名称标记;标签[加载测算法 (&L)]在菜单中显示“加载测算法 (&L)”;当用
户选择此菜单项时,执行菜单宏^C^C(arxload "c:/program files/ACAD2000/csf.arx")。
工具条提供了比菜单更为快捷的选择方式,定制工具条可以通过两条途径:一是采用Toolbar命令,另一是编辑菜单文件。可以将一些常用的菜单项制作成工具条,这样能加快用户点取速度,工具条过多也会使绘图区显得拥挤。同样可以在VBA或ObjectARX应用程序中创建工具条,需注意的是在ObjectARX程序中必须为利用MFC类库创建的工具条创建一个接收工具条命令消息的CWnd对象,同时应针对AutoCAD多文档特性编写代码。
对话框一般在应用程序中创建,VBA和VC++都是理想的可视化编程工具。在VisualLISP中仍然使用对话框控制语言(DCL)创建对话框,与前者相比显得繁琐。
用户界面定制与开发是一项十分重要的工作,构造布局合理、操作简便的界面需要发挥软件开发人员的想象力。限于篇幅,只能叙述AutoCAD 2000界面定制的概貌,有兴趣者可以查阅有关文献资料。
3. Visual C++开发Acad2000数字测图软件
3.1  ActiveX Automation应用软件开发
AutoCAD ActiveX Automaion提供给控制程序可编程对象有:图形对象、类型风格对象、结构对象和图形显示对象,甚至AutoCAD程序本身也被看作对象。
在Acad R14之前,编制一些测绘应用软件利用AutoCAD输出图形(如变形监测软件中绘制沉降曲线)主要通过图形交换文件。现在可以利用AutoCAD提供的自动化接口,编制控制程序控制AutoCAD2000的启动、创建新图以及完成绘图任务。当然AutoCAD ActiveX Automation不一定专为其他进程调用,VBA和ObjectARX就可在AutoCAD进程内调用自动化接口。
Visual C++ 开发ActiveX Automation应用程序一般可采用两条途径,但都要用AutoCAD 2000提供的类型库文件(Acad.tlb,该文件和Acad.exe文件同在一个目录中)。这里以VC6.0为例,介绍利用MFC提供的类COleDispatchDriver驱动AutoCAD的方法:
创建一个基于对话框的MFC AppVizard  [exe]新工程AcadDrv,在向导选项中全部采用默认,在类CAcadDrvApp的成员函数InitInstance()的函数体开始处增加一句“AfxOleInit();”,然后启动ClassWizard,选择[add class]按钮,接着选[from type library]菜单项,找到Acad.tlb文件并选中,弹出对话框的列表框中列出了所有AutoCAD ActiveX Automation对象(在C++中具体表现为类),可以选择要用到的类。产生的类将存入文件Acad.h和Acad.cpp中,打开Acad.h可以看到对象的属性和方法均由类的成员函数表示所有对象类均从COleDispatchDriver派生。下面一段代码显示了启动Acad2000的一般步骤。
LPDISPATCH pDisp;  LPUNKNOWN pUnk;  CLSID clsid;     //定义变量
::CLSIDFromProgID(L"AutoCAD.Application.15",&clsid);   //获取Acad2000的类ID
if(::GetActiveObject(clsid,NULL,&pUnk) == S_OK){   //判断ACAD是否已启动
if (pUnk->QueryInterface(IID_IDispatch,(void**) &pDisp)== S_OK){
m_app.AttachDispatch(pDisp);  //建立与AutoCAD的连接,m_app为IacadApplication的实例
pUnk->Release();
}
}
else if (!m_app.CreateDispatch(clsid)){  //启动AutoCAD2000
AfxMessageBox("Acad 2000 not found");
return;
}
m_app.SetVisible(TRUE); //使AutoCAD2000窗口可见

  VC++中开发Automation控制程序另一种方法是采用新的#import编译指令,产生两个文件:Acad.tlh和Acad.tli。TLH文件包含驱动类的声明和智能指针(smart pointer),TLI文件包含了驱动类的内联实现。同上建立新的工程,可以将#import语句放在AfxStd.h文件中:
#include <afxdisp.h>
#import “c:\program files\acad2000\acad.tlb”  no_namespace
……
3.2  ObjectARX应用软件开发
从AutoCAD R13开始Autodesk公司提供C++语言的二次开发工具包ARX,以取代C语言开发包ADS(AutoCAD 高级开发系统),发展到AutoCAD 2000已是ObjectARX 3.0版本。开发ObjectARX 3.0应用程序须VC++6.0编译器和ARX SDK。ARX SDK分为5个部分:
⑴ AcRx类库,用于绑定应用程序和运行时类的注册和识别;
⑵ AcEd类库,用于注册内部命令和系统事件通知;
⑶ AcDb类库,用于直接访问AutoCAD数据库;
⑷ AcGi 类库,用于渲染AutoCAD图形界面;
⑸ AcGe类库,用于线性代数和几何对象相关的类。
ObjectARX应用程序实质上是一个动态链接库,ARX程序与AutoCAD通信的入口是acrxEntryPoint()函数。下面代码演示了入口函数的最一般用法:
extern "C" AcRx::AppRetCode  acrxEntryPoint(AcRx::AppMsgCode msg,void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:  //处理应用程序初始化消息
acrxDynamicLinker->unlockApplication(pkt);//允许卸载应用程序
acrxRegisterAppMDIAware(pkt);//允许在多文档执行
initApp();//初始化,一般定义命令
break;
case AcRx::kUnloadAppMsg://处理应用程序卸载消息
unloadApp();//执行卸载,一般删除命令组
break;
default:
break;
}
return AcRx::kRetOK;
}
AutoCAD图形是存储在数据库中的对象(图形实体和内部结构)的集合。ObjectARX的应用程序能访问这些对象或创建新对象。当对象在AutoCAD中被创建后,它们被添加到相应的容器对象中。如实体添加到块表中,符号表记录被添加到相应的符号表中,其他对象被添加到命名对象字典、其他对象或扩展字典中。下图显示了创建一个直线和园时的块表结构:
块表                 图纸空间





模型空间




下面示例显示创建一条直线:
AcDbObjectId createLine()
{
//定义两个点并创建一条直线
AcGePoint3d startPt(4.0,2.0,0.0);
AcGePoint3d endPt(10.0,7.0,0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);
//获得当前块表
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
//获得当前块表记录并关闭块表
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForWrite);
pBlockTable->close();
//添加实体至块表记录
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pLine);
//关闭块表记录和实体
pBlockTableRecord->close();
pLine->close();
return lineId;
}
使用ObjectARX不但可以访问AutoCAD数据库和与编辑器交互,而且可以完成利用MFC创建用户界面、创建自定义实体、自定义通知、事务处理、协议扩展、与其他环境进行通信等高级功能。有兴趣者可查阅ARX SDK 帮助文档。
3.3  几个开发实例源代码
(1) 消隐模式对话框与AutoCAD编辑器交互
//CCsfTraverseDlg必须从CAduiDialog类派生,可直接替换ClassWizard自动生成代/码中的CDialog
void CCsfTraverseDlg::OnButtonPicka()
{
UpdateData(TRUE);
BeginEditorCommand();//隐藏对话框将控制权交给编辑器
ads_point pt;
if(acedGetPoint(NULL,"\n拾取已知点A:",pt) == RTNORM){
CompleteEditorCommand();//如果取得一个点,则返还到对话框
m_lfPtAX = pt[Y];
m_lfPtAY = pt[X];
UpdateData(FALSE);
}
else
{
CancelEditorCommand(); //如果拾取失败,则取消命令和对话框
}
}
(2) 改变Acad确省图标和标题
……
HICON hIcon = :undefinedoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_ICON_CSF));
acedGetAcadFrame()->SendMessage(WM_SETICON,(WPARAM)ICON_SMALL,
(LPARAM)hIcon);
acedGetAcadFrame()->SetWindowText(_T("测算法[Ver 2.0]"));
(3) 加载指定形文件
Acad::ErrorStatus loadShapeFile(const char *cFileName)
{
AcDbTextStyleTable *pTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pTable,
AcDb::kForWrite);
if(pTable->has(cFileName)){  //如果已经加载,返回eAlreadyInDb
pTable->close();
return  Acad::eAlreadyInDb;
}
   char cFilePath[MAXPATH],filename[MAXPATH];
   strcpy(filename,cFileName);
   if(acedFindFile(strcat(filename,".shx"),cFilePath) != RTNORM){
      acutPrintf("形文件( %s )找不到.",cFileName);
      pTable->close();
      return  Acad::eFileNotFound; //找不到该形文件,返回eFileNotFound
   }
   AcDbTextStyleTableRecord *pRecord = new AcDbTextStyleTableRecord;
   pRecord->setIsShapeFile(Adesk::kTrue);
   pRecord->setFileName(cFilePath);
   pRecord->setName(cFileName);
pTable->add(pRecord); //在字型表添加该形记录后,必须关闭表和记录。
   pTable->close();
   pRecord->close();
   return Acad::eOk;
}
4. 面向GIS数字测图软件系统设计的一般要点
GIS的广泛应用对数字地图的提出了新的要求,不仅仅是图,更重要的是空间和属性信息。因此作为GIS的前端软件,必须既要方便测图生产,又要能与GIS交换数据,而不带来很大匹配的工作量,在软件系统设计时一般要注意以下几点:
(1) 根据应用需要分层
一般参照《地形图图式》的九类地形要素分为九个图层一个辅助图层,其他要素如地籍图要素、规划红线、煤气管线等可根据需要另建图层。
(2) 地图要素分类编码
《地形要素分类与代码》GB 14804-93采用四位整数编码,在数字测图软件系统设计时应参照国标,采用四位编码或四位以上编码。考虑到编码可扩展性,笔者建议采用五位以上编码:
第一位表示地图类,如地形图要素则为1,地籍图要素为2;第二位表示大类码;第三位表示中类码;第四位表示小类码;第五位表示序号;第六位以后为系统自定义码。
如12211表示地面上的窑洞,第一位表示为地形图类,第二位表示居民地,第三位表示特殊房屋,第四位表示窑洞,第五位表示地面上的窑洞。
不管采用何种编码体系应注意编码的科学性、一致性、唯一性、可扩展性和稳定性。为了便于野外采集数据,可编制与系统码相对应的简码,如一般房屋为F1,提高采集效率。
(3) 按点、线、面、注记设计图形数据结构
根据GIS矢量数据结构特点,将图形要素划分为点、线、面、注记四类:点状符号采用shape或block绘制(应建立符号库,尽量采用shape以减小图形存储空间),如各类检修井;线状地物采用pline或line绘制(应建立线型库,尽量采用pline),如陡坎;面状地物可采用pline绘制,对于植被符号可采用pline定义边界,然后在边界内采用shape填充符号,房屋、河流、宗地界址线等应构成封闭多边形;注记采用text绘制;对于一些复合地物,如围墙、桥梁可采用编组(group)方式定制。总之,一个地图要素在图形数据库中应可区分为一个整体。
(4) 嵌入属性信息
GIS要求信息比一般地形图多,必须在图形要素中嵌入属性信息,如实体编码、房屋楼层、材料等。在AutoCAD中添加属性信息一般有两类方法:其一是在不常用的实体固有属性区定义特殊信息,如Thickness、Elevation;其二是添加实体扩展数据(XDATA)或扩展记录(XRECORD)。笔者建议采用第二种方法,这样可不改变AutoCAD自身属性规则,并且能根据需要定义若干项属性。
(5) 与GIS交换数据信息
最简单的交换方式是通过DXF文件交换信息,但不能实现全信息交换,需要较大的修改编辑工作量。实现全信息交换一般方法有:将图形信息全信息写入文本数据文件或通用数据库作为与GIS交换信息的接口;直接将图形信息全信息写入特定的GIS格式文件(如MapInfo 的MIF、MID文件)。
四、结束语
AutoCAD 2000的开放性和丰富的开发工具可大大缩短测图软件开发周期,使其成为专业制图软件开发者的首选平台,如何进一步提高测图效率和实现与各类GIS系统的无缝衔接是数字测图软件开发的努力方向。本文结合笔者在实际开发过程中的经验,介绍若干开发技术,仅起抛砖引玉的作用。定有不当之处,欢迎指正。
【参考文献】
[1]. 邵俊昌,李旭东. AutoCAD ObjectARX 2000 开发技术指南. 电子工业出版社,2000.
[2]. David J. Kruglinski. Visual C++ 技术内幕. 清华大学出版社,1999.
[3]. AutoDesk公司. AutoCAD 2000 Online Help. 1999.
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 转播转播 分享分享 分享淘帖 支持支持 反对反对

相关帖子

工作时间:工作日的9:00-12:00/13:30-18:00,节假日不在线,请勿留言

1514

主题

7465

帖子

1万

积分

admin

Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10

积分
12406

社区QQ达人

推荐
 楼主| 发表于 2015-2-2 12:20:59 | 只看该作者
ganxiefenxiang
工作时间:工作日的9:00-12:00/13:30-18:00,节假日不在线,请勿留言

3

主题

1787

帖子

1926

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1926
推荐
发表于 2014-8-15 15:35:56 | 只看该作者
(*^__^*) 嘻嘻……
*滑块验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|EaBIM网 ( 苏ICP备2020058923号-1  苏公网安备32011502011255号

GMT+8, 2024-11-27 11:30

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表