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

news/2024/7/8 5:15:57 标签: 数据库, 图形, table, lisp, object, list

以地籍库为例介绍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 配置数据源

  设D:/宗地/目录下有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


http://www.niftyadmin.cn/n/1374335.html

相关文章

搭建以太坊私链环境(Windows)

1、下载Geth.exe 运行文件&#xff0c;并安装 https://github.com/ethereum/go-ethereum/releases/下载后&#xff0c;只有一个Geth.exe的文件 2、cmd进入按章目录运行&#xff1a;geth -help看看是否可用geth命令 3、在Geth安装目录下放置初始化创世块文件genesis.json {&qu…

git 使用那些事儿

本文来自网易云社区作者&#xff1a;孙有军工欲善其事&#xff0c;必先利其器&#xff0c;git是一个开源的分布式版本控制工具,很多文章都写的太长&#xff0c;或者资料太多&#xff0c;难以一时间看完。在此总结了git的一些使用方式&#xff0c;因此该文不是鸿篇巨著&#xff…

PAT B1013

令 Pi​ 表示第 i 个素数。现任给两个正整数 M≤N≤104&#xff0c;请输出 PM​ 到 PN​ 的所有素数。 输入格式&#xff1a; 输入在一行中给出 M 和 N&#xff0c;其间以空格分隔。 输出格式&#xff1a; 输出从 PM​ 到 PN​ 的所有素数&#xff0c;每 10 个数字占 1 行&…

[Jenkins] 解决 Gradle 编译包含 SVG Drawable 出现异常

2019独角兽企业重金招聘Python工程师标准>>> 异常信息 java.awt.AWTError: Cant connect to X11 window server using localhost:10.0 as the value of the DISPLAY variable. 解决方案 在 Jenkins shell 脚本里调用 gradlew 编译之前&#xff0c;增加如下语句 unse…

PAT 甲1059

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N p1​k1​p2​k2​⋯pm​km​. Input Specification: Each input file contains one test case which gives a positive integer N in the range of long…

oracle中存储过程,存储函数,触发器,游标,索引,事务以及锁的概念,作用...

2019独角兽企业重金招聘Python工程师标准>>> 1、存储过程&#xff1a;oracle有系统存储过程和自定义存储过程&#xff0c;为了完成特定功能的sql语句集&#xff0c;经编译后存储在数据库中&#xff0c;用户通过特定的存储过程名来执行。 作用&#xff1a; (1)、由于…

Java访问COM的基本原理

Java作为一种跨平台的语言&#xff0c;在很多环境下都获得了成功。然而&#xff0c;在Windows平台下&#xff0c;Java的发展却受到了一定程度的限制。其中很重要的原因就是&#xff0c;目前Java对Windows构件模型的支持力度不够&#xff0c;使得Java程序很难复用Windows平台下丰…

配置资源文件拷贝插件

<build><pluginManagement><plugins><!-- 资源文件拷贝插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>2.7</version><configu…