默认头像
卧底
卧底
  • 注册日期2004-04-18
  • 发帖数235
  • QQ
  • 铜币614枚
  • 威望2点
  • 贡献值0点
  • 银元0个
阅读:3378回复:3

[原创]自己做一个SymbolSelector

楼主#
更多 发布于:2007-07-21 11:31

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
 '''


 ''' 如果是Fill Symbols,画RectangleElement
 '''

 '''
 '''
 '''
 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
 '''


 ''' 如果是Marker Symbols,画LineElement
 '''

 '''
 '''
 '''
 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
 '''


 ''' 如果是Marker Symbols,画MarkerElement
 '''

 '''
 '''
 '''
 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),为其他开发者节省时间。

[此贴子已经被作者于2007-7-21 11:38:07编辑过]
喜欢0 评分0
个人专栏: https://zhuanlan.zhihu.com/c_165676639
默认头像
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15951
  • QQ
  • 铜币25345枚
  • 威望15368点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
1楼#
发布于:2007-07-22 13:27

ae9.2提供了符号选择的控件,不过界面还是难看了些,:)

楼主写得比较详细,支持一下!

GIS麦田守望者,期待与您交流。
举报 回复(0) 喜欢(0)     评分
默认头像
卧底
卧底
  • 注册日期2004-04-18
  • 发帖数235
  • QQ
  • 铜币614枚
  • 威望2点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2007-07-22 22:53

嗯,9.2好像是开放了不少,还是要继续学习呵呵

个人专栏: https://zhuanlan.zhihu.com/c_165676639
举报 回复(0) 喜欢(0)     评分
默认头像
路人甲
路人甲
  • 注册日期2007-11-13
  • 发帖数9
  • QQ
  • 铜币140枚
  • 威望0点
  • 贡献值0点
  • 银元0个
3楼#
发布于:2009-11-20 22:47
大哥可以請教一下如何才能實現比例尺選擇器或指北針選擇器感謝
举报 回复(0) 喜欢(0)     评分
默认头像

返回顶部