【干货】iData二次开发——以脚本语言Python为例

时间:2024-04-06 20:06:10
【干货】iData二次开发——以脚本语言Python为例

南方数码测绘软件事业部邹磊对iData接口类中交互、选择、实体、图层、编码等内容介绍进行了详细的讲解,带领大家以完成任务的方式编写脚本,以掌握开发接口的灵活运用。 


昨天的微信,我们以Python语言为例,介绍iData的Python二次开发功能(点击阅读:邹磊:iData二次开发,拥有无限可能)。


iData拥有Python、Lua、C#、VB、Java、C++等多种语言的二次开发功能,虽然不同语言的语法要求不尽相同,但二次开发的接口、类、函数、参数大同小异。今天,我们将以脚本语言Python和Lua为例做简要介绍。


01

环境要求


 C#、VB:二次开发需要安装Microsoft Visual Studio,推荐Visual Studio 2013版本。对于其他版本的Visual Studio,只要安装了.NET Framework 4.5.1即可。同时,如果只需要运行二次开发程序,不做二次开发,可仅安装Microsoft .NET Framework;


 Python:安装Python (版本3.5.1或者3.5.2),配置环境变量,将python.exe的路径加入系统的Path变量即可。iData推荐使用包含了大量第三方工具的WinPython。32位的iData需要32位的Python,64位的iData需要64位的Python;


Java:二次开发需要安装JDK,如果只运行不做开发也可只安装JRE。同时还需要配置环境变量,将java.exe和jvm.dll所在路径同时加入系统的Path变量。32位的iData需要32位的JDK/JRE,64位的iData需要64位的JDK/JRE;


 Lua:iData自带,不需要配置环境。


【干货】iData二次开发——以脚本语言Python为例

设置环境变量


02

文档和对话框


iData中的很多接口函数都在iDataInterface中,使用C#、VB,可以在对象浏览器中查看这些接口的名称和参数,使用Java可以通过javadoc查看,如果使用的是Python则可以在iData运行目录下的PyiData.py文件中查看(推荐使用Spyder打开,可以自动显示文档)。


对文档(数据库)、对话框的各种操作在开发中会经常用,并且使用较为简单容易理解,iData二次开发教程从这里开始。


现在,再来看一看上一节最后给出的一段简单的示例代码,判断是否有文档打开,有则关闭当前,没有则打开指定文档:


import PyiData as pid

isOk=pid.isDocumentActived()    #获取文档打开状态

docPath='F:\\AerialTestData\\测试数据\\I50G057076.mdb'

if not isOk:    #判断文档是否打开

    isOK=pid.OpenDoc(docPath)   #打开指定路径的文档

    print('打开文档', docPath)

else:

    docPath=pid.getCurDocPath() #获取当前打开的文档路径

    print('已经打开了文档', docPath)

    isOk=pid.CloseDoc(docPath)  #关闭文档

    print('关闭文档', docPath)


代码第一行import PyiData as pid就是将Python二次开发中的iDataInterface引入并重命名为pid,因此接下来的所有iData接口函数都会在pid中,比如第二行判断当前是否有文档打开的接口isDocumentActived,除此之外,文档相关的使用较为频繁的几个接口如下:


OpenDoc:打开文件
CloseDoc:关闭文件

getCurBase:获取当前文件所打开的数据库对象

getCurDocPath:当前文档的路径

isDocumentActived:判断当前视图中是否有文档打开


再看下面一段,弹出对话框选择文件和文件夹,把下面的代码保存成py文件执行,或者直接在shell里敲下面的代码,看看各种对话框的效果。


import PyiData as pid

#打开单个文件对话框

filename = pid.getOpenFileName('选择单个文件','F:\\', '数据库(*.mdb)')

print('选择了文件:', filename) 

#保存文件对话框

filename = pid.getSaveFileName('保存文件', 'F:\\')

print('选择了文件:', filename)

#打开多个文件对话框

filenameList = pid.getOpenFileNames('选择多个文件','F:\\', '数据库(*.mdb)')

print('选择了文件', len(filenameList), '个:') 

for name in filenameList:

    print(name)


【干货】iData二次开发——以脚本语言Python为例

打开文件对话框示例


除了上面的常用对话框外,iData还有以下常用的对话框接口,可以使用Spyder查看具体文档和说明。


getOpenFileName:打开文件对话框

getOpenFileNames:打开文件对话框(多选)

getExistingDirectory:打开目录对话框

getSaveFileName:保存文件对话框

GetCustomColorDlg:选择颜色对话框


除此之外,Python中还可以使用第三方的界面库提供界面,比如PyQt4,如有需要可以参考PyQt4的文档。Lua语言中还有特定的MessageBox类方法,具体使用方法和示例,可以参考iData运行目录下的lua目录中的luaBasicUI.lua文件。


03

交互和选择


交互和选择是iData二次开发中最常用的功能,iData提供了功能强大的、同CAD类似的交互和选择的接口。


先来看一下交互,交互就是iData从运行中停下来等待用户输入信息的过程,比如输入数据、选择实体等等。


下面的代码将会让用户在iData图面上点击选择一个点并打印出选择的这个点的坐标。接口的输入参数和返回值,可以查阅文档(即PyiData.py文件,推荐Spyder查看)。


#鼠标选点  

e, point = pid.iDataGetPoint('请选择一个点:')

if e == pid.iData.eOk:

    print('选择了点:', point.x(), point.y())

 

#拉框选点 

e, point2 = pid.iDataGetCorner(point, '拉框选择第二个点:')

if e == pid.iData.eOk:

    print('选择了第二个点:', point.x(), point.y())

 

#鼠标选择角度 

e, angle = pid.iDataGetOrient(point, '选择一个角度:')

if e == pid.iData.eOk:

    print('选择了角度:', angle)


【干货】iData二次开发——以脚本语言Python为例

拉框选择坐标点示例


除了上面的选择坐标点,iData还提供了获取整数、实数、字符串的接口,示例如下:


#分别输入整数、实数字符串

e, num = pid.iDataGetInt('请输入整数:')

if e == pid.iData.eOk:

    pid.iDataPrintf('输入整数:' + str(num))

 

e, num = pid.iDataGetReal('请输入实数:')

if e == pid.iData.eOk:

    pid.iDataPrintf('输入实数:' + str(num))

   

e, s = pid.iDataGetString('请输入字符串:')

if e == pid.iData.eOk:

    pid.iDataPrintf('输入字符串:' + s)



iData中常用的交互接口如下,具体说明和示例请查阅文档。


 iDataPrintf:打印

 iDataInitGet:初始化关键字

 iDataGetString:获取字符串

 iDataGetInt:获取整数数值

 iDataGetReal:获取浮点数值

 iDataGetPoint:选择一个点

iDataGetPoint2:连线,选择一个点

 iDataGetCorner:拉框,选择一个点

 iDataGetOrient:获取线段和X轴的夹角


选择,就是根据一定的规则,选择图面上满足规则的实体(可以理解为图形及其属性,后面会详细介绍)。当需要对图面进行操作时,要先根据需要的条件选择出需要的实体,再进行操作。


iData接口包含丰富强大的选择功能,可以根据不同的需求组合选择出所需要的实体。较常用的选择接口如下:


iDataEntSel:单击鼠标选择实体

 iDataSSGetX:选择给定图层上的实体

 iDataSSGet:根据给定的点、矩形、多边形等,在给定图层上选择实体

 iDataGetSelectedEntitys:获取视图中被选中的实体

ClearSelection:取消对实体的选择状态


下面将对这些接口举例说明。


下面的代码,让iData停下来,等待用户用鼠标在屏幕上点击选择单个实体:


#用鼠标在屏幕上点击选择单个实体

e, entity, point = pid.iDataEntSel('鼠标屏幕点选选实体:')

if e == pid.iData.eOk:

    print('选择了一个实体:')

    print(entity)

    print('点击位置:', point)


让iData停下来,等待用户用鼠标以任意方式选择实体:


#用鼠标以任意方式选择实体

e, entityList = pid.iDataSSGet('选择实体:')

if e == pid.iData.eOk:

    print('选了', len(entityList), '个实体。')


iData不等待,直接根据条件选择实体,可以选择全部,也可以按照图层进行筛选:


#选择图面所有实体

e, entityList = pid.iDataSSGetX()

print('当前图面共', len(entityList), '个实体。')

del entityList  #清空列表

 

#选择图层IDATA和LCA图层上的所有实体

e, entityList = pid.iDataSSGetX(['IDATA', 'LCA'])

print('指定图层上共', len(entityList), '个实体。')

 

for entity in entityList:   #让选择到的实体高亮显示

    entity.setHighLight(True)

pid.iDataRegen(pid.Rect(),True) #刷新图面

del entityList  #清空列表


在指定区域内,选择IDATA图层上的实体,可以是框选,也可以是交选:


框选:选择方式ContainsItemShape相当于从左向右拉框


交选:选择方式IntersectsItemShape相当于从右向左拉框


#在指定区域内,选择IDATA图层上的实体,框选

#选择方式ContainsItemShape相当于从左向右拉框

rect = pid.Rect(0, 0, 250, 250)

e, entityList = pid.iDataSSGetRect(rect, pid.iData.ContainsItemShape, ['IDATA'])

if e == pid.iData.eOk:

    print('指定区域中找到', len(entityList), '个实体')

 

#在指定区域内,选择所有图层上的实体,交选

#选择方式IntersectsItemShape相当于从右向左拉框

rect = pid.Rect(0, 0, 250, 250)

e, entityList = pid.iDataSSGetRect(rect, pid.iData.IntersectsItemShape)

if e == pid.iData.eOk:

    print('指定区域中找到', len(entityList), '个实体')


当然,iData还拥有更为复杂的实体选功能,例如通过不规则多边形选择等等,如有需要可查阅相关文档。


到这里,大家已经对iData二次开发有了初步的了解,下面的代码,类似于move(移动图面上的实体)功能,相信大家能够看明白其实现过程。


# -*- coding: utf-8 -*-

"""

Created on Fri Sep 15 14:16:17 2017

@author: Zoulei

"""

 

import PyiData as pid

 

e, entity, point = pid.iDataEntSel('选择一个实体:')#选择实体

if e==pid.iData.eOk:

    print('原实体点击位置点:' + str(point))

    e, point2 = pid.iDataGetPoint2(point, '选择一个将要移动到的点:')

 

    if e==pid.iData.eOk:

        entity.setPos(point2.x(), point2.y())#移动实体

        print('实体东移%.3f,北移%.3f' % (point2.x() - point.x(), point2.y() - point.y()))

       

        pid.panToPoint(point2)#移动图面

        pid.CommitEntity(entity, pid.iData.kModified)#提交数据库

        pid.iDataRegen(None, True)#刷新图面

    else:

        print('放弃选择点')

else:

    print('放弃选择实体')


【干货】iData二次开发——以脚本语言Python为例

移动实体示例


通过今天的文章,相信大家已经了解了iData二次开发的中的文档、对话框、交互、选择相关的一些内容,但这些还不足以完成一项小的开发任务。更多示例和说明,敬请继续关注南方数码官微接下来的推送。