/// <summary> /// 通过鼠标点击获取观察点与被观察点同时进行两点间通视分析 /// </summary> /// <param name="Button"></param> /// <param name="Shift"></param> /// <param name="X"></param> /// <param name="Y"></param> public override void OnMouseDown(int Button, int Shift, int X, int Y) { if (m_frm3DLineOfSight.m_Layer == null || m_frm3DLineOfSight.m_Surface == null) { MessageBox.Show("请设置有效的表面数据", "提示!"); return; } if (m_frm3DLineOfSight.txtObsOffset.Text == "" || m_frm3DLineOfSight.txtTarOffset.Text == "") { MessageBox.Show("观察点高度和被观察点高度不能为空", "提示!"); return; } m_frm3DLineOfSight.TopMost = true; ISceneGraph pSceneGraph = m_sceneHookHelper.SceneGraph; m_pNewLineFeedback = new NewLineFeedbackClass(); IPolyline pPolyline = m_pNewLineFeedback.Stop(); //用于判断是否已经获取两点 ISceneControl pSceneControl = m_sceneHookHelper.Hook as ISceneControl; Cls3DModulsefun pCls3DModulsefun = new Cls3DModulsefun(); //用于绘制通视分析结果的方法 object pOwner; object pObject; ESRI.ArcGIS.Geometry.IPoint pPoint = new ESRI.ArcGIS.Geometry.PointClass(); pSceneGraph.Locate(pSceneGraph.ActiveViewer, X, Y, esriScenePickMode.esriScenePickGeography, true, out pPoint, out pOwner, out pObject);//获取鼠标点击的位置并转化为地理坐标 if (pPoint == null) { return; } ESRI.ArcGIS.Geometry.IPoint pFlashPoint = new ESRI.ArcGIS.Geometry.PointClass(); IClone pClone = pPoint as IClone; pFlashPoint = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; pFlashPoint.Z = pFlashPoint.Z / pSceneGraph.VerticalExaggeration; pFlashPoint.SpatialReference = pSceneGraph.Scene.SpatialReference; IDisplay3D pDisplay = pSceneGraph as IDisplay3D; pDisplay.FlashLocation(pFlashPoint);//闪烁显示被点击的位置 IGeometry pGeometry = null; if (m_pScenePoints == null) { m_pScenePoints = new PolylineClass(); pGeometry = m_pScenePoints as IGeometry; pGeometry.SpatialReference = pSceneGraph.Scene.SpatialReference; } object before = Type.Missing; object after = Type.Missing; m_pScenePoints.AddPoint(pPoint, ref before, ref after);//添加获取的点到点集合中 if (m_pScenePoints.PointCount == 2) { pClone = m_pScenePoints as IClone; pPolyline = pClone.Clone() as ESRI.ArcGIS.Geometry.IPolyline;//当点集合中点数达到两个时生成一条线用于判断观察点与被观察点是否确定 m_pScenePoints = null; } if (pPolyline != null) { m_pScenePoints = null; ISurface pSurface = m_SurFace; ESRI.ArcGIS.Geometry.IPoint fPoint = pPolyline.FromPoint; //获取观察点 fPoint.Z = pSurface.GetElevation(fPoint); //获取观察点的高程 ESRI.ArcGIS.Geometry.IPoint tPoint = pPolyline.ToPoint; tPoint.Z = pSurface.GetElevation(tPoint); if (pSurface.IsVoidZ(fPoint.Z) || pSurface.IsVoidZ(tPoint.Z)) { return; } fPoint.Z = fPoint.Z + Convert.ToDouble(m_frm3DLineOfSight.txtObsOffset.Text);//观察者的高度加上观察者所在的高程才是观察点实际的高程 tPoint.Z = tPoint.Z + Convert.ToDouble(m_frm3DLineOfSight.txtTarOffset.Text); ESRI.ArcGIS.Geometry.IPoint pObstruct; IPolyline pVisPolyline; IPolyline pInVisPolyline; bool bIsVis; object pRefractionFactor = Type.Missing; //进行两点间的通视分析 pSurface.GetLineOfSight(fPoint, tPoint, out pObstruct, out pVisPolyline, out pInVisPolyline, out bIsVis, m_frm3DLineOfSight.checkBoxCurv.Checked, m_frm3DLineOfSight.checkBoxCurv.Checked, ref pRefractionFactor); ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbolClass(); pSimpleLineSymbol.Width = 2; pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid; //绘制可视与不可视的沿地表线要素 if (pVisPolyline != null) { pSimpleLineSymbol.Color = Cls3DMarkDraw.getRGB(0, 255, 0); pCls3DModulsefun.AddGraphic(pSceneControl, pVisPolyline as IGeometry, pSimpleLineSymbol as ISymbol); } if (pInVisPolyline != null) { pSimpleLineSymbol.Color = Cls3DMarkDraw.getRGB(255, 0, 0); pCls3DModulsefun.AddGraphic(pSceneControl, pInVisPolyline as IGeometry, pSimpleLineSymbol as ISymbol); } IGeometryCollection pVisPatch = new MultiPatchClass();//用于存储可视域的要素 pGeometry = pVisPatch as IGeometry; pGeometry.SpatialReference = pSceneGraph.Scene.SpatialReference; double dTargetHeightForVis = 0; ISimpleFillSymbol pSimpleFillSymbol = new SimpleFillSymbolClass(); IGeometryCollection pInVisPatch = new MultiPatchClass();//存储不可视域的要素 pGeometry = pInVisPatch as IGeometry; pGeometry.SpatialReference = pSceneGraph.Scene.SpatialReference; IGeometryCollection pPathGeo = pInVisPolyline as IGeometryCollection; if (pPathGeo != null) { //下面的作用是将不可视域线每段path生成线要素进行绘制 张琪 20110623 for (int i = 0; i < pPathGeo.GeometryCount; i++) { IGeometryCollection pInPolyline = new PolylineClass(); IPath path = pPathGeo.get_Geometry(i) as IPath; pInPolyline.AddGeometry(path as IGeometry, ref before, ref after); pCls3DModulsefun.CreateVerticalLOSPatches(bIsVis, fPoint, tPoint, pVisPolyline, pInPolyline as IPolyline, pVisPatch, pInVisPatch, dTargetHeightForVis); } } else//当不可视域为空时,直接分析生成可视域与不可视域 { pCls3DModulsefun.CreateVerticalLOSPatches(bIsVis, fPoint, tPoint, pVisPolyline, pInVisPolyline, pVisPatch, pInVisPatch, dTargetHeightForVis); } // // 对可视域与不可视域要素在场景中绘制出来 if (pInVisPatch != null) { pSimpleFillSymbol.Color = Cls3DMarkDraw.getRGB(255, 0, 0); pCls3DModulsefun.AddGraphic(pSceneControl, pInVisPatch as IGeometry, pSimpleFillSymbol as ISymbol); } if (pVisPatch != null) { pSimpleFillSymbol.Color = Cls3DMarkDraw.getRGB(0, 255, 0); pCls3DModulsefun.AddGraphic(pSceneControl, pVisPatch as IGeometry, pSimpleFillSymbol as ISymbol); } } }
private void btnSure_Click(object sender, EventArgs e) { SysCommon.CProgress vProgress = new SysCommon.CProgress("进度条"); try { if (comboBoxOpen.Text == "") { MessageBox.Show("请选择数据!", "提示!"); return; } if (txtZFactor.Text == "") { MessageBox.Show("请设置Z值参数!", "提示!"); return; } if (txtCellSize.Text == "") { MessageBox.Show("请设置输出精度参数!", "提示!"); return; } if (txtSave.Text == "") { MessageBox.Show("请输入保存文件名!", "提示!"); return; } string Unit; if (radioBtnDegree.Checked) { Unit = "DEGREE"; } else { Unit = "PERCENT"; } //this.Hide(); //Progress.FormProgress vProgress.EnableCancel = false;//设置进度条 vProgress.ShowDescription = true; vProgress.FakeProgress = true; vProgress.TopMost = true; vProgress.ShowProgress(); vProgress.SetProgress("正在进行坡度分析"); ILayer pLayer = GetLayerByName(ref fileName);//根据图层名获取图层 IGeoDataset pGeoDataset = pLayer as IGeoDataset; ISurfaceOp pSurfaceOp; IRasterAnalysisEnvironment pRasterAnalysisEnvironment = new RasterSurfaceOp(); pSurfaceOp = pRasterAnalysisEnvironment as ISurfaceOp; object pObject = Convert.ToDouble(txtCellSize.Text); object pZFactor = Convert.ToDouble(txtZFactor.Text); pRasterAnalysisEnvironment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref pObject); //设置输出数据的像元值大小 IWorkspaceFactory pWorkspaceFactory = new RasterWorkspaceFactoryClass(); string OutPath = System.IO.Path.GetDirectoryName(txtSave.Text); //输出文件存储的目录信息 string TempPath = string.Concat(System.IO.Path.GetDirectoryName(Application.ExecutablePath), "\\Temp\\"); //临时文件存储位置 if (!Directory.Exists(TempPath)) { Directory.CreateDirectory(TempPath);// 当路径不存在时创建临时文件存储路径 } IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(TempPath, 0); pRasterAnalysisEnvironment.OutWorkspace = pWorkspace; IRasterBandCollection pRasterBandCollection; string Newfile = System.IO.Path.GetFileName(txtSave.Text); if (pGeoDataset is IRasterLayer) { IRasterLayer pRasterLayer = pLayer as IRasterLayer; pGeoDataset = (IGeoDataset)pRasterLayer.Raster; if (Unit == "DEGREE")//选择不同单位进行坡度分析 { pRasterBandCollection = pSurfaceOp.Slope(pGeoDataset, esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopeDegrees, ref pZFactor) as IRasterBandCollection; } else { pRasterBandCollection = pSurfaceOp.Slope(pGeoDataset, esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopePercentrise, ref pZFactor) as IRasterBandCollection; } pWorkspace = pWorkspaceFactory.OpenFromFile(OutPath, 0); pRasterBandCollection.SaveAs(Newfile, pWorkspace, RasterType); //保存分析结果到固定路径下 vProgress.Close(); if (MessageBox.Show("坡度分析成功,是否加载分析结果", "提示!", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { vProgress.ShowProgress(); vProgress.SetProgress("正在进行加载结果数据"); IRasterWorkspace pRasterWorkspace = pWorkspaceFactory.OpenFromFile(OutPath, 0) as IRasterWorkspace; // 张琪 20110613 IRasterDataset pRasterDataset = pRasterWorkspace.OpenRasterDataset(System.IO.Path.GetFileName(txtSave.Text)); //包含扩展名的表面数据集 IRasterLayer pOutRasterLayer = new RasterLayerClass(); pOutRasterLayer.CreateFromDataset(pRasterDataset); m_pCurrentSceneControl.Scene.AddLayer(pOutRasterLayer as ILayer, true); vProgress.Close(); } System.Runtime.InteropServices.Marshal.ReleaseComObject(pRasterBandCollection); } else if (pGeoDataset is ITinLayer) { ITinLayer pTinLayer = pGeoDataset as ITinLayer; ITinAdvanced pTinAdvanced = pTinLayer.Dataset as ITinAdvanced; Cls3DModulsefun pCls3DModulsefun = new Cls3DModulsefun(); IRasterDataset pRasterDataset; esriRasterizationType pesriRasterizationType; if (Unit == "DEGREE") { pesriRasterizationType = esriRasterizationType.esriDegreeSlopeAsRaster; } else { pesriRasterizationType = esriRasterizationType.esriPercentageSlopeAsRaster; } rstPixelType prstPixelType = rstPixelType.PT_LONG; //TIN数据转换成Raster数据并进行坡度分析(暂时未成功) vProgress.Close(); pRasterDataset = pCls3DModulsefun.TinToRaster2(pTinAdvanced, pesriRasterizationType, OutPath, Newfile, prstPixelType, Convert.ToDouble(txtCellSize.Text), pTinAdvanced.Extent, true, RasterType); if (MessageBox.Show("坡度分析成功,是否加载分析结果", "提示!", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { IRasterLayer pOutRasterLayer = new RasterLayerClass(); pOutRasterLayer.CreateFromDataset(pRasterDataset); m_pCurrentSceneControl.Scene.AddLayer(pOutRasterLayer as ILayer, true); if (this.WriteLog) { Plugin.LogTable.Writelog("坡度分析,表面集为:" + comboBoxOpen.Text); Plugin.LogTable.Writelog("输出栅格路径为:" + txtSave.Text); } } } else { MessageBox.Show("目前不支持对当前选择图层的坡度分析功能", "提示!"); } m_pCurrentSceneControl.SceneGraph.RefreshViewers(); this.Close(); DeleteFolder(TempPath);//清楚临时文件 } catch { vProgress.Close(); this.Close(); MessageBox.Show("很抱歉,操作失败!", "提示!"); return; } }