自己做一个SymbolSelector

来源:互联网 发布:netstat端口占用 编辑:程序博客网 时间:2024/04/28 15:46

1 Introduction      

      在AO下不用我说,大家都会调用ISymbolSelector,那么怎样在AE下做一个SymbolSelector。在网上搜了一圈(包括Support.ESRI.com),并没有太多相关的解决方法,看来只有自力更生了。(某教练说:只要认真去做,中国人没有做不到的事情)

2 First Method

      可以采用ISymbol.SetupDC到PictureBox,将Symbol画到PictureBox就OK了,这个也是最常用的方法,估计也是ESRI想让开发者这么做的。(原因1.ESRI暴露了这方面的接口;原因2.ESRI提供了相关的例子)

      这种方法在VB6下应该是比较容易做的,如果你在VB6下开发推荐采用这种方法。但到了.NET反而不好实现了,.NET希望你通过System.Drawing.Graphics去画东西,另外.NET中的PictureBox控件并没有暴露hDC(纯属个人猜测,有待大家检验)

       另外这种方法有一个缺陷:就是如何让用户在PictureBox控件中选择Symbol,这个实现起来就困难了,需要你去判断Mouse的位置了。

3 Second Method

       第二种方法也是今天想拿出来与大家交流的方法:就是依旧选择在MapControl中画,也是说你在SymbolSelect对话框中使用MapControl代替PictureBox。这种方法不存在选择Symbol的问题,对于开发者来说在MapControl选择Symbol,应该是小菜了。另外在MapControl画Symbol也不需要我多说了。

        但是这种方法也有一个问题,等大家实现了,就可以发现其实画在MapControl上的效果不是很好,因为当你有滚动条时,上滚下滚都导致MapControl的刷新,但是刷新Symbol的效果让人十分郁闷。(目前至少我实现后的效果出现了刷新的问题,如果你有好方法请告知。)

下面就实现最关键的部分,其实代码是很简单,要提出的是这里使用的接口都是基于AE的,请放心。尤其要提起的是ServerStyleGallery对应的是以.ServerStyle为后缀名的Style文件(如ESRI.ServerStyle)

  Private Sub DrawSymbols()
    If CurSymbol Is Nothing Then Exit Sub
    Dim pGC As IGraphicsContainer = SymbolMap.Map
    Dim pStyleGlry As IStyleGallery
    pStyleGlry = New ServerStyleGallery
    Dim pStylePath As String 'Add the Civic.style to the IStyleGalleryStorage
    Dim pStylStor As IStyleGalleryStorage
    pStylStor = pStyleGlry
    ''ServerStyle Path
    pStylePath = My.Application.Info.DirectoryPath & "/Style/ESRI.ServerStyle"
    pStylStor.AddFile(pStylePath) 'Locate the first fill
    Dim pItems As IEnumStyleGalleryItem = Nothing

    If TypeOf CurSymbol Is IFillSymbol Then
      pItems = pStyleGlry.Items("Fill Symbols", pStylePath, "Default")
      ''如果是Fill Symbols,画RectangleElement
      DrawPolygon(pGC, pItems)
    ElseIf TypeOf CurSymbol Is IMarkerSymbol Then
      pItems = pStyleGlry.Items("Marker Symbols", pStylePath, "Default")
      ''如果是Marker Symbols,画MarkerElement
      DrawPoint(pGC, pItems)
    ElseIf TypeOf CurSymbol Is ILineSymbol Then
      pItems = pStyleGlry.Items("Line Symbols", pStylePath, "Default")
      ''如果是Marker Symbols,画LineElement
      DrawLine(pGC, pItems)
    Else
      Exit Sub
    End If
    Dim env As IEnvelope = New Envelope
    env.XMin = 0
    env.YMin = 0
    env.XMax = 310
    env.YMax = 300
    SymbolMap.ActiveView.Extent = env
    SymbolMap.ActiveView.Refresh()

  End Sub
  ''' <summary>
  ''' 如果是Fill Symbols,画RectangleElement
  ''' </summary>
  ''' <param name="pGC"></param>
  ''' <param name="pItems"></param>
  ''' <remarks></remarks>
  Private Sub DrawPolygon(ByVal pGC As IGraphicsContainer, ByVal pItems As IEnumStyleGalleryItem)
    Dim pItem As IStyleGalleryItem
    pItem = pItems.Next

    Dim i As Integer = 0
    Dim j As Integer = 0
    While pItem IsNot Nothing
      Dim pPolygon As IPolygon = New Polygon
      Dim pPC As IPointCollection = pPolygon
      Dim ii As Integer = i / 6
      Dim p1 As IPoint = New Point
      p1.X = 10 + j * 50
      p1.Y = 10 + ii * 50
      pPC.AddPoint(p1)
      Dim p2 As IPoint = New Point
      p2.X = 10 + j * 50
      p2.Y = 50 + ii * 50
      pPC.AddPoint(p2)
      Dim p3 As IPoint = New Point
      p3.X = 50 + j * 50
      p3.Y = 50 + ii * 50
      pPC.AddPoint(p3)
      Dim p4 As IPoint = New Point
      p4.X = 50 + j * 50
      p4.Y = 10 + ii * 50
      pPC.AddPoint(p4)

      Dim pE As IElement = New RectangleElement
      pE.Geometry = pPolygon
      Dim pFSE As IFillShapeElement = pE
      pFSE.Symbol = pItem.Item
      pgc.AddElement(pE, 0)

      pItem = pItems.Next
      i = i + 1
      ''逢六换行
      j = (j + 1) Mod 6
    End While

  End Sub
  ''' <summary>
  ''' 如果是Marker Symbols,画LineElement
  ''' </summary>
  ''' <param name="pGC"></param>
  ''' <param name="pItems"></param>
  ''' <remarks></remarks>
  Private Sub DrawLine(ByVal pGC As IGraphicsContainer, ByVal pItems As IEnumStyleGalleryItem)
    Dim pItem As IStyleGalleryItem
    pItem = pItems.Next

    Dim i As Integer = 0
    Dim j As Integer = 0
    While pItem IsNot Nothing

      Dim pPolyline As IPolyline = New Polyline
      Dim pPC As IPointCollection = pPolyline
      Dim ii As Integer = i / 6
      Dim p1 As IPoint = New Point
      p1.X = 10 + j * 50
      p1.Y = 30 + ii * 50
      pPC.AddPoint(p1)
      Dim p2 As IPoint = New Point
      p2.X = 50 + j * 50
      p2.Y = 30 + ii * 50
      pPC.AddPoint(p2)

      Dim pE As IElement = New LineElement
      pE.Geometry = pPolyline
      Dim pLE As ILineElement = pE
      pLE.Symbol = pItem.Item
      pGC.AddElement(pE, 0)

      pItem = pItems.Next
      i = i + 1
      ''逢六换行
      j = (j + 1) Mod 6
    End While

  End Sub
  ''' <summary>
  ''' 如果是Marker Symbols,画MarkerElement
  ''' </summary>
  ''' <param name="pGC"></param>
  ''' <param name="pItems"></param>
  ''' <remarks></remarks>
  Private Sub DrawPoint(ByVal pGC As IGraphicsContainer, ByVal pItems As IEnumStyleGalleryItem)
    Dim pItem As IStyleGalleryItem
    pItem = pItems.Next

    Dim i As Integer = 0
    Dim j As Integer = 0
    While pItem IsNot Nothing

      Dim ii As Integer = i / 6
      Dim p1 As IPoint = New Point
      p1.X = 30 + j * 50
      p1.Y = 30 + ii * 50

      Dim pE As IElement = New MarkerElement
      pE.Geometry = p1
      Dim pME As IMarkerElement = pE
      pME.Symbol = pItem.Item
      pGC.AddElement(pE, 0)

      pItem = pItems.Next
      i = i + 1
      ''逢六换行
      j = (j + 1) Mod 6
    End While

  End Sub        

4 End

         以上都是个人的观点,存在一定的错误和不确定,请大家指正。另外实现SymbolSelect对话框也不只这两种方法,说不定大家已经有好的方法,没拿出来分享而已,希望大家能贡献一些源码(Open Source),为其他开发者节省时间。

 
原创粉丝点击