一种低成本构建有线电视用户地理信息系统的方法

一种低成本构建有线电视地理信息系统的方法

 

 

欧剑平

 

 

 

 

   有线电视用户地理信息系统是综合利用计算机图形、数据库、网络等技术完成有线电视用户地理信息的录入、编辑、查询、统计等功能的系统,能对用户所处的小区、楼栋、单元、楼层等地理信息提供标准的格式化的描述,避免用户地理信息的多样性和不一致性,保证地址信息的唯一性,从而提高用户资料的准确、可用性,并为客户服务工作的快捷开展提供便利。

   有线电视用户地理信息系统至少应该包括地理信息图形库子系统、地理信息词典库子系统、用户信息库子系统和相关的应用程序子系统,其中建立地理信息图形库子系统是一项高成本的系统工程,不仅需专业的技术队伍,更需要大量的人力物力和较长的生产周期,而且还要根据实际变化不断更新的地理图形,一般有线电视运营商很难能做到这一点,所以目前能实现有线电视地理信息系统的并不多见。利用三方提供的现成的专业地图服务来建立地理信息图形库子系统则能大幅降低成本,以下提供一些基本思路和一些具体的实现细节。

   目前互联网上“图行天下”、“三维城市”等地图信息服务为构建地理信息图形库提供了一个非常便利的图形资料来源,通过一些截图软件(如HyperSnap)和图像处理软件(如Photoshop)即可轻易获取局部地图从而拼接形成需要的整体地图。一般来说,大中城市可获得三维立体式的图像,而较小的城市、城镇、农村则可获得效果较差的二维图像,这些图像对有线电视用户地理信息系统来说是够用的。虽然这些图像为位图图像,但目前计算机的性能不断提高,就算图像的尺寸很大,显示的也速度是很快的,如用本文介绍的程序从一台普通的微机从一台一般的服务器上调出并显示一幅11583×5027像素的24位全彩位图地图仅需几秒钟的时间,调出后缩放和平移的响应非常快,远非在互联网上类似操作可比。另外通过图像处理软件(如图Photoshop)可方便地不断对地图中已经发生变化了的地方进行编辑更新,使这些地理信息图形库一直保持与实际相符。当然获取、使用这些地图信息应取得相关地图运营商的许可,且应该考虑到不能侵害这些地图运营商的利益。

   按上述方法在服务器上建立了地理信息图形库后,如何实现实现在客户端浏览这些地图?而又不能让客户端的用户直接拷贝获取这些图像的文件。为了实现这个目的,可采用隐式共享的方式(在Windows Server 2003中的具体做法是在建立共享时在共享名后加“$”符号)来设置服务器中图像文件所在的文件夹,通常这个共享名是不为普通用户所知的,但却可以在应用程序中植入该共享名来访问和显示这些的图像,同时这类程序应该具备在视窗中平移、缩放这些图像的功能。下面介绍用VB 6.0来实现这一点的方法。

    首先在本机d 盘建立一个文件夹名“大理”,在其下建立一个文件夹名为“城区”,并将拼成的图形文件以jpg格式保存在这里,命名为1.jpg,同城将该文件横向象素和纵向象素各减少一半后存储为2.jpg,再减少一半后存储为4.jpg,依次产生16.jpg32.jpg等文件。如下图:

   以上这些图像包括的区域范围是一致的,但实际象素则依次倍减,这可用Photoshop做到。

   VB中建立一个“标准EXE”工程,将窗体Form1ScaleMode属性置为“3-Pixel,在窗体中增加一个PictureBox控件、一个Timer控件,一个水平滑块控件,一个垂直滑块控制和一个命令按钮控件,各控件名称均取系统默认值,各控件的位置布局大略如下图如示,(为节省篇幅,故意将窗体尺寸设置为很小,实际应用中可根据需要自行设置窗体尺寸)。将命令按钮控件的Caption属性置为“*”,将PictureBox控件的BoaderStyle属性置为“0-None"Timer控件的Interval属性置为500

 

 

键入以下程序后,运行,地图以最小比例显示在窗体中,如下图(考虑版面有限,图中的PictureBox尺寸故意设置得很小,在实际应用中一般都要有屏幕80%左右的大小),这时可通过键盘的方向键或鼠标拖曳的方式对地图进行平移操作,也可通过拖动水平和垂直滑块来实现地图平移;还可通过数字键盘上的加号键和减号键实现地图的中点缩放。通过单击右下角的“*”按钮实现地图位置的复位。

 

Option Explicit

Private mintCoordinateX, mintCoordinateY As Integer

Private mintCoordinatexMove, mintCoordinateYMove As Integer

Private mintImageWidth(6), mintImageHeight(6) As Integer

Private mZoomRate As Single

Private mZoomGrade As Integer

Private mMemdc(6) As Long

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, _

ByVal nCount As Long, lpObject As Any) As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, _

ByVal hObject As Long) As Long

Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long

Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, _

ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _

ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, _

ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _

ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, _

ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long

Private Type BITMAP

        bmType As Long

        bmWidth As Long

        bmHeight As Long

        bmWidthBytes As Long

        bmPlanes As Integer

        bmBitsPixel As Integer

        bmBits As Long

End Type

 

Private Sub Command1_Click()

    HScroll1.Value = 0: VScroll1.Value = 0

End Sub

 

Private Sub Form_Load()

    mZoomRate = 1 / 16

    mZoomGrade = 5

    Dim bm As BITMAP

    Dim picCurrentPicture(6) As Picture

    Dim i As Integer

   

    For i = 1 To 6

     Set picCurrentPicture(i) = _

     LoadPicture("d:/大理/城区" & "/" & Trim(Str(2 ^ (i - 1))) & ".jpg")

     mMemdc(i) = CreateCompatibleDC(Picture1.hdc)

     GetObject picCurrentPicture(i).Handle, LenB(bm), bm

     mintImageWidth(i) = bm.bmWidth

     mintImageHeight(i) = bm.bmHeight

     SelectObject mMemdc(i), picCurrentPicture(i).Handle

     Set picCurrentPicture(i) = Nothing

    Next i

       HScroll1.Max = mintImageWidth(mZoomGrade) / 2

       HScroll1.Min = -mintImageWidth(mZoomGrade) / 2

       VScroll1.Max = mintImageHeight(mZoomGrade) / 2

       VScroll1.Min = -mintImageHeight(mZoomGrade) / 2

    Exit Sub

   

    For i = 1 To 6

    DeleteDC mMemdc(i)

      Set picCurrentPicture(i) = Nothing

    Next i

 

End Sub

Private Sub DisplayImage()

    Picture1.Cls

    StretchBlt Picture1.hdc, Picture1.Width / 2 - mintCoordinateX - _

    mintImageWidth(mZoomGrade) / 2, Picture1.Height / 2 - _

    mintCoordinateY - mintImageHeight(mZoomGrade) / 2, _

    mintImageWidth(mZoomGrade), mintImageHeight(mZoomGrade), _

    mMemdc(mZoomGrade), 0, 0, mintImageWidth(mZoomGrade), _

    mintImageHeight(mZoomGrade), vbSrcCopy

End Sub

Private Sub Form_Unload(Cancel As Integer)

    Dim i As Integer

    For i = 1 To 6

     DeleteDC mMemdc(i)

    Next i

End Sub

Private Sub Picture1_DragDrop(Source As Control, X As Single, Y As Single) '拖曳地图

    Dim temp As Integer

    temp = VScroll1.Value + (mintCoordinateYMove - Y) / 10

    If temp <= VScroll1.Min Then temp = VScroll1.Min

    If temp >= VScroll1.Max Then temp = VScroll1.Max

    VScroll1.Value = temp

    temp = HScroll1.Value + (mintCoordinatexMove - X) / 10

    If temp <= HScroll1.Min Then temp = HScroll1.Min

    If temp >= HScroll1.Max Then temp = HScroll1.Max

    HScroll1.Value = temp

End Sub

Private Sub Picture1_KeyDown(KeyCode As Integer, Shift As Integer) '键盘控制地图

    Dim steppix As Integer

    Dim CurrentHScroll1 As Integer

    Dim CurrentVScroll1 As Integer

    steppix = 10            '平移速度控制因子

    Select Case KeyCode

      Case vbKeyLeft       '左方向键使地图在视图中右移

      HScroll1.Value = IIf(HScroll1.Value - steppix < HScroll1.Min, HScroll1.Min, HScroll1.Value - steppix)

      Case vbKeyRight      '右方向键使地图在视图中左移

      HScroll1.Value = IIf(HScroll1.Value + steppix > HScroll1.Max, HScroll1.Max, HScroll1.Value + steppix)

      Case vbKeyUp         ' 上方向键使地图在视图中下移

      VScroll1.Value = IIf(VScroll1.Value - steppix < VScroll1.Min, VScroll1.Min, VScroll1.Value - steppix)

      Case vbKeyDown       '下方向键使地图在视图中上移

      VScroll1.Value = IIf(VScroll1.Value + steppix > VScroll1.Max, VScroll1.Max, VScroll1.Value + steppix)

     

      Case vbKeyAdd       '加号键放大地图显示

      If mZoomRate < 1 Then

       mZoomRate = mZoomRate * 2: mZoomGrade = mZoomGrade - 1

       CurrentHScroll1 = HScroll1.Value: CurrentVScroll1 = VScroll1.Value

       HScroll1.Max = HScroll1.Max * 2: HScroll1.Min = HScroll1.Min * 2:  HScroll1.Value = CurrentHScroll1 * 2

       VScroll1.Max = VScroll1.Max * 2: VScroll1.Min = VScroll1.Min * 2: VScroll1.Value = CurrentVScroll1 * 2 - 1

      Call DisplayImage

      End If

      

       Case vbKeySubtract   '减号键缩小地图显示

       If mZoomRate > 1 / 32 Then

       mZoomRate = mZoomRate / 2: mZoomGrade = mZoomGrade + 1

       CurrentHScroll1 = HScroll1.Value: CurrentVScroll1 = VScroll1.Value

       HScroll1.Max = HScroll1.Max / 2: HScroll1.Min = HScroll1.Min / 2: HScroll1.Value = CurrentHScroll1 / 2

       VScroll1.Max = VScroll1.Max / 2: VScroll1.Min = VScroll1.Min / 2: VScroll1.Value = CurrentVScroll1 / 2

       Call DisplayImage

      End If

     End Select

End Sub

 

Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) '拖曳地图

    mintCoordinatexMove = X

    mintCoordinateYMove = Y

    Picture1.Drag

End Sub

 

Private Sub Timer1_Timer()

    Call DisplayImage

    Picture1.SetFocus

    Timer1.Enabled = False

End Sub

 

Private Sub VScroll1_change()   '通过垂直滑块上下移动地图

    mintCoordinateY = VScroll1.Value

    Call DisplayImage

    Picture1.SetFocus

End Sub

 

Private Sub HScroll1_change()   '通过水平滑块水平移动地图

    mintCoordinateX = HScroll1.Value

    Call DisplayImage

    Picture1.SetFocus

End Sub

 

 

   在实际应用中,

LoadPicture("d:/大理/城区" & "/" & Trim(Str(2 ^ (i - 1))) & ".jpg")

   语句应该采用隐式的方式来访问被设置为服务器的计算机的某个共享文件夹,比如写为:

LoadPicture("//zfwq/gismaplib$" & "/大理/城区" & Trim(Str(2 ^ (i - 1))) & ".jpg")

   其中“zfwq”是服务器名,“gismaplib$”是共享名(该共享名对普通用户来说是透明和不可见,只有应用程序“知道”)。这样用户虽能显示图像却不知道图像到底存储在哪里,也就不可能获取这些图像文件了。

   当然,还应结合SQL等技术建立地理信息词典、用户信息库等子系统,编制其他模块程序实现地图中地址的实时显示、查询、编辑等功能,因幅有限,不再赘述,如有兴趣可与笔者联系。

   因时间仓促及本人水平有限,文中不当之处定然很多,恳请同行指正。另外实现用户地理信息系统的方法很多,以上仅为其中一种低成本的可用的实现方式,不足之处,恳请指正。

 

 

 

 

                                       

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值