阅读:3299回复:3
[原创]自己做一个SymbolSelector
<P>1 Introduction </P>
<P> 在AO下不用我说,大家都会调用ISymbolSelector,那么怎样在<FONT color=#ff0000>AE</FONT>下做一个SymbolSelector。在网上搜了一圈(包括Support.ESRI.com),并没有太多相关的解决方法,看来只有自力更生了。(朱广沪说:只要认真去做,中国人没有做不到的事情)</P> <P>2 First Method</P> <P> 可以采用ISymbol.SetupDC到PictureBox,将Symbol画到PictureBox就OK了,这个也是最常用的方法,估计也是ESRI想让开发者这么做的。(原因1.ESRI暴露了这方面的接口;原因2.ESRI提供了相关的例子)</P> <P> 这种方法在VB6下应该是比较容易做的,如果你在VB6下开发推荐采用这种方法。但到了.NET反而不好实现了,.NET希望你通过System.Drawing.Graphics去画东西,另外.NET中的PictureBox控件并没有暴露hDC(纯属个人猜测,有待大家检验)</P> <P> 另外这种方法有一个缺陷:就是如何让用户在PictureBox控件中选择Symbol,这个实现起来就困难了,需要你去判断Mouse的位置了。</P> <P>3 Second Method</P> <P> 第二种方法也是今天想拿出来与大家交流的方法:就是依旧选择在MapControl中画,也是说你在SymbolSelect对话框中使用MapControl代替PictureBox。这种方法不存在选择Symbol的问题,对于开发者来说在MapControl选择Symbol,应该是小菜了。另外在MapControl画Symbol也不需要我多说了。</P> <P> 但是这种方法也有一个问题,等大家实现了,就可以发现其实画在MapControl上的效果不是很好,因为当你有滚动条时,上滚下滚都导致MapControl的刷新,但是刷新Symbol的效果让人十分郁闷。(目前至少我实现后的效果出现了刷新的问题,如果你有好方法请告知。)</P> <P>下面就实现最关键的部分,其实代码是很简单,要提出的是这里使用的接口都是基于AE的,请放心。尤其要提起的是ServerStyleGallery对应的是以.ServerStyle为后缀名的Style文件(如ESRI.ServerStyle)</P> <P> Private Sub DrawSymbols()<br> If CurSymbol Is Nothing Then Exit Sub<br> Dim pGC As IGraphicsContainer = SymbolMap.Map<br> Dim pStyleGlry As IStyleGallery<br> pStyleGlry = New ServerStyleGallery<br> Dim pStylePath As String 'Add the Civic.style to the IStyleGalleryStorage<br> Dim pStylStor As IStyleGalleryStorage<br> pStylStor = pStyleGlry<br> ''ServerStyle Path<br> pStylePath = My.Application.Info.DirectoryPath ; "\Style\ESRI.ServerStyle"<br> pStylStor.AddFile(pStylePath) 'Locate the first fill<br> Dim pItems As IEnumStyleGalleryItem = Nothing</P> <P> If TypeOf CurSymbol Is IFillSymbol Then<br> pItems = pStyleGlry.Items("Fill Symbols", pStylePath, "Default")<br> ''如果是Fill Symbols,画RectangleElement<br> DrawPolygon(pGC, pItems)<br> ElseIf TypeOf CurSymbol Is IMarkerSymbol Then<br> pItems = pStyleGlry.Items("Marker Symbols", pStylePath, "Default")<br> ''如果是Marker Symbols,画MarkerElement<br> DrawPoint(pGC, pItems)<br> ElseIf TypeOf CurSymbol Is ILineSymbol Then<br> pItems = pStyleGlry.Items("Line Symbols", pStylePath, "Default")<br> ''如果是Marker Symbols,画LineElement<br> DrawLine(pGC, pItems)<br> Else<br> Exit Sub<br> End If<br> Dim env As IEnvelope = New Envelope<br> env.XMin = 0<br> env.YMin = 0<br> env.XMax = 310<br> env.YMax = 300<br> SymbolMap.ActiveView.Extent = env<br> SymbolMap.ActiveView.Refresh()</P> <P> End Sub<br> ''' <summary><br> ''' 如果是Fill Symbols,画RectangleElement<br> ''' </summary><br> ''' <param name="pGC"></param><br> ''' <param name="pItems"></param><br> ''' <remarks></remarks><br> Private Sub DrawPolygon(ByVal pGC As IGraphicsContainer, ByVal pItems As IEnumStyleGalleryItem)<br> Dim pItem As IStyleGalleryItem<br> pItem = pItems.Next</P> <P> Dim i As Integer = 0<br> Dim j As Integer = 0<br> While pItem IsNot Nothing<br> Dim pPolygon As IPolygon = New Polygon<br> Dim pPC As IPointCollection = pPolygon<br> Dim ii As Integer = i \ 6<br> Dim p1 As IPoint = New Point<br> p1.X = 10 + j * 50<br> p1.Y = 10 + ii * 50<br> pPC.AddPoint(p1)<br> Dim p2 As IPoint = New Point<br> p2.X = 10 + j * 50<br> p2.Y = 50 + ii * 50<br> pPC.AddPoint(p2)<br> Dim p3 As IPoint = New Point<br> p3.X = 50 + j * 50<br> p3.Y = 50 + ii * 50<br> pPC.AddPoint(p3)<br> Dim p4 As IPoint = New Point<br> p4.X = 50 + j * 50<br> p4.Y = 10 + ii * 50<br> pPC.AddPoint(p4)</P> <P> Dim pE As IElement = New RectangleElement<br> pE.Geometry = pPolygon<br> Dim pFSE As IFillShapeElement = pE<br> pFSE.Symbol = pItem.Item<br> pgc.AddElement(pE, 0)</P> <P> pItem = pItems.Next<br> i = i + 1<br> ''逢六换行<br> j = (j + 1) Mod 6<br> End While</P> <P> End Sub<br> ''' <summary><br> ''' 如果是Marker Symbols,画LineElement<br> ''' </summary><br> ''' <param name="pGC"></param><br> ''' <param name="pItems"></param><br> ''' <remarks></remarks><br> Private Sub DrawLine(ByVal pGC As IGraphicsContainer, ByVal pItems As IEnumStyleGalleryItem)<br> Dim pItem As IStyleGalleryItem<br> pItem = pItems.Next</P> <P> Dim i As Integer = 0<br> Dim j As Integer = 0<br> While pItem IsNot Nothing</P> <P> Dim pPolyline As IPolyline = New Polyline<br> Dim pPC As IPointCollection = pPolyline<br> Dim ii As Integer = i \ 6<br> Dim p1 As IPoint = New Point<br> p1.X = 10 + j * 50<br> p1.Y = 30 + ii * 50<br> pPC.AddPoint(p1)<br> Dim p2 As IPoint = New Point<br> p2.X = 50 + j * 50<br> p2.Y = 30 + ii * 50<br> pPC.AddPoint(p2)</P> <P> Dim pE As IElement = New LineElement<br> pE.Geometry = pPolyline<br> Dim pLE As ILineElement = pE<br> pLE.Symbol = pItem.Item<br> pGC.AddElement(pE, 0)</P> <P> pItem = pItems.Next<br> i = i + 1<br> ''逢六换行<br> j = (j + 1) Mod 6<br> End While</P> <P> End Sub<br> ''' <summary><br> ''' 如果是Marker Symbols,画MarkerElement<br> ''' </summary><br> ''' <param name="pGC"></param><br> ''' <param name="pItems"></param><br> ''' <remarks></remarks><br> Private Sub DrawPoint(ByVal pGC As IGraphicsContainer, ByVal pItems As IEnumStyleGalleryItem)<br> Dim pItem As IStyleGalleryItem<br> pItem = pItems.Next</P> <P> Dim i As Integer = 0<br> Dim j As Integer = 0<br> While pItem IsNot Nothing</P> <P> Dim ii As Integer = i \ 6<br> Dim p1 As IPoint = New Point<br> p1.X = 30 + j * 50<br> p1.Y = 30 + ii * 50<br></P> <P> Dim pE As IElement = New MarkerElement<br> pE.Geometry = p1<br> Dim pME As IMarkerElement = pE<br> pME.Symbol = pItem.Item<br> pGC.AddElement(pE, 0)</P> <P> pItem = pItems.Next<br> i = i + 1<br> ''逢六换行<br> j = (j + 1) Mod 6<br> End While</P> <P> End Sub </P> <P>4 End</P> <P> 以上都是个人的观点,存在一定的错误和不确定,请大家指正。另外实现SymbolSelect对话框也不只这两种方法,说不定大家已经有好的方法,没拿出来分享而已,希望大家能贡献一些源码(Open Source),为其他开发者节省时间。</P> [此贴子已经被作者于2007-7-21 11:38:07编辑过]
|
|
|
1楼#
发布于:2007-07-22 13:27
<P>ae9.2提供了符号选择的控件,不过界面还是难看了些,:)</P>
<P>楼主写得比较详细,支持一下!</P> |
|
|
2楼#
发布于:2007-07-22 22:53
<P>嗯,9.2好像是开放了不少,还是要继续学习呵呵</P>
|
|
|
3楼#
发布于:2009-11-20 22:47
大哥可以請教一下如何才能實現比例尺選擇器或指北針選擇器感謝
|
|