当前位置:服务支持 >  软件文章 >  AutoCAD数据库连接地籍库案例

AutoCAD数据库连接地籍库案例

阅读数 13
点赞 0
article_banner

以地籍库为例介绍AutoCAD数据库连接


李玲


(广西第一测绘院)



【摘 要】 以地籍库为例,介绍AutoCAD2000的数据库连接功能dbConnect。通过地籍库的建立及维护过程,介绍数据库的连接、图形与数据维护的一致性。


【关键词】 AutoCAD 数据库连接 维护 一致性



1 引言


  自从AutoCAD R12将AutoCAD SQL Extension (ASE)引入后,AutoCAD用户就有了将AutoCAD对象链接到外部数据库的能力。AutoCAD 2000将其所有的数据库连接功能组合在一起,形成单一的易于理解的用户界面,称之为dbConnect,dbConnect完全取代了AutoCAD早期版本中老的ASE界面。在AutoCAD 2000中,数据库连接的特点是基于微软的OLE DB技术,通过一个组件对象模型(COM)编程界面——ActiveX数据对象(ADO),可以完全控制OLE DB。ADO能够用在支持COM的任何计算机语言中,也包括AutoCAD编程环境,例如VBA 和 Visual LISP。本文以地籍库为例,以Visual LISP为编程环境,介绍AutoCAD 2000的数据库连接及图形与数据库维护的一致性。


2 图形与数据库的连接


  在AutoCAD中,用数据库进行任何工作之前,必须先建立到数据库的连接。


2.1 建立数据库连接


2.1.1 配置数据源


  设https://www.gofarlic.com\宗地\目录下有Access的Parcel.mdb文件,其中表Table1,表的结构如下:


  Table1:



ID 街道号 街坊号 宗地号 土地利用类别 权属人 宗地面积



  现在要在名为Parcels的图形中连接Parcels.mdb,连接方法可以手工连接,也可以用程序自动连接。手工连接的方法如下:


  1)打开parcels.dwg


  2)从Tools菜单中选择dbConnect。出现dbConnect管理器。


  3)在dbConnect管理器中右击Data Sources,并从捷菜单中选择Configure a Data Source,显示Configure a Data Source对话框。


  4)键入 parcels作为数据源名,点击OK。出现Data Link Properties对话框。


  5)在OLE DB Providers列表框中选择Microsoft Jet 3.51 OLE DB Provider,按Next>>。


  6)键入Parcel.mdb文件的完整路径。


  7)点击Test Connection 校验连接是否建立。


  8)点击OK。


  一旦数据源配置完成,在DATA Links目录生成一个UDL文件,它的名字出现在dbConnect管理器窗口中的Data Sources节点下。


  自动创建连接的过程其实就是通过程序创建如上所述的UDL文件的过程,这里不再详述。


2.1.2 用ADO获取连接到AutoCAD设置的数据源


  用LoadAdo函数获取连接到ACAD设置的数据源,为下面的函数连接数据库作准备。


(defun LoadAdo( / gADO-DLLpath )


  (vl-load-com) ;装载ActiveX


  (setq acadObj (vlax-get-acad-object)


     acadDoc (vla-get-ActiveDocument acadObj)


  gADO-DLLpath "c:\\program files\\common files\\system\\ado\\msado15.dll")


(if (null ado-adOpenDynamic)


(vlax-import-type-library


  :tlb-filename gADO-DLLpath


  :methods-prefix "ado-"


  :properties-prefix "ado-"


  :constants-prefix "ado-"


  ) ;装载ADO Library


)


(setq ADOConnect (vlax-create-object "ADODB.Connection")) ;创建全程变量ADOConnect


(setq wsPath (vlax-get-property


        (vlax-get-property


           (vlax-get-property


                (vlax-get-acad-object)


           "Preferences"


         )


        "Files"


         )


        "WorkspacePath"


     )


   name ( getvar "dwgname")


   len (strlen name)


   name (substr name 1 (- len 3))


   name (strcat name "udl")


adoString (strcat "File Name=" wsPath "\\" name ";User ID=;Password=;" )


) ;取数据源udl文件路径


(vlax-put-property ADOConnect "ConnectionString" adoString)


; ADOConnect 将 name.mdb 连接到name.udl文件


(vlax-invoke-method ADOConnect "Open" adoString "" "" -1)


); end LoadAdo


2.2 建立链接模板


2.2.1建立链接模板


  链接对象到数据库之前,必须先建立链接模板,建立链接模板的过程如下:


  1)打开上面已连接数据库的Parcels图形。


  2)打开dbConnect管理器并连接到parcels数据源。


  3)右击Table1表,并选择New Link Template。显示New Link Template对话框。


  4)将链接的默认名称Table1_DataLink1改为Parcels(与图形名相同)。点击Continue进入Link Template对话框,点击ID旁边的框指定ID为关键列,然后点击OK。现在dbConnect管理器中会看到在图形parcels下面的Parcels节点。


2.2.2 用CAO获取链接模板


(defun LoadCao( / linkTemplates name linkname MDBname len index)


 (if (null caom-GetLinkTemplates) ;检查CAO library 是否装载


 (progn


  (vlax-import-type-library


   :tlb-filename "cao15.dll"


   :methods-prefix "caom-"


   :properties-prefix "caop-"


   :constants-prefix "caok-"


  ) ;装载CAO Liabrary


))


(setq CAOConnect (vlax-create-object "CAO.DbConnect"))


(setq linkTemplates (vl-catch-all-apply 'caom-GetLinkTemplates


          (list CAOConnect acadDoc))


)


 (setq name (getvar "dwgname")


    len (strlen name)


    name (substr name 1 (- len 4))


    index 0


    count (vlax-get-property linkTemplates "Count")


   MDBname ""


   linkTemplate nil


  )


(while (< index count)


(setq linkTemplate (vlax-invoke-method linkTemplates "Item" index)


    linkname (vlax-get-property linkTemplate "Name")


    MDBname (vlax-get-propertylinkTemplate "DataSource")


    index (1+ index)


)


   (if (= name MDBname)


    (setq index count)


   )


);在图形链接模板库中搜寻Parcels链接模板


 (if (/= name MDBname)


   (setq linkTemplate nil)


 )


linkTemplate ;使函数返回Table1的链接模板


)


2.3宗地与数据库的自动链接


  在parcels图形中画一权属界线,并将其链接到数据库(以界线对应的图形句柄作为数据库中表Table1的ID号,因为AutoCAD中图形句柄是唯一的):


(defun draw (/)


 (setq p (getpoint \n权属界线第一点:))


 (while p


  (setq plist (append plist (list p)))


  (setq p (getpoint \n下一点:))


)


(if plist


(progn


 (setq ename (LandPline plist));函数LandPline根据节点列表画出权属界线,并返回对应的实体名


 (append_DB ename) ;在数据库中加入权属界线对应的数据记录


 (MakeLink ename) ;将权属界线链接到数据库中对应的数据记录


))


);end defun draw



  其中,append_DB及MakeLink函数定义如下:


(defun append_DB (ename / Object ID area m_plist RS fields fields Count Index


             thisField value)


 (setq Object (vlax-ename->vla-object ename))


       ID (vla-get-Handle Object) ;取实体的句柄


      area (vla-get-area Object) ;取实体面积


)


(setq m_plist (list ID "" "" "" "" "" (rtos area 2 6)));预定义数据记录各字段的数值


(cond


  ; Create the ADO Recordset object


  ((null (setq RS (vlax-create-object "ADODB.Recordset")))


  (princ "\nUnable to create ADODB.Recordset object.")


)


  ((null (ok 'ado-Open (list RS "Table1" ADOConnect ado-adOpenDynamic


          ado-adLockOptimistic ado-adOptionUnspecified)));其中ADOConnect为函数LoadADO中返回的数据库连接


)


(T


  (ado-AddNew RS) ;在Table1中追加一空白记录


  (setq fields (ado-get-Fields RS)


     fieldsCount (vlax-get-property fields "Count")


        index 0


)


  (while (< index fieldsCount)


  (setq thisField (vlax-get-property fields "item" index)


       value (nth index m_plist)


       index (1+ index)


  )


  (ado-put-Value thisField value ) ;将预定义的数值赋予各字段


 ) ;将空白记录各字段赋值


 (ado-Update RS) ;向数据库提交变化


)


);end cond


  (ReleaseRS RS)


);End Defun append_DB


 (defun ReleaseRS (RS)


  (if RS


  (progn


   (if (= (ado-get-State RS) ado-adStateOpen)


    (ado-Close RS)


   )


   (vlax-release-object RS)


   (setq RS nil)


  ))


)


  以上的append_DB在数据库记录中加入ID和宗地面积,使宗地图形与数据库记录一一对应,宗地的其他属性可以在数据库中手工录入。


(defun MakeLink( ename / VlaObj objectID vlax-obj currKeyValues OneKeyValue linkResult)


  (setq linkTemplate (LoadCao))


  (setq VlaObj (vlax-ename->vla-object ename)


  objectID (vla-get-Handle VlaObj)


  vlax-obj (vlax-get-property VlaObj "ObjectID")


 currKeyValues (vlax-create-object "CAO.keyValues")


  OneKeyValue (vlax-create-object "CAO.KeyValue")


)


(vlax-put-property OneKeyValue "FieldName" "ID")


(vlax-put-property OneKeyValue "Value" objectID)


(vlax-invoke-method currKeyValues "Add" OneKeyValue)


(setq linkResult (vl-catch-all-apply 'caom-CreateLink (list linkTemplate lax-obj currKeyValues) ))


 (if (vl-catch-all-error-p linkResult)


     (princ "\n Trying to execute CreateLink() caused an ActiveX error:")


 )


);end defun MakeLink


3 图形与数据的一致性


  宗地的变化包括权属界线的节点的变化(删点、增点、移点)和宗地的分割、合并。节点的变化仅引起图形和数据记录的改变,图形与数据间的链接关系不变;宗地的分割、合并不仅会引起图形的变化、记录的增减,图形与数据间的链接关系也相应发生改变。


3.1 权属界线节点变化


  以移点为例:


  (defun c:MoveDot ( / ename ss point newpoint oldpoint xylist vlaxobj objID area)


  (setq point (getpoint "\n请选待移动的界址点: [或回车=退出]"))


  (if point


  (progn


   (setq newpoint (getpoint "\n移动到点:"))


   (setq ss (ssget point))


   (setq ename (ssname ss 0))


   (setq xylist (GetPlXY ename) ) ;函数GetPLXY取界线的节点列表


   (setq oldpoint (Plist-DotAt xylist point) ;函数Plist-DotAt返回节点列表中最靠近point的节点


   (Update-ename ename oldpoint newpoint) ;函数Update-ename将界线对象ename中的oldpoint替换成newpoint


   (setq vlaxObj (vlax-ename->vla-object ename)


      objID (vla-get-Handle vlaxObj)


      area (rtos (vla-get-area vlaxObj) 2 6)


   )


  (setq SQLstr (strcat "UPDATE " table " SET 宗地面积='"area "' where ID='" objID "'" )) ;定义SQL语句


    (if (null (ok 'ado-Execute (list db SQLstr nil ado-adOptionUnspecified))) ;执行SQL语句,将数据记录中的宗地面积更新


  (progn


  (princ "\nUnable to Update record.")


  (exit)


  ))


)


3.2 宗地分割与合并


  以宗地分割为例,如图1所示:权属界线由点1至点7构成,分割线由点t1至点t3构成,分割线将宗地分割为Z1、Z2宗地。




  (defun c:Split ( / ename iename xylist inplist plist enam1 ename2 vlaxObj ID SQLstr)(setq ename (car(entsel \n选取欲分割的权属界线:))


(setq iename (car (entsel \n选取分割线:)))


(setq inplist (GetPlXY iename)) ;函数GetPlXY 返回分割线节点列表


(setq xylist (GetPlXY ename));函数GetPlXY 返回权属界线节点列表



(setq plist (SplitPlist xylist inplist));SplitPlist函数返回分割后的两个复合线列表:((点1 点2 i1 t2 i2 点7) (i1 点3 点4 点5 点6 i2 t2))


(setq xylist1 (car plist) xylist2 (cadr plist))


(setq ename1 (LandPline xylist1) ename2 (LandPline xylist2))


LandPline函数根据节点列表构造权属界线,并返回界线对应的实体名


(setq vlaxObj (vlax-ename->vla-object ename)


    ID (vla-get-Handle vlaxObj)


)


(setq SQLstr (strcat "DELETE FROM " table " where ID='" ID "'") )


(if (null (ok 'ado-Execute (list ADOConnect SQLstr nil


               ado-adOptionUnspecified)))


 (progn


  (princ "\nUnable to delete record.")


  (exit)


 )


)


  ;执行SQL语句,将原权属界线对应的数据记录删除,相应的链接关系也被删除


  (command "erase" ename "") ;将原权属界线删除


  (append_DB ename1) ;在数据库中建立宗地Z1对应的数据记录


  (Make_Link ename1) ;将宗地Z1的权属界线链接到对应的数据记录


  (Append_DB ename2) ;在数据库中建立宗地Z2对应的数据记录


  (Make_Link ename1) ;将宗地Z2的权属界线链接到对应的数据记录


);End Defun Split


4 结束语


  本文以地籍库的建立及维护过程为例,较详细的介绍了AutoCAD2000的数据库连接dbConnect功能。出于篇幅考虑,文中与dbConnect无紧密联系的函数略去不表。希望本文能对读者取到参考作用。



参考文献:


[1]  (美)Scott McFarlane著;罗阿理等译.AutoCAD数据库连接.机械工业出版社,2001.5


[2]  郭剑蜂,陈杉,王宁编著.用Visual LISP开发AutoCAD 2000应用程序. 人民邮电出版社,2000.1


[3]  汤峻编.AutoCAD2000高级应用与Visual LISP 开发宝典. 人民邮电出版社,2001.1



免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删
相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空