自己动手,做个GIS平台(1)-位图基础

前端之家收集整理的这篇文章主要介绍了自己动手,做个GIS平台(1)-位图基础前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

现在市面上GIS产品已经很丰富了,为什么还要自己动手做一个呢?你看到这个标题,并点开它,说明你感兴趣。作为技术人员,只要有兴趣,这就足够了,“不要问为什么”。如果非要给个理由的话,那就是市面上的GIS产品都做得太复杂、太难用,学会使用它所花的时间,不会比自己动手做一个所花的时间少,当然前提是你写代码够快。

至于最终写出来的东西能做什么用?这好比是屠龙术,会不会屠龙术是技能问题;找得到找不到龙来屠,那是人品问题。这里只能帮忙解决点技能问题,人品问题那只能靠你自己!如果实在找不到龙,找只猪来替代也行,会屠龙的人多了,杀猪市场的竞争压力可能就不会那么大。

本文主要根据GIS平台的大体实现步骤来描述,偏向于纸上谈兵,当然了,会有少量代码辅助解说。个人认为vb.net语言是很简便的开发语言,最容易理解,因此演示代码使用vb.net语言(VS2008 express、.net2.0)。若实际开发的话,建议使用开发原生程序的工具,如VC(本人是用VC来开发)、Delphi等,因为性能是软件产品里的生命线。人生苦短,让用户坐在电脑前,等待软件蜗牛般的处理,那无异于谋杀,程序员很可能是这个时代最疯狂的杀手。

这里所介绍的内容只在window和winmobile系统上检验过,理论上说,也适合其它平台,信不信由你。

除了开发工具,在图形库上,2D选用gdi+,3D则采用directx,选它们是因为都是WIN操作系统里现成的。你可以根据自己爱好选择不同的图形库,如OpenGL等,没什么限制。

1、图形概念

开发GIS的核心是什么,当然是图形了。GIS软件从本质上说和其它常用图形软件如AutoCAD没什么不同,只不过GIS除了图形外,有很多地理属性信息,行业专业性强一点而已。所以虽然主题是“做个GIS平台”,其实能做个GIS平台,改去做CAD平台也没什么困难。

图形有很多种分法,开发中主要用的是“位图”和“矢量图”这两种概念。简单举例说,photoshop软件处理的就是位图,AutoCAD处理的就是矢量图。

1.1、位图

在GIS里,位图处理比较简单,大多数动作就是载入图片,作为底图,在对应位置显示出来就行。通常直接调用图形库对应功能就可以了。

在VB窗口里显示张航拍图片,如google地图上的影象图片

A、 新建一个VB窗口应用工程HateMap项目,系统会自动建一个窗口Form1,此项目可直接运行。

B、 修改Form1名称为FormMain,做为显示主窗口。给各个对象起个容易识别的名称是个好习惯,可避免很多不必要麻烦。编码规范很重要,有时能决定产品的生死存亡。

C、 增加个按钮,命名ButtonPng,双击此按钮,输入代码

    ''' <summary>在0,0位置开始绘制影象图片</summary>
    Private Sub ButtonPng_Click(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles ButtonPng.Click
        Dim imgPng As Image = Image.FromFile("c:\trstrtqss.png") '载入影象图片,假设图片已在C盘

        Dim grDraw As Graphics = Graphics.FromHwnd(Me.Handle) '把当前窗口当做画布
        grDraw.Clear(Color.White) '底色改为白色
        grDraw.DrawImage(imgPng,0) '0,0位置开始画上图片

        '资源释放,说明:.net平台上很多对象类为了省事,都是对WIN原生dll直接封装,这部分对象资源没法自动回收,需要使用者手动释放。
        '一个简单原则,只要类有提供Dispose函数,那对应的对象实例用完后,调用下Dispose。
        '更稳妥的方式,是在Try Finally里保证释放。本文只是提供演示代码,一切从简。
        imgPng.Dispose()
        grDraw.Dispose()
    End Sub

D、 运行效果


代码里可看到,窗口左上角为起始坐标(0,0),X轴向右正方向,Y轴向下正方向,与笛卡儿坐标不同。如下图所示:


上面代码虽然能把影象显示出来,可是问题多多,比如切换下窗口,在回到此窗口,就发现什么都没了。那是因为窗口被别的窗口覆盖后,此窗口被覆盖的地方就变成了脏区域,重新显示此窗口时,这些区域需要重新绘制(具体内容请参考window相关编程资料,推荐《Programming Windows》)。所以,要在Paint事件里重新绘制。此外,显示区域一般为独立的区域,而上面例子中按钮直接覆盖在图片上。一般做法是新增加个Panel控件(示例里命名为PanelView)来替代Form做为显示区域。

修改后的代码如下:

 Public Class FormMain
    '图形不直接绘制在控件上,而是绘制在内存图片上。
    '这样做的好处首先不需要重复画,只要绘制一次就够了;
    '其次,实现双缓存机制,频繁显示时屏幕不会闪。
    Dim imgMain As Bitmap
    Dim grImg As Graphics '指向imgMain
    Dim grPanel As Graphics '指向控件PanelView

    ''' <summary>在0,ByVal e As System.EventArgs) Handles ButtonPng.Click
        '已初始化并显示,直接退出
        If imgMain IsNot Nothing Then
            Return
        End If

        Dim imgPng As Image = Image.FromFile("c:\trstrtqss.png") '载入影象图片,假设图片已在C盘

        '创建与PanelView同样大小内存图片
        imgMain = New Bitmap(PanelView.Width,PanelView.Height)
        grImg = Graphics.FromImage(imgMain)
        grImg.Clear(Color.White) '底色改为白色
        grImg.DrawImage(imgPng,0位置开始画上图片

        grPanel = Graphics.FromHwnd(PanelView.Handle) '把PanelView控件区域当做画布
        grPanel.DrawImage(imgMain,0)
        '资源释放
        imgPng.Dispose()
    End Sub

    ''' <summary>刷新</summary>
    Private Sub FormMain_Paint(ByVal sender As System.Object,ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        If imgMain IsNot Nothing Then
            grPanel.DrawImage(imgMain,0)
        End If
    End Sub

    ''' <summary>退出是释放资源</summary>
    Private Sub FormMain_FormClosed(ByVal sender As System.Object,ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
        If imgMain IsNot Nothing Then
            grPanel.Dispose()
            grImg.Dispose()
            imgMain.Dispose()
        End If
    End Sub
End Class

运行结果如下:


当然这是最简陋的界面,但对于示例来说基本框架有了,界面越简单越好,正常程序要包括菜单、工具栏、状态栏等标准界面。

其实上面程序还是问题多多,比如改变窗口大小,把窗口最大化,就会发现绘制区域没按想象那样延伸。这就涉及到Resize事件处理,你可以自己改改看。

地理信息里卫星图片、航拍图片就是位图,这些数据处理麻烦的地方在于投影坐标转换、比例调整等,更多的是地理专业上的处理。从严格意义上说这与软件关系不大,只要照着地图商提供的参数转换、切割、拼接就行。不过,这种数据量都很大,如何有效管理是个问题。

猜你在找的VB相关文章