扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
一、系统开发模式
创新互联建站主要从事成都网站设计、网站制作、外贸营销网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务景东,十余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:13518219792
(一)GIS二次开发模式
GIS二次开发模式主要有三种:独立开发模式、宿主型开发模式、GIS组件开发模式。独立开发难度太大,宿主型二次开发受GIS平台所提供的脚本语言的限制,因此,结合GIS工具软件与可视化开发语言的集成二次开发方式是GIS应用开发的主流。它的优点是既可以充分利用GIS工具软件对空间数据库的管理、分析功能,又可以充分利用可视化软件开发工具的高效方便等编程优点,集二者之所长,不仅能大大提高应用系统的开发效率,而且使用面向对象的可视化软件开发出来的应用程序具有更好的用户界面,更强大的数据库功能。
组件式GIS的基本思想是把GIS的各功能模块划分为若干个组件,每个组件完成不同的功能。各个GIS组件之间,以及GIS组件与其他非GIS组件之间,通过可视化的软件开发工具集成起来,形成最终的GIS应用系统。组件式GIS具有二次开发方便、易于集成、无限扩展等特点。有利于提高二次开发的效率,增强GIS系统中各子系统之间的集成度,便于与其他信息系统集成,为其他信息系统提供地理信息处理功能。
因此,本系统采用VB.NET+Arc GIS Engine+Access集成的组件式GIS二次开发模式,利用建立在组件开发基础上的Esri Arc GIS提供的Arc GIS Engine实现GIS的基本功能,以通用软件开发工具,尤其是可视化开发工具Visual Basic.NET为开发平台,进行二者的集成开发。
(二)应用程序的四层模型
面向对象的、基于模块化的组件设计需要能够方便地修改应用程序的各个部分。完成这一目标的一种好方法就是在层上工作,将一个应用程序的主要功能分离到不同的层或者级中。从本质上讲,层代表了一个应用程序主要的功能。系统采用的是当前比较流行的多层应用程序中的四层模型。四层模型的结构关系图见图13—4。
图13—4 四层模型的结构关系图
(1)用户层
用户层只提供用户使用界面和简单的界面数据合法性验证。
(2)业务外观层
业务外观层为用户层提供处理信息浏览界面。这一层是作为SGWMIS.sln解决方案文件中的Business Facade项目实现的。业务外观层用作隔离层,它将用户界面与各种业务功能的实现隔离开来。除了低级系统和支持功能之外,对数据库服务器的所有调用都是通过此程序集进行的。
(3)业务规则层
业务规则层是作为SGWMIS.sln解决方案文件中的Business Rules项目实现的,它包含各种业务规则和逻辑的实现。
(4)数据访问层
数据访问层为业务规则层提供数据服务。这一层是作为SGWMIS.sln解决方案文件中的Data Ac cess项目的实现。
这种分层设计方式很有用,因为每一层都可以独立地修改。可以修改商务层,不断地从数据层接受相同的数据,并把这些数据传递到表示层,而不用担心出现歧义。也可以修改表示层,使得对于外观的修改不必改动下面的商务层逻辑。
二、系统主要功能
系统主要包括系统管理、研究区信息、水质评价、水质预测、含水层固有脆弱性评价、污染风险评价、污染预警、帮助等功能模块。
(一)系统管理功能
包括项目管理、添加文件、查看结果、退出系统。
(1)项目管理:实现新建项目、打开项目、保存项目、关闭项目的功能。
(2)添加文件:用于添加研究区水质数据文件和相关的图形文件。
(3)查看结果:用于查看当前项目已保存过的水质评价、水质预测、水质预警等运行结果。
(二)研究区信息管理功能
包括数据信息和空间信息管理两方面,实现各种基本信息数据的输入,并对已存储的各种数据内容进行修改、添加、删除等操作。
(三)图形显示功能
对于空间图形,可以任意选择显示一个或多个图层,对于矢量图层可以任意放大、缩小、漫游、全屏显示和复位等。图形显示窗口是一个如图13—5所示的窗口,它包括:工具栏、目录树栏、视图区和缩略图区。
图13—5 图形显示窗口
(1)工具栏
工具栏里提供了比较常用的视图工具,包括
打开新地图,
添加shapefile文件,
删除选中图层,
设置图层颜色,
打印地图,
将地图输出为图片,
放大、
缩小工具,
拖动工具,
全屏显示,
属性查询等。
(2)目录树栏:包含了图件各层信息,包括标注,点图层、线图层、面图层。可以在图层选项中任意打开或关闭某一层,从而选取需要显示的信息。
(3)缩略图区:该区显示了当前图的缩略图,图中的红色方框表示右侧视图区当前显示区域。挪动视图,红框的位置随视图的移动而移动,从而实现了用鹰眼对全图进行缩放浏览跟踪。
(4)视图区:显示图件的大量信息,包括所有的点、线、面,标注、图例等。
三、帮助
系统提供了HTML格式的帮助文件,用户可以从中了解系统所有功能的操作步骤,如图13—6。
图13—6 系统帮助
四、系统特点
地下水污染预警系统是一个集MIS、GIS业务和水质污染预警专业模型为一体的图文一体化信息系统,系统具有以下特点:
(1)系统采用通过.Net开发平台将Arc GIS Engine中提供的GIS控件和自主开发的组件有机地融合在地下水水质与污染预警管理中,是一种理想的组合方式。
(2)系统从设计到实现都遵循了实用性原则。该系统易于使用、便于系统管理、数据更新简便,具有优化的系统结构和完善的数据库系统,以及友好的用户界面。
(3)系统具有一定的空间分析功能、具备缓冲区分析、叠加分析、空间插值等功能,而且能够对空间数据进行等值线、等值面作图等。
(4)采用面向对象设计与交互式设计的思想,系统功能逻辑清晰、内容丰富、功能较强。具有模糊综合评价、神经网络、灰色模型、时间序列分析等数学模型。可以进行水质评价、预测、含水层固有脆弱性评价、污染源荷载风险评价、污染风险评价、水质污染预警。运行结果能以形象、直观的地图、表格和图表以及由它们互相组合形成的复合地图等多种形式表现用户所需的信息。
可以把所有画的线都保存在一个列表中,画的时候全部画出即可。如下:
Public Class Form1
Class Line '直线类
Public Point1, Point2 As Point '成员,直线的两个端点
Sub New(p1 As Point, p2 As Point) '构造方法
Point1 = p1
Point2 = p2
End Sub
Public Sub Draw(g As Graphics) '绘制方法
g.DrawLine(Pens.Black, Point1, Point2)
End Sub
End Class
Private Lines As New List(Of Line) '列表用于保存所有画下的直线
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BackColor = Color.White
DoubleBuffered = True '开启双缓冲可有效避免闪烁
End Sub
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
Lines.Add(New Line(e.Location, e.Location)) '在直线列表中添加直线
End Sub
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button Windows.Forms.MouseButtons.Left Then Return '左键未按下
'鼠标拖动时改变列表最后一条直线(也即当前直线的第二个端点)
Lines(Lines.Count - 1).Point2 = e.Location
Refresh() '刷新窗体
End Sub
'在Form的Paint事件中绘制所有直线,每次Form1重绘时都会触发Paint事件
'PS: 也可以通过重写OnPaint方法来达到类似的效果
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias '开启抗锯齿
For Each l In Lines '遍历所有直线
l.Draw(e.Graphics) '调用绘制方法,传入的参数可以理解为画布
Next
End Sub
End Class
运行效果:
1、利用公式求出Y值 第一列设置表头为x,下面依次填入取值, 比如 x 1 2 3 4 ...... 第二例表头设置为y,在下面表格中填入计算公式 如 =2*x+1 然后选中点右下角的十字型标记,拖下去,和前面x数量一致。 2、然后选中数据源(即选中要进行操作的数据区域,这里指XY值所在区域。) 3、执行菜单命令插入——图表——XY散点图 执行命令,打开图表向导对话框选XY散点图--选平滑线散点图--完成 最后使用图表向导在横坐标填入x值,纵坐标填入y值,生成图即可 将一次函数的Y列用公式编辑出来,分别填写出当取不同的X值时得到不的函数值,选择函数值所在列,插入——图表按提示操作。执行菜单命令 执行菜单命令
例1:以下程序我们申请几个指向不同类型的指针:
’使用StructLayout(LayoutKind.Sequential)属性告诉net编译器:结构的元素在内存中按其出现的顺序排列
StructLayout(LayoutKind.Sequential) _
Public Structure DEFUDT_Test
Public bytb As Byte
Public i32a As Int32
End Structure
Public Function fnGetIntptr1() As IntPtr
’取得一个4字节数组指针
Dim tabytTest(3) As Byte
’以下语句告诉net垃圾回收进程不对tabytTest进行处理,也就是说tabytTest占用的内存区域固定不变。
Dim thObject As GCHandle = GCHandle.Alloc(tabytTest, GCHandleType.Pinned)
Dim tpObject As IntPtr = thObject.AddrOfPinnedObject() ’取得指向字节数组的指针
’取得一个指向32位内存数据的指针,
’由于使用gchandle取指针的方法只能对引用的对象有效,
’所以对如int32等值类型必须使用将其封装成为一个对象的方法以变为引用类型
Dim ti32Test As Object = Convert.ToInt32(0)
’以下语句告诉net垃圾回收进程不对ti32test进行处理,也就是说ti32Test的内存位置固定不变。
Dim thObject1 As GCHandle = GCHandle.Alloc(ti32Test, GCHandleType.Pinned)
Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject() ’取得ti32Test的首地址
Dim tudtTest1 As DEFUDT_Test
’由于结构是一种值类型变量,为保证指针申请方便,我们申请
’取得一个和结构tudtTest1大小一致的字节数组指针,只要空间占用长度和结构一样就可以了
’由于net在结构封装中会插入额外的数据位,所以一定要用sizeof方法得到结构在非托管使用时的实际大小
Dim tudtTest(Marshal.SizeOf(tudtTest1)) As Byte
Dim thObject2 As GCHandle = GCHandle.Alloc(tudtTest, GCHandleType.Pinned)
Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject() ’取得指向结构的指针
’在这儿你可以写对指针处理的任意代码(在例2中会给予补充)……
’在使用完毕后一定要释放指针指向的内存块,让垃圾回收器可对这个内存块回收处理
If thObject.IsAllocated Then
thObject.Free()
End If
If thObject1.IsAllocated Then
thObject1.Free()
End If
If thObject2.IsAllocated Then
thObject2.Free()
End If
End Function
上例中指针流程处理可以归纳为:
1、 定义一个具有合适内存长度的引用变量(关于引用变量和值变量的差异可以参观VB.NET的书籍)
2、使用GCHandle.Alloc方法将变量的内存区域固定下来。
3、使用GCHandle对象的AddrOfPinnedObject取得该内存区域的首地址并赋值给指针变量.
4、对指针进行操作
5、使用GCHandle对象的free方法释放指针指向的内存区域以便net垃圾回收器可以回收这个内存空间
2、指针所指向数据的存取
在.net中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy、PtrToStringUni 、PtrToStructure 、OffsetOf、WriteXXX,RreadXXX等,其中WriteXXX的表示向指针所表示的地址中写入XXX类型的数据,而ReadXXX中作用就是将指针所在地址的数据以XXX类型方式读出。看例程2,我们使用这些方法演示对例1那几个指向不同类型数据的指针作数据存/取操作。
例2:演示向例1申请得到的几个指针执行写入及读取数据的操作.
Marshal.WriteInt32(tpObject1, 0, Convert.ToInt32(77)) ’向ti32Test变量指向的地址写入32位整数77
MsgBox("现在ti32Test的值为:" ti32Test) ’因为变量存储地址的数据已改为77,所以显示为77
’以下这句之所以可行,因为ti32Test是32位整数,而tpObject指向的tabytTest数组刚好有4个元素
’而每一个byte元素都占用8位,合起来就是32位,和ti32Test占用的空间一样。这就印证了前面提’
’到的net中指针没有指向类型的说明。
Marshal.WriteInt32(tpObject, 0, ti32Test)
’以下代码再将tabytTest字节数组的内容理解为一个int32整数,
’并将值赋值给tudtTest结构中的int32元素
’我们使用Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32以取得i32a元素在结构中的内存偏移位置
’所以New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32)就临时产生了
’一个指针并指向i32a所在的内存地址(, 这个方法也说明了指针可以以字节为单位进行加减计算以指向合适的变量。
’Marshal.ReadInt32的作用是从指针中读取一个32整数。
Marshal.WriteInt32(New IntPtr(tpObject2.ToInt32 + Marshal.OffsetOf(GetType(DEFUDT_Test), "i32a").ToInt32), _
0, Marshal.ReadInt32(tpObject))
’这儿可以将字节数组的内容复制到真正的结构中
MsgBox(Marshal.OffsetOf(tudtTest1.GetType, "i32a").ToInt32)
tudtTest1 = CType(Marshal.PtrToStructure(tpObject2, GetType(DEFUDT_Test)), DEFUDT_Test)
MsgBox("结构tidtTest1中i32a元素的值为:" tudtTest1.i32a) ’此处将显示刚赋的值77
不想整个重画,最好用单色的背景,例如黑色,线条是白色的
用变量把线条的内容备份
当想改变线条的位置或者长度之前,先用存下来的变量以黑色重画一次,覆盖原来的白色线条
然后再画新的白色线条,这种重画方法比较节省资源
假如需要用花哨的背景或者图片当背景,也可以用局部重回的方式。
代码就不提供了,只提供思路。
根据个人的经历谈谈个人感想
我一开始学的是VB,但学会后,也就是楼主你的样子,后来学C,觉得C太垃圾了,这可能和VB的简单形成对比,C语言学会后就再也没用,后来直接由VB升级到VB.NET,的确,如同楼主所说,.NET是比较简单,但是有个后遗症,是现在我都烦的,就是编译的软件必须要在有.NET的电脑上运行,XP是不带.NET的,而且,版本还的相对,如果用.NET4.0编的,在4.0以下版本电脑上运行很可能就出错,并且,如果你要打包的话也可以,就是把软件打包成安装包,然后附带.NET环境,但缺点就出来了,.NET3.5完整安装包235M,因为它包括了以下所有版本,还好.NET4.0只有50M左右,因为它不包括以下版本,但总之,.NET就是简单了编程,但复杂了使用,软件得打包,不像VB,编好后直接打开EXE就可以了。所以就麻烦了,举些例子,以前用VBA编OFFICE的宏,打开OFFICE就可以编,编好后就存为XLSM就可以了,现在用.NET就成了VSTO了,编好后,不和文档在一起,是分开的DLL,如果要运行,条件为,1,.NET环境,2,OFFICE,3,VSTO相比以前只需要OFFICE复杂了N倍,而且编辑时也需要VS(动不动就几G)才行,相比以前只要有OFFICE就可以区别也很大,同样,CAD的嵌入开发也是一样的。
所以总体来说,越底层的语言越底层的API越好用,越通用,越高级的越不通用,所以现在我开发软件我都烦了,要是一个小软件几百K~M,再附带个.NET就好几百兆,用的时候还得安装才能用,又不是什么大软件有必要这么做么,还有.NET不是万能的,有些地方也得用API,而且.NET其实也挺复杂,难的地方不比API简单,其实就感觉是封装好了的API而已。
至于数据库,的确.NET连接比较简单
至于学C?那就不用了,因为.NET的支持 C#,C++,VB,J#,只要会其中一种就可以了(而且你只要会其中一门,是能看懂另一门的,比如我虽然编辑C#可能要出错,但C#代码我是几乎全部能看懂的,网上查资料也能看懂其他语言的),大部分是学C的升级用C#.NET,VB的升级成VB.NET,你没必要把它当成另一中语言来学,语法是基本一样的。只是从一开是学C的比较多,就成了C#的比较多而已了,至于语言,我不想做语言攻击,其实都是有用的,就是看自己习惯不,比如我就不习惯C。
我也不想说VB好还是VB.NET好,其实是看你用途,我只是至今没发现什么网上的软件是.NET编辑的,一些软件比如CAD,OFFICE安装时安装了.NET,其实都不是它们是基于.NET编辑的,而是为了支持.NET的嵌入式开发,你所看到的软件,比如QQ,迅雷,你看他们带.NET了吗?要是.NET好,他们干嘛不用,答案是因为不方便,因为XP系统一般是没有.NET的,连WIN7内嵌的.NET都不支持最新的.NET,也就是你用什么版本编的就得安装相应版本,那也要求对方电脑也得跟着升级,而API是不用升级着走的~
所以,你要编的软件在其他电脑上用,VB+API吧,如果你要个人电脑上用,VB.NET吧,如果你编小软件vb+api吧,如果你要大型软件就VB.NET吧,所以,你自己选吧。
希望给你的意见能对你有好处,现在深夜11点了,我也改睡了,拜拜!~
祝你学习愉快!
对了,还有点,比如CAD2007不支持.NET3.5以上的编程,而且.NET编好的EXE或者DLL是可以用专门的软件打开看你源代码的,也就是反编译,这对于加密(可以看你的加密方法)就很麻烦了(据说采用什么办法可以解决)。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流