前两天好不容易搞好了Map与Scene的二三维联动,以为将二维中的线连动到三维中变成3D样式的管子很简单,又卡了。再一次狂乱的在Esri论坛上找答案,有这样的贴子提到如果用SceneControl加载一个sxd文件,然后在上面画线是可以的,便是如何才能让加载shp文件的SceneControl也能画线呢,有很多人都碰到过这个问题。上面有一个贴子结贴后最佳答案是这样说的:
直接 IGraphicsContainer3D gc3d = new GraphicsLayer3DClass(); 在gc3d上画就OK了。
但是说实话,对于新手的我,我真不知道看了这句话,我应该么样去改我的代码。下面贴出摘自网上的一段在SceneControl控件上监听mouseDown事件连续画线的代码,我在这上面纠结了很久。
private void axSceneControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ISceneControlEvents_OnMouseDownEvent e) { IPoint pt = null; ISceneGraph pSG = axSceneControl1.SceneGraph; ISceneViewer pSW = pSG.ActiveViewer; object a; object b; pSG.Locate(pSW, e.x, e.y, esriScenePickMode.esriScenePickAll, true, out pt, out a, out b); if (pt == null) return; ptCol.Add(pt); int i = ptCol.Count; if (i < 1) return; IRgbColor pRgbColor = new RgbColorClass(); pRgbColor.Blue = 255; pRgbColor.Green = 0; pRgbColor.Red = 0; ISimpleLine3DSymbol pSimpleLine3DSymbol = new SimpleLine3DSymbolClass(); pSimpleLine3DSymbol.Style = esriSimple3DLineStyle.esriS3DLSTube; ILineSymbol pLineSymbol = pSimpleLine3DSymbol as ILineSymbol; pLineSymbol.Color = pRgbColor; pLineSymbol.Width = 10; //ILineElement pLineElement = new LineElementClass(); //pLineElement.Symbol = pLineSymbol; //产生线段对象 line ILine pLine = new LineClass(); IPoint fromPt = ptCol[i - 1]; IPoint toPt = ptCol[i - 2]; pLine.PutCoords(fromPt, toPt); //将线段对象添加到多义线对象polyline object Missing1 = Type.Missing; object Missing2 = Type.Missing; ISegment pSegment = pLine as ISegment; m_polyline.AddSegment(pSegment, ref Missing1, ref Missing2); //让Z值生效 IZAware Zaware = m_polyline as IZAware; Zaware.ZAware = true; IGeometry geometry = (IGeometry)m_polyline; //更新到Graphics窗口 IGraphicsContainer3D pGCon3D = axSceneControl1.Scene.BasicGraphicsLayer as IGraphicsContainer3D; IElement pElement = new LineElementClass(); pElement.Geometry = geometry; ILineElement pLineElement = pElement as ILineElement; pLineElement.Symbol = pLineSymbol; pGCon3D.DeleteAllElements(); pGCon3D.AddElement(pElement); axSceneControl1.Scene.SceneGraph.RefreshViewers(); }
是的,这段代码如果 axSceneControl1 加载的是.sxd文件确实可以画。且是画出的就是管子样式的线。那么么样改一下就能让加载.shp文件的axSceneControl1 也可以画呢。看代码:
public Form1() { InitializeComponent(); _axesGraphicsContainer3D = new GraphicsLayer3DClass(); ILayer layer = _axesGraphicsContainer3D as ILayer; layer.Name = "XXX"; this.axSceneControl1.Scene.AddLayer(_axesGraphicsContainer3D as ILayer, true); } private void axSceneControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ISceneControlEvents_OnMouseDownEvent e) { IPoint pt = null; ISceneGraph pSG = axSceneControl1.SceneGraph; ISceneViewer pSW = pSG.ActiveViewer; object a; object b; pSG.Locate(pSW, e.x, e.y, esriScenePickMode.esriScenePickAll, true, out pt, out a, out b); if (pt == null) return; ptCol.Add(pt); int i = ptCol.Count; if (i < 1) return; IRgbColor pRgbColor = new RgbColorClass(); pRgbColor.Blue = 255; pRgbColor.Green = 0; pRgbColor.Red = 0; ISimpleLine3DSymbol pSimpleLine3DSymbol = new SimpleLine3DSymbolClass(); pSimpleLine3DSymbol.Style = esriSimple3DLineStyle.esriS3DLSTube; ILineSymbol pLineSymbol = pSimpleLine3DSymbol as ILineSymbol; pLineSymbol.Color = pRgbColor; pLineSymbol.Width = 10; //ILineElement pLineElement = new LineElementClass(); //pLineElement.Symbol = pLineSymbol; //产生线段对象 line ILine pLine = new LineClass(); IPoint fromPt = ptCol[i - 1]; IPoint toPt = ptCol[i - 2]; pLine.PutCoords(fromPt, toPt); //将线段对象添加到多义线对象polyline object Missing1 = Type.Missing; object Missing2 = Type.Missing; ISegment pSegment = pLine as ISegment; m_polyline.AddSegment(pSegment, ref Missing1, ref Missing2); //让Z值生效 IZAware Zaware = m_polyline as IZAware; Zaware.ZAware = true; IGeometry geometry = (IGeometry)m_polyline; //更新到Graphics窗口 IGraphicsContainer3D pGCon3D = this._axesGraphicsContainer3D; //这一行代码要改 IGraphicsContainer3D pGCon3D = axSceneControl1.Scene.BasicGraphicsLayer as IGraphicsContainer3D; IElement pElement = new LineElementClass(); pElement.Geometry = geometry; ILineElement pLineElement = pElement as ILineElement; pLineElement.Symbol = pLineSymbol; pGCon3D.DeleteAllElements(); pGCon3D.AddElement(pElement); axSceneControl1.Scene.SceneGraph.RefreshViewers(); }
O了,这样,你用SceneControl加载一个中国地图的shp文件进来,再在上面点击鼠标几下试下,就能看到效果了。