/// <summary> /// 创建TIN /// </summary> private void CreateDelaunay() { //创建TIN IFeatureLayer featureLayer = m_dataInfo.GetInputLayer() as IFeatureLayer; IFeatureClass featureClass = featureLayer.FeatureClass; IField pField = featureClass.Fields.get_Field(0); if (pField == null) { MessageBox.Show("创建Delaunay三角网失败"); return; } IGeoDataset pGeoDataset = featureClass as IGeoDataset; IEnvelope pEnvelope = pGeoDataset.Extent; pEnvelope.SpatialReference = pGeoDataset.SpatialReference; ITinEdit pTinEdit = new TinClass(); pTinEdit.InitNew(pEnvelope); object obj = Type.Missing; pTinEdit.AddFromFeatureClass(featureClass, null, pField, null, esriTinSurfaceType.esriTinMassPoint, ref obj); m_DT = pTinEdit as ITin; //将所有点标识为噪声点 ITinAdvanced tinAdvanced = m_DT as ITinAdvanced; for (int i = 0; i < tinAdvanced.NodeCount; i++) { m_nodeFlag.Add(-1); } }
/// <summary> /// 创建Tin文件 /// </summary> /// <param name="pFeatureClass">要素类</param> private void CreateTinFromFeature(IFeatureClass pFeatureClass) { try { IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset; ESRI.ArcGIS.Geometry.IEnvelope pExtent = pGeoDataset.Extent; pExtent.SpatialReference = pGeoDataset.SpatialReference; //获得高程值 IFields pFields = pFeatureClass.Fields; IField pHeightField; pHeightField = pFields.get_Field(3); ITinEdit pTinEdit = new TinClass(); pTinEdit.InitNew(pExtent); object Missing = Type.Missing; object pbUseShapeZ = Missing; object pOverWrite = Missing; pTinEdit.AddFromFeatureClass(pFeatureClass, null, pHeightField, null, esriTinSurfaceType.esriTinMassPoint, ref pbUseShapeZ); pTinEdit.SaveAs(Application.StartupPath + "\\Convert\\TemTIN\\" + this.Random, ref pOverWrite); pTinEdit.StopEditing(false); CreateContourData(Application.StartupPath + "\\Convert\\TemTIN"); } catch (Exception) { } }
private ITin Create_TIN(IFeatureClass pFeatureClass, IField pField) { IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset; ITinEdit pTinEdit = new TinClass(); pTinEdit.InitNew(pGeoDataset.Extent); object pObj = Type.Missing; pTinEdit.AddFromFeatureClass(pFeatureClass, null, pField, null, esriTinSurfaceType.esriTinMassPoint, ref pObj); pTinEdit.Refresh(); return(pTinEdit as ITin); }
public static IGeometry GetExample14() { const int PointCount = 100; const double ZMin = 0; const double ZMax = 4; //Extrusion: Square Shaped Base Geometry Extruded Between Single TIN-Based Functional Surface IGeometryCollection multiPatchGeometryCollection = new MultiPatchClass(); //Base Geometry IEnvelope envelope = new EnvelopeClass(); envelope.XMin = -10; envelope.XMax = 10; envelope.YMin = -10; envelope.YMax = 10; IGeometry baseGeometry = envelope as IGeometry; //Upper Functional Surface ITinEdit tinEdit = new TinClass(); tinEdit.InitNew(envelope); Random random = new Random(); for (int i = 0; i < PointCount; i++) { double x = envelope.XMin + (envelope.XMax - envelope.XMin) * random.NextDouble(); double y = envelope.YMin + (envelope.YMax - envelope.YMin) * random.NextDouble(); double z = ZMin + (ZMax - ZMin) * random.NextDouble(); IPoint point = GeometryUtilities.ConstructPoint3D(x, y, z); tinEdit.AddPointZ(point, 0); } IFunctionalSurface functionalSurface = tinEdit as IFunctionalSurface; IConstructMultiPatch constructMultiPatch = new MultiPatchClass(); constructMultiPatch.ConstructExtrudeBetween(functionalSurface, functionalSurface, baseGeometry); return(constructMultiPatch as IGeometry); }
/// <summary> /// 高程点生成TIN /// </summary> /// <param name="featureClass">点要素</param> /// <param name="path">保存路径</param> /// <returns>TIN数据</returns> public static ITin CreateTIN(IFeatureClass featureClass, string path) { string folder = System.IO.Path.GetDirectoryName(path); IGeoDataset geoDataset = featureClass as IGeoDataset; IField zField = featureClass.Fields.get_Field(4);//高程字段 ITinEdit tinEdit = new TinClass(); tinEdit.InitNew(geoDataset.Extent); tinEdit.AddFromFeatureClass(featureClass, null, zField, null, esriTinSurfaceType.esriTinMassPoint); if (System.IO.Directory.Exists(folder + "\\tin")) { (new System.IO.DirectoryInfo(folder + "\\tin")).Delete(true); } tinEdit.SaveAs(folder + "\\tin"); tinEdit.Refresh(); tinEdit.StopEditing(true); return(tinEdit as ITin); }
protected override void OnClick() { try { string shpFilePath = string.Format(@"C:\temp\contour datas"); string shpFileName = "contour2.shp"; // height data IWorkspaceFactory workspaceFactory = new ESRI.ArcGIS.DataSourcesFile.ShapefileWorkspaceFactoryClass(); IWorkspace workspace = workspaceFactory.OpenFromFile(shpFilePath, 0); IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace; IFeatureClass pFeatureClass = featureWorkspace.OpenFeatureClass(shpFileName); IFeatureLayer pFeatureLayer = new FeatureLayerClass(); pFeatureLayer.FeatureClass = pFeatureClass; IQueryFilter pQueryFilter = new QueryFilterClass(); pQueryFilter.WhereClause = ""; IEnvelope pEnv = pFeatureLayer.AreaOfInterest; IGeoDataset pGDS = (IGeoDataset)pFeatureLayer.FeatureClass; ISpatialReference pSR = pGDS.SpatialReference; IGeometry pGeom = pEnv; pGeom.Project(pSR); ITinEdit pTinEdit = new TinClass(); pTinEdit.InitNew(pEnv); IFields pFields = pFeatureClass.Fields; IField pFiled = pFields.get_Field(pFields.FindField("HSL")); object Missing = Type.Missing; esriTinSurfaceType pTinSurface = esriTinSurfaceType.esriTinHardLine; pTinEdit.AddFromFeatureClass(pFeatureClass, pQueryFilter, pFiled, pFiled, pTinSurface, ref Missing); string outputFolderPath = @"C:\temp\Output\"; string tinFolderName = "tin_data"; pTinEdit.SaveAs(outputFolderPath + tinFolderName, ref Missing); MessageBox.Show("end"); } catch (System.Exception ex) { MessageBox.Show(ex.Message); } ArcMap.Application.CurrentTool = null; }
/// <summary> /// /// </summary> /// <param name="ConstraintCpllt"></param> /// <param name="KnownCEdgeLt"></param> /// <param name="strIdentity"></param> /// <param name="blnSave"></param> /// <remarks>If the "data area" is not set deliberately, then ArcEngine will set a default "data area". /// The default data area excludes super edges and super nodes</remarks> public void Triangulate(List <CPolyline> ConstraintCpllt = null, List <CEdge> KnownCEdgeLt = null, string strIdentity = "", bool blnSave = false) { var cpg = _CPg; //cpg.pPolygon = null; cpg.JudgeAndSetPolygon(); IPointCollection4 pCol = cpg.pPolygon as IPointCollection4; int intCount = pCol.PointCount; var pEnv = cpg.pPolygon.Envelope; ITinEdit TinEdit = new TinClass(); TinEdit.InitNew(pEnv); ITinEdit2 TinEdit2 = TinEdit as ITinEdit2; TinEdit2.SetToConstrainedDelaunay(); //this must be done before adding any feature var pTinAdvanced2 = TinEdit as ITinAdvanced2; ITinFeatureEdit pTinFeatureEdit = TinEdit as ITinFeatureEdit; cpg.JudgeAndSetZToZero(); //we need z coordinate to construct triangulation pTinFeatureEdit.AddPolygonZ(cpg.pPolygon, esriTinEdgeType.esriTinHardEdge, 1, 1, 1, null); if (ConstraintCpllt != null) { foreach (var cpl in ConstraintCpllt) { cpl.JudgeAndSetPolyline(); cpl.JudgeAndSetZToZero(); pTinFeatureEdit.AddPolylineZ(cpl.pPolyline, esriTinEdgeType.esriTinHardEdge, 1, 1, null); } } _pTinAdvanced2 = pTinAdvanced2; //we are not allowed to use AddShapeZ. //it will report that there is no Z value in the shape, even we already set Z value to 0 //The reason may be that we actually need polyhedron //TinEdit.AddShapeZ((IGeometry)cpg.pPolygon, esriTinSurfaceType.esriTinHardClip, 0); //******************************************** //this function set the "data area" of the TIN, //we avoid to use this function because it may introduce new points //the new poins can be very close to the original points //TinEdit.AddShape((IGeometry)cpg.pPolygon, esriTinSurfaceType.esriTinHardClip, 0); //TinEdit.Refresh(); if (pTinAdvanced2.DataNodeCount != this.CptLt.Count) { //Usually, KnownCEdgeLt saves all the constraints for the triangulation CSaveFeature.SaveCEdgeEb(KnownCEdgeLt, "KnownCEdgeLt" + strIdentity); CSaveFeature.SaveCptEb(this.CptLt, "CptLtForKnownCEdgeLt" + strIdentity); var NodeCptLt = GetCptLtFromTinAdvanced(pTinAdvanced2, true); CSaveFeature.SaveCptEb(NodeCptLt, "TinNode" + strIdentity); //var TinCEdgeLt= get var ExtraNodeCptLt = new List <CPoint>(pTinAdvanced2.DataNodeCount - this.CptLt.Count); foreach (var nodeCpt in NodeCptLt) { if (this.CptSD.ContainsKey(nodeCpt) == false) { ExtraNodeCptLt.Add(nodeCpt); } } CSaveFeature.SaveCptEb(ExtraNodeCptLt, "ExtraNodeCptLt" + strIdentity); var TinCEdgeLt = GetCEdgeLtFromTinAdvanced(pTinAdvanced2); CSaveFeature.SaveCEdgeEb(TinCEdgeLt, "TinCEdgeLt" + strIdentity); throw new ArgumentException("the numbers of points should be the same!"); } this.CptLt.SetIndexID(); var ITinEdgeLt = GenerateITinEdgeLt(); var tincedgeSS = new SortedSet <CEdge>(new CCmpEdge_CptGID_BothDirections()); var tincedgelt = new List <CEdge>(); if (KnownCEdgeLt != null) { tincedgeSS = new SortedSet <CEdge>(KnownCEdgeLt, new CCmpEdge_CptGID_BothDirections()); tincedgelt.AddRange(KnownCEdgeLt); } cpg.SetAxisAngleAndReverseLt(); var cptSD = this.CptSD; foreach (var tinedge in ITinEdgeLt) { //there are always a pair of edges between a pair of triangles, but we only need one edge. //So we reverse some edges than we can delete one edge of each pair var pFrNode = tinedge.FromNode; var pToNode = tinedge.ToNode; CPoint frcpt, tocpt; FindCorrCptInSDByTinNode(pFrNode, cptSD, out frcpt); FindCorrCptInSDByTinNode(pToNode, cptSD, out tocpt); CEdge newCEdge; if (frcpt.indexID < tocpt.indexID) { newCEdge = new CEdge(frcpt, tocpt); } else if (frcpt.indexID > tocpt.indexID) { newCEdge = new CEdge(tocpt, frcpt); } else { throw new ArgumentException("should not happen!"); } //test if the new edge is outside the boundary polygon (cpg) if (newCEdge.FrCpt.indexID < cpg.CEdgeLt.Count) { //the new edge starts from a point which constitues the boundary polygon (cpg) newCEdge.SetAxisAngle(); if (CGeoFunc.IsInbetween_Counterclockwise(cpg.AxisAngleLt[newCEdge.FrCpt.indexID], newCEdge.dblAxisAngle, cpg.ReverseAxisAngleLt[newCEdge.FrCpt.indexID]) == false) { //the new edge is outside the boundary polygon (cpg) continue; } } //add the new edge if the edge is not added yet if (tincedgeSS.Add(newCEdge)) { this.NewCEdgeLt.Add(newCEdge); tincedgelt.Add(newCEdge); } } if (blnSave == true) { CSaveFeature.SaveCEdgeEb(tincedgelt, "tincedgelt" + strIdentity, blnVisible: false); } this.CEdgeLt = tincedgelt; }
private List <CPoint> LookingForNeighboursDT(IFeatureLayer pFeatureLayer, double dblThreshold, int intPtNumLast, ref long lngTimeForSearching, ref long lngTimeForDT, ref long lngMemory, ref long lngMemoryDT, ref long lngMemoryDTProcess, ref int intOutPut, string strTINPath) { lngMemory = GC.GetTotalMemory(true); //lngMemoryDT = GC.GetTotalMemory(true); //lngMemoryDTProcess = Process.GetProcessesByName("ContinuousGeneralizer.vshost")[0].WorkingSet64; long lngStartTime = System.Environment.TickCount; //record the start time //lngMemoryDT = Process.GetProcessesByName("ContinuousGeneralizer.vshost")[0].WorkingSet64; //Process .GetProcessesByName("ContinuousGeneralizer.vshost")[0]. //create TIN IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass; IGeoDataset pGDS = (IGeoDataset)pFeatureClass; IEnvelope pEnv = (IEnvelope)pGDS.Extent; pEnv.SpatialReference = pGDS.SpatialReference; IFields pFields = pFeatureClass.Fields; IField pHeightFiled = new FieldClass(); try { pHeightFiled = pFields.get_Field(pFields.FindField("Id")); } catch (Exception) { pHeightFiled = pFields.get_Field(pFields.FindField("ID")); throw; } //ITinWorkspace ITinEdit pTinEdit = new TinClass(); pTinEdit.InitNew(pEnv); object Missing = Type.Missing; pTinEdit.AddFromFeatureClass(pFeatureClass, null, pHeightFiled, null, esriTinSurfaceType.esriTinHardLine, ref Missing); lngTimeForDT = System.Environment.TickCount - lngStartTime; //Time for constructing DT //long lngMemoryafterTinEdit = GC.GetTotalMemory(false) - lngMemoryDT; //GC.Collect(); //lngMemoryDT = GC.GetTotalMemory(true) - lngMemoryDT; //lngMemoryDTProcess = Process.GetProcessesByName("ContinuousGeneralizer.vshost")[0].WorkingSet64 - lngMemoryDTProcess; //C5.LinkedList<int> intLLt = new C5.LinkedList<int>(); ITinNodeCollection pTinNodeCollection = (ITinNodeCollection)pTinEdit; List <CPoint> CptLt = new List <CPoint>(pTinNodeCollection.NodeCount); for (int i = 1; i <= pTinNodeCollection.NodeCount; i++) //i=1-4: super node { ITinNode pNode = pTinNodeCollection.GetNode(i); CPoint cpt = new CPoint(pNode); //cpt.intTS = new C5.TreeSet<int>(); CptLt.Add(cpt); } //long lngMemoryafterfetching = GC.GetTotalMemory(true); //lngMemoryDT = GC.GetTotalMemory(true) - lngMemoryDT; //Looking for neighbours based on Breadth First Search if (intPtNumLast != -1) { dblThreshold = dblThreshold * Math.Pow(Convert.ToDouble(intPtNumLast) / Convert.ToDouble(CptLt.Count - 4), 0.5); //---------------dblThreshold------------------------------------------------// //Math.Pow(1.8 / Convert.ToDouble(CptLt.Count - 4), 0.5);//---------------dblThreshold------------------------------------------------// } //double dblThresholdDT = (1 + Math.Sqrt(2)) / 2 * dblThreshold; lngTimeForSearching = System.Environment.TickCount; //the start time SCG.LinkedList <int> intTargetLLt = new SCG.LinkedList <int>(); SCG.LinkedList <int> intAllLLt = new SCG.LinkedList <int>(); for (int i = 0; i < CptLt.Count; i++) { CptLt[i].isTraversed = true; intTargetLLt = new SCG.LinkedList <int>(); intTargetLLt.AddLast(CptLt[i].pTinNode.Index); intAllLLt = new SCG.LinkedList <int>(); intAllLLt.AddLast(CptLt[i].pTinNode.Index); while (intTargetLLt.Count > 0) { intTargetLLt = BSF(CptLt[i], ref CptLt, ref intTargetLLt, ref intAllLLt, dblThreshold, ref intOutPut); } intOutPut--; //the point will take itself as a close point, so we have to minus 1 //CptLt[i].intTS.Remove(CptLt[i].pTinNode.Index); RestoreIsTraversed(ref CptLt, ref intAllLLt); //intAllLLt.Dispose(); } //long lngMemoryaftersearch = GC.GetTotalMemory(true); lngTimeForSearching = System.Environment.TickCount - lngTimeForSearching; //the result time lngMemory = GC.GetTotalMemory(true) - lngMemory; pTinEdit.SaveAs(strTINPath + "\\" + pFeatureLayer.Name, true); long lngFileSize = CHelpFunc.GetDirectoryLength(strTINPath + "\\" + pFeatureLayer.Name); lngMemory += lngFileSize; lngMemoryDT = lngFileSize; return(CptLt); }
public void DEMToTIN(IRaster iRaster, string tinFileName) { try { //***************生成TIN模型********************************************* IGeoDataset pGeoData = iRaster as IGeoDataset; IEnvelope pExtent = pGeoData.Extent; IRasterBandCollection pRasBC = iRaster as IRasterBandCollection; IRasterBand pRasBand = pRasBC.Item(0); IRawPixels pRawPixels = pRasBand as IRawPixels; IRasterProps pProps = pRawPixels as IRasterProps; int iWid = pProps.Width; int iHei = pProps.Height; double w = iWid / 1000.0f; double h = iHei / 1000.0f; IPnt pBlockSize = new DblPntClass(); bool IterationFlag; if (w < 1 && h < 1) //横纵都小于1000个像素 { pBlockSize.X = iWid; pBlockSize.Y = iHei; IterationFlag = false; } else { pBlockSize.X = 1001.0f; pBlockSize.Y = 1001.0f; IterationFlag = true; } double cellsize = 0.0f; //栅格大小 IPnt pPnt1 = pProps.MeanCellSize(); //栅格平均大小 cellsize = pPnt1.X; ITinEdit pTinEdit = new TinClass() as ITinEdit; pTinEdit.InitNew(pExtent); ISpatialReference pSpatial = pGeoData.SpatialReference; pExtent.SpatialReference = pSpatial; IPnt pOrigin = new DblPntClass(); IPnt pPixelBlockOrigin = new DblPntClass(); //栅格左上角像素中心坐标 double bX = pBlockSize.X; double bY = pBlockSize.Y; pBlockSize.SetCoords(bX, bY); IPixelBlock pPixelBlock = pRawPixels.CreatePixelBlock(pBlockSize); object nodata = pProps.NoDataValue; //无值标记 ITinAdvanced2 pTinNodeCount = pTinEdit as ITinAdvanced2; int nodeCount = pTinNodeCount.NodeCount; object vtMissing = Type.Missing; object vPixels = null; //格子 double m_zTolerance = 0; if (!IterationFlag) //当为一个处理单元格子时;(w < 1 && h < 1) //横纵都小于1000个像素 { pPixelBlockOrigin.SetCoords(0.0f, 0.0f); pRawPixels.Read(pPixelBlockOrigin, pPixelBlock); vPixels = pPixelBlock.get_SafeArray(0); double xMin = pExtent.XMin; double yMax = pExtent.YMax; pOrigin.X = xMin + cellsize / 2; pOrigin.Y = yMax - cellsize / 2; bX = pOrigin.X; bY = pOrigin.Y; pTinEdit.AddFromPixelBlock(bX, bY, cellsize, cellsize, nodata, vPixels, m_zTolerance, ref vtMissing, out vtMissing); } else //当有多个处理单元格时,依次循环处理每个单元格 { int i = 0, j = 0, count = 0; int FirstGoNodeCount = 0; //while (nodeCount != FirstGoNodeCount) //{ count++; nodeCount = pTinNodeCount.NodeCount; int bwidth = 0; int bheight = 0; //依次循环处理 for (i = 0; i < (int)h + 1; i++) { if (i < (int)h) { bheight = 1000; } else { bheight = iHei - 1000 * i; } for (j = 0; j < (int)w + 1; j++) { if (j < (int)w) { bwidth = 1000; } else { bwidth = iWid - 1000 * j; } pBlockSize.SetCoords(bwidth, bheight); pPixelBlock = pRawPixels.CreatePixelBlock(pBlockSize); double bX1, bY1, xMin1, yMax1; bX1 = pBlockSize.X; bY1 = pBlockSize.Y; pPixelBlockOrigin.SetCoords(j * 1000, i * 1000); pRawPixels.Read(pPixelBlockOrigin, pPixelBlock); vPixels = pPixelBlock.get_SafeArray(0); xMin1 = pExtent.XMin; yMax1 = pExtent.YMax; //bX1 = pBlockSize.X; //bY1 = pBlockSize.Y; pOrigin.X = xMin1 + j * 1000 * cellsize + cellsize / 2.0f; pOrigin.Y = yMax1 - i * 1000 * cellsize - cellsize / 2.0f; bX1 = pOrigin.X; bY1 = pOrigin.Y; pTinEdit.AddFromPixelBlock(bX1, bY1, cellsize, cellsize, nodata, vPixels, m_zTolerance, ref vtMissing, out vtMissing); FirstGoNodeCount = pTinNodeCount.NodeCount; } } //} } //保存TIN文件 pTinEdit.SaveAs(tinFileName, ref vtMissing); pTinEdit.StopEditing(true); m_pTin = pTinEdit as ITin; MessageBox.Show("转换成功!"); } catch (SystemException e) { MessageBox.Show(e.Message); } }
public static IGeometry GetExample15() { const double CircleDegrees = 360.0; const int CircleDivisions = 36; const double VectorComponentOffset = 0.0000001; const double CircleRadius = 9.5; const int PointCount = 100; const double UpperZMin = 7; const double UpperZMax = 10; const double LowerZMin = 0; const double LowerZMax = 3; //Extrusion: Circle Shaped Base Geometry Extruded Between Two Different TIN-Based Functional Surfaces IGeometryCollection multiPatchGeometryCollection = new MultiPatchClass(); //Base Geometry IPointCollection polygonPointCollection = new PolygonClass(); IPoint originPoint = GeometryUtilities.ConstructPoint3D(0, 0, 0); IVector3D upperAxisVector3D = GeometryUtilities.ConstructVector3D(0, 0, 10); IVector3D lowerAxisVector3D = GeometryUtilities.ConstructVector3D(0, 0, -10); lowerAxisVector3D.XComponent += VectorComponentOffset; IVector3D normalVector3D = upperAxisVector3D.CrossProduct(lowerAxisVector3D) as IVector3D; normalVector3D.Magnitude = CircleRadius; double rotationAngleInRadians = GeometryUtilities.GetRadians(CircleDegrees / CircleDivisions); for (int i = 0; i < CircleDivisions; i++) { normalVector3D.Rotate(-1 * rotationAngleInRadians, upperAxisVector3D); IPoint vertexPoint = GeometryUtilities.ConstructPoint2D(originPoint.X + normalVector3D.XComponent, originPoint.Y + normalVector3D.YComponent); polygonPointCollection.AddPoint(vertexPoint, ref _missing, ref _missing); } IPolygon polygon = polygonPointCollection as IPolygon; polygon.Close(); IGeometry baseGeometry = polygon as IGeometry; ITopologicalOperator topologicalOperator = polygon as ITopologicalOperator; topologicalOperator.Simplify(); //Functional Surfaces IEnvelope envelope = new EnvelopeClass(); envelope.XMin = -10; envelope.XMax = 10; envelope.YMin = -10; envelope.YMax = 10; Random random = new Random(); //Upper Functional Surface ITinEdit upperTinEdit = new TinClass(); upperTinEdit.InitNew(envelope); for (int i = 0; i < PointCount; i++) { double x = envelope.XMin + (envelope.XMax - envelope.XMin) * random.NextDouble(); double y = envelope.YMin + (envelope.YMax - envelope.YMin) * random.NextDouble(); double z = UpperZMin + (UpperZMax - UpperZMin) * random.NextDouble(); IPoint point = GeometryUtilities.ConstructPoint3D(x, y, z); upperTinEdit.AddPointZ(point, 0); } IFunctionalSurface upperFunctionalSurface = upperTinEdit as IFunctionalSurface; //Lower Functional Surface ITinEdit lowerTinEdit = new TinClass(); lowerTinEdit.InitNew(envelope); for (int i = 0; i < PointCount; i++) { double x = envelope.XMin + (envelope.XMax - envelope.XMin) * random.NextDouble(); double y = envelope.YMin + (envelope.YMax - envelope.YMin) * random.NextDouble(); double z = LowerZMin + (LowerZMax - LowerZMin) * random.NextDouble(); IPoint point = GeometryUtilities.ConstructPoint3D(x, y, z); lowerTinEdit.AddPointZ(point, 0); } IFunctionalSurface lowerFunctionalSurface = lowerTinEdit as IFunctionalSurface; IConstructMultiPatch constructMultiPatch = new MultiPatchClass(); constructMultiPatch.ConstructExtrudeBetween(upperFunctionalSurface, lowerFunctionalSurface, baseGeometry); return(constructMultiPatch as IGeometry); }
private void button1_Click(object sender, EventArgs e) { if (mLayerCombox.Text == "" || mFeildCombox.Text == "")//判断输入合法性 { MessageBox.Show("没有相应的图层"); return; } ITinEdit pTin = new TinClass(); //寻找Featurelayer IFeatureLayer pFeatureLayer = mSceneControl.Scene.get_Layer(mLayerCombox.SelectedIndex) as IFeatureLayer; if (pFeatureLayer != null) { IEnvelope pEnvelope = new EnvelopeClass(); IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass; IQueryFilter pQueryFilter = new QueryFilterClass(); IField pField = null; //找字段 pField = pFeatureClass.Fields.get_Field(pFeatureClass.Fields.FindField(mFeildCombox.Text)); if (pField.Type == esriFieldType.esriFieldTypeInteger || pField.Type == esriFieldType.esriFieldTypeDouble || pField.Type == esriFieldType.esriFieldTypeSingle) //判断类型 { IGeoDataset pGeoDataset = pFeatureLayer as IGeoDataset; pEnvelope = pGeoDataset.Extent; //设置空间参考系 ISpatialReference pSpatialReference; pSpatialReference = pGeoDataset.SpatialReference; //选择生成TIN的输入类型 esriTinSurfaceType pSurfaceTypeCount = esriTinSurfaceType.esriTinMassPoint; switch (mTINType.Text) { case "点": pSurfaceTypeCount = esriTinSurfaceType.esriTinMassPoint; break; case "直线": pSurfaceTypeCount = esriTinSurfaceType.esriTinSoftLine; break; case "光滑线": pSurfaceTypeCount = esriTinSurfaceType.esriTinHardLine; break; } //创建TIN pTin.InitNew(pEnvelope); object missing = Type.Missing; //生成TIN pTin.AddFromFeatureClass(pFeatureClass, pQueryFilter, pField, pField, pSurfaceTypeCount, ref missing); pTin.SetSpatialReference(pGeoDataset.SpatialReference); //创建Tin图层并将Tin图层加入到场景中去 ITinLayer pTinLayer = new TinLayerClass(); pTinLayer.Dataset = pTin as ITin; mSceneControl.Scene.AddLayer(pTinLayer, true); } else { MessageBox.Show("该字段的类型不符合构建TIN的条件"); } } }
public static IGeometry GetExample15() { const double CircleDegrees = 360.0; const int CircleDivisions = 36; const double VectorComponentOffset = 0.0000001; const double CircleRadius = 9.5; const int PointCount = 100; const double UpperZMin = 7; const double UpperZMax = 10; const double LowerZMin = 0; const double LowerZMax = 3; //Extrusion: Circle Shaped Base Geometry Extruded Between Two Different TIN-Based Functional Surfaces IGeometryCollection multiPatchGeometryCollection = new MultiPatchClass(); //Base Geometry IPointCollection polygonPointCollection = new PolygonClass(); IPoint originPoint = GeometryUtilities.ConstructPoint3D(0, 0, 0); IVector3D upperAxisVector3D = GeometryUtilities.ConstructVector3D(0, 0, 10); IVector3D lowerAxisVector3D = GeometryUtilities.ConstructVector3D(0, 0, -10); lowerAxisVector3D.XComponent += VectorComponentOffset; IVector3D normalVector3D = upperAxisVector3D.CrossProduct(lowerAxisVector3D) as IVector3D; normalVector3D.Magnitude = CircleRadius; double rotationAngleInRadians = GeometryUtilities.GetRadians(CircleDegrees / CircleDivisions); for (int i = 0; i < CircleDivisions; i++) { normalVector3D.Rotate(-1 * rotationAngleInRadians, upperAxisVector3D); IPoint vertexPoint = GeometryUtilities.ConstructPoint2D(originPoint.X + normalVector3D.XComponent, originPoint.Y + normalVector3D.YComponent); polygonPointCollection.AddPoint(vertexPoint, ref _missing, ref _missing); } IPolygon polygon = polygonPointCollection as IPolygon; polygon.Close(); IGeometry baseGeometry = polygon as IGeometry; ITopologicalOperator topologicalOperator = polygon as ITopologicalOperator; topologicalOperator.Simplify(); //Functional Surfaces IEnvelope envelope = new EnvelopeClass(); envelope.XMin = -10; envelope.XMax = 10; envelope.YMin = -10; envelope.YMax = 10; Random random = new Random(); //Upper Functional Surface ITinEdit upperTinEdit = new TinClass(); upperTinEdit.InitNew(envelope); for (int i = 0; i < PointCount; i++) { double x = envelope.XMin + (envelope.XMax - envelope.XMin) * random.NextDouble(); double y = envelope.YMin + (envelope.YMax - envelope.YMin) * random.NextDouble(); double z = UpperZMin + (UpperZMax - UpperZMin) * random.NextDouble(); IPoint point = GeometryUtilities.ConstructPoint3D(x, y, z); upperTinEdit.AddPointZ(point, 0); } IFunctionalSurface upperFunctionalSurface = upperTinEdit as IFunctionalSurface; //Lower Functional Surface ITinEdit lowerTinEdit = new TinClass(); lowerTinEdit.InitNew(envelope); for (int i = 0; i < PointCount; i++) { double x = envelope.XMin + (envelope.XMax - envelope.XMin) * random.NextDouble(); double y = envelope.YMin + (envelope.YMax - envelope.YMin) * random.NextDouble(); double z = LowerZMin + (LowerZMax - LowerZMin) * random.NextDouble(); IPoint point = GeometryUtilities.ConstructPoint3D(x, y, z); lowerTinEdit.AddPointZ(point, 0); } IFunctionalSurface lowerFunctionalSurface = lowerTinEdit as IFunctionalSurface; IConstructMultiPatch constructMultiPatch = new MultiPatchClass(); constructMultiPatch.ConstructExtrudeBetween(upperFunctionalSurface, lowerFunctionalSurface, baseGeometry); return constructMultiPatch as IGeometry; }
public static IGeometry GetExample14() { const int PointCount = 100; const double ZMin = 0; const double ZMax = 4; //Extrusion: Square Shaped Base Geometry Extruded Between Single TIN-Based Functional Surface IGeometryCollection multiPatchGeometryCollection = new MultiPatchClass(); //Base Geometry IEnvelope envelope = new EnvelopeClass(); envelope.XMin = -10; envelope.XMax = 10; envelope.YMin = -10; envelope.YMax = 10; IGeometry baseGeometry = envelope as IGeometry; //Upper Functional Surface ITinEdit tinEdit = new TinClass(); tinEdit.InitNew(envelope); Random random = new Random(); for (int i = 0; i < PointCount; i++) { double x = envelope.XMin + (envelope.XMax - envelope.XMin) * random.NextDouble(); double y = envelope.YMin + (envelope.YMax - envelope.YMin) * random.NextDouble(); double z = ZMin + (ZMax - ZMin) * random.NextDouble(); IPoint point = GeometryUtilities.ConstructPoint3D(x, y, z); tinEdit.AddPointZ(point, 0); } IFunctionalSurface functionalSurface = tinEdit as IFunctionalSurface; IConstructMultiPatch constructMultiPatch = new MultiPatchClass(); constructMultiPatch.ConstructExtrudeBetween(functionalSurface, functionalSurface, baseGeometry); return constructMultiPatch as IGeometry; }
public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message) { // Get Parameters IGPParameter3 inputParameter = (IGPParameter3)paramvalues.get_Element(0); IGPParameter3 polygonParameter = (IGPParameter3)paramvalues.get_Element(1); IGPParameter3 outputParameter = (IGPParameter3)paramvalues.get_Element(2); IGPParameter3 fieldParameter = (IGPParameter3)paramvalues.get_Element(3); // UnPackGPValue. This ensures you get the value from either the dataelement or GpVariable (ModelBuilder) IGPValue inputParameterValue = m_GPUtilities.UnpackGPValue(inputParameter); IGPValue polygonParameterValue = m_GPUtilities.UnpackGPValue(polygonParameter); IGPValue outputParameterValue = m_GPUtilities.UnpackGPValue(outputParameter); IGPValue fieldParameterValue = m_GPUtilities.UnpackGPValue(fieldParameter); // Decode Input Feature Layers IFeatureClass inputFeatureClass; IFeatureClass polygonFeatureClass; IQueryFilter inputFeatureClassQF; IQueryFilter polygonFeatureClassQF; m_GPUtilities.DecodeFeatureLayer(inputParameterValue, out inputFeatureClass, out inputFeatureClassQF); m_GPUtilities.DecodeFeatureLayer(polygonParameterValue, out polygonFeatureClass, out polygonFeatureClassQF); if (inputFeatureClass == null) { message.AddError(2, "Could not open input dataset."); return; } if (polygonFeatureClass == null) { message.AddError(2, "Could not open clipping polygon dataset."); return; } if (polygonFeatureClass.FeatureCount(null) > 1) { message.AddWarning("Clipping polygon feature class contains more than one feature."); } // Create the Geoprocessor Geoprocessor gp = new Geoprocessor(); // Create Output Polygon Feature Class CreateFeatureclass cfc = new CreateFeatureclass(); IName name = m_GPUtilities.CreateFeatureClassName(outputParameterValue.GetAsText()); IDatasetName dsName = name as IDatasetName; IFeatureClassName fcName = dsName as IFeatureClassName; IFeatureDatasetName fdsName = fcName.FeatureDatasetName as IFeatureDatasetName; // Check if output is in a FeatureDataset or not. Set the output path parameter for CreateFeatureClass tool. if (fdsName != null) { cfc.out_path = fdsName; } else { cfc.out_path = dsName.WorkspaceName.PathName; } // Set the output Coordinate System for CreateFeatureClass tool. // ISpatialReference3 sr = null; IGPEnvironment env = envMgr.FindEnvironment("outputCoordinateSystem"); // Same as Input if (env.Value.IsEmpty()) { IGeoDataset ds = inputFeatureClass as IGeoDataset; cfc.spatial_reference = ds.SpatialReference as ISpatialReference3; } // Use the environment setting else { IGPCoordinateSystem cs = env.Value as IGPCoordinateSystem; cfc.spatial_reference = cs.SpatialReference as ISpatialReference3; } // Remaining properties for Create Feature Class Tool cfc.out_name = dsName.Name; cfc.geometry_type = "POLYGON"; // Execute Geoprocessor gp.Execute(cfc, null); // Get Unique Field int iField = inputFeatureClass.FindField(fieldParameterValue.GetAsText()); IField uniqueField = inputFeatureClass.Fields.get_Field(iField); // Extract Clipping Polygon Geometry IFeature polygonFeature = polygonFeatureClass.GetFeature(0); IPolygon clippingPolygon = (IPolygon)polygonFeature.Shape; // Spatial Filter ISpatialFilter spatialFilter = new SpatialFilterClass(); spatialFilter.Geometry = polygonFeature.ShapeCopy; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains; // Debug Message message.AddMessage("Generating TIN..."); // Create TIN ITinEdit tinEdit = new TinClass(); // Advanced TIN Functions ITinAdvanced2 tinAdv = (ITinAdvanced2)tinEdit; try { // Initialize New TIN IGeoDataset gds = inputFeatureClass as IGeoDataset; tinEdit.InitNew(gds.Extent); // Add Mass Points to TIN tinEdit.StartEditing(); tinEdit.AddFromFeatureClass(inputFeatureClass, spatialFilter, uniqueField, uniqueField, esriTinSurfaceType.esriTinMassPoint); tinEdit.Refresh(); // Get TIN Nodes ITinNodeCollection tinNodeCollection = (ITinNodeCollection)tinEdit; // Report Node Count message.AddMessage("Input Node Count: " + inputFeatureClass.FeatureCount(null).ToString()); message.AddMessage("TIN Node Count: " + tinNodeCollection.NodeCount.ToString()); // Open Output Feature Class IFeatureClass outputFeatureClass = m_GPUtilities.OpenFeatureClassFromString(outputParameterValue.GetAsText()); // Debug Message message.AddMessage("Generating Polygons..."); // Create Voronoi Polygons tinNodeCollection.ConvertToVoronoiRegions(outputFeatureClass, null, clippingPolygon, "", ""); // Release COM Objects tinEdit.StopEditing(false); System.Runtime.InteropServices.Marshal.ReleaseComObject(tinNodeCollection); System.Runtime.InteropServices.Marshal.ReleaseComObject(tinEdit); } catch (Exception ex) { message.AddError(2, ex.Message); } }
/// <summary> /// 根据生成的featureclass动态生成tin /// </summary> /// <params name="pFeatureClass"></params> /// <params name="pField"></params> /// <params name="pPath"></params> /// <returns></returns> private ITin CreateTin(IFeatureClass pFeatureClass, IField pField, string pPath) { IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset; ITinEdit pTinEdit = new TinClass(); pTinEdit.InitNew(pGeoDataset.Extent); object pObj = Type.Missing; pTinEdit.AddFromFeatureClass(pFeatureClass, null, pField, null, esriTinSurfaceType.esriTinMassPoint, ref pObj); pTinEdit.SaveAs(pPath, ref pObj); pTinEdit.Refresh(); return pTinEdit as ITin; }