/// <summary> /// 求导线(pRefPoint到pEndPoint)上的掘进点 /// </summary> /// <params name="pRefPoint">参考导线点</params> /// <params name="pEndPoint">导线的终点</params> /// <params name="dDistance">距离参考导线点的距离</params> /// <returns>距参考导线点一定距离的点</returns> public static IPoint GetJJPoint(IPoint pRefPoint, IPoint pEndPoint, double dDistance) { if (pRefPoint.Z.Equals(Double.NaN)) { pRefPoint.Z = 0; } if (pEndPoint.Z.Equals(Double.NaN)) { pEndPoint.Z = 0; } IVector3D vector3D = new Vector3DClass(); vector3D.ConstructDifference(pEndPoint, pRefPoint); //从参考点到导线终点的向量 vector3D.Normalize(); //向量单位化 IPoint pJjPoint = new PointClass(); pJjPoint.X = pRefPoint.X + dDistance * vector3D.XComponent; pJjPoint.Y = pRefPoint.Y + dDistance * vector3D.YComponent; pJjPoint.Z = pRefPoint.Z + dDistance * vector3D.ZComponent; return(pJjPoint); }
public static IVector3D ConstructVector3D(double xComponent, double yComponent, double zComponent) { IVector3D vector3D = new Vector3DClass(); vector3D.SetComponents(xComponent, yComponent, zComponent); return vector3D; }
/// <summary> /// 更新半径 /// </summary> /// <param name="radius"></param> public void UpdatePosition(double radius) { this.radius = radius; IZAware zAware = (IGeometry)centerPoint as IZAware; zAware.ZAware = true; upperAxisVector3D = new Vector3DClass(); upperAxisVector3D.SetComponents(0, 0, 10); lowerAxisVector3D = new Vector3DClass(); lowerAxisVector3D.SetComponents(0, 0, -10); lowerAxisVector3D.XComponent -= vectorComponentOffset; normalVector3D = upperAxisVector3D.CrossProduct(lowerAxisVector3D) as IVector3D; normalVector3D.Magnitude = this.radius; double rotationAngleInRadians = 2 * (Math.PI / 180); geometryCollection = new MultiPatchClass(); pointCollection.RemovePoints(0, pointCollection.PointCount); for (int i = 0; i < 180; i++) { normalVector3D.Rotate(-1 * rotationAngleInRadians, upperAxisVector3D); IPoint vertexPoint = new PointClass(); vertexPoint.X = centerPoint.X + normalVector3D.XComponent; vertexPoint.Y = centerPoint.Y + normalVector3D.YComponent; vertexPoint.Z = centerPoint.Z; pointCollection.AddPoint(vertexPoint, missing, missing); } base.Geometry = pointCollection as IGeometry; this.Update(); }
private IVector GetClosingVector(List <IVector3D> TraverseCourses, IPoint StartPoint, IPoint EndPoint, out double SUMofLengths) { IVector SumVec = null; SUMofLengths = 0; for (int i = 0; i < TraverseCourses.Count - 1; i++) { if (i == 0) { SUMofLengths = TraverseCourses[0].Magnitude + TraverseCourses[1].Magnitude; SumVec = TraverseCourses[0].AddVector(TraverseCourses[1]); } else { IVector3D SumVec3D = SumVec as IVector3D; SUMofLengths += TraverseCourses[i + 1].Magnitude; SumVec = SumVec3D.AddVector(TraverseCourses[i + 1]); } } double dCalcedEndX = StartPoint.X + SumVec.ComponentByIndex[0]; double dCalcedEndY = StartPoint.Y + SumVec.ComponentByIndex[1]; IVector3D CloseVector3D = new Vector3DClass(); CloseVector3D.SetComponents(dCalcedEndX - EndPoint.X, dCalcedEndY - EndPoint.Y, 0); IVector CloseVector = CloseVector3D as IVector; return(CloseVector); }
public IGeometry CreateGeometry(double radius, IPolyline polyline, double qdgc, double zdgc) { IPointCollection pointCollection = CreatePointCollectionForCircle(radius); IVector3D pVectorZ = new Vector3DClass(); pVectorZ.SetComponents(0, 0, 1); IConstructMultiPatch patch = new MultiPatchClass(); IZAware zAware = pointCollection as IZAware; if (zAware == null) { return(null); } zAware.ZAware = true; // 依据管线长度拉伸 patch.ConstructExtrude(polyline.Length, pointCollection as IGeometry); // 依据管线角度旋转 IVector3D pVector3D = new Vector3DClass(); pVector3D.SetComponents(polyline.ToPoint.X - polyline.FromPoint.X, polyline.ToPoint.Y - polyline.FromPoint.Y, zdgc - qdgc); double rotateAngle = Math.Acos(pVector3D.ZComponent / pVector3D.Magnitude); IVector3D vectorAxis = pVectorZ.CrossProduct(pVector3D) as IVector3D; ITransform3D transform3D = patch as ITransform3D; transform3D.RotateVector3D(vectorAxis, rotateAngle); // 平移到指定位置 transform3D.Move3D(polyline.FromPoint.X, polyline.FromPoint.Y, qdgc); return(patch as IGeometry); }
public static IVector3D ConstructVector3D(double xComponent, double yComponent, double zComponent) { IVector3D vector3D = new Vector3DClass(); vector3D.SetComponents(xComponent, yComponent, zComponent); return(vector3D); }
/// <summary> /// create a Vector3D from components /// </summary> /// <param name="componentX">component X</param> /// <param name="componentY">component Y</param> /// <param name="componentZ">component Z</param> /// <returns>object Vector 3D</returns> public static IVector3D ConstructVector3D(double componentX, double componentY, double componentZ) { IVector3D vector3D = new Vector3DClass(); vector3D.SetComponents(componentX, componentY, componentZ); return(vector3D); }
protected void AddTraverseInfoToGrid(IGSPlan Plan, DataGridView TraverseGrid, List <IVector3D> Traverse, List <IVector3D> AdjustedTraverse, List <string> FromToList) { ICadastralUnitConversion pCadUnitConverter = new CadastralUnitConversionClass(); double dMetersPerUnit = pCadUnitConverter.ConvertDouble(1, Plan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter); IAngularConverter pAngConv = new AngularConverterClass(); Utilities Utils = new Utilities(); List <string> lstAdjustedCourses = new List <string>(); List <string> lstResiduals = new List <string>(); foreach (IVector3D vect in AdjustedTraverse) { pAngConv.SetAngle(vect.Azimuth, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); int iPrec = 7; if (Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds) { iPrec = 0; } string sBearing = pAngConv.GetString(Plan.DirectionFormat, Plan.AngleUnits, iPrec); string sAdjusted = Utils.FormatDirectionDashesToDegMinSecSymbols(sBearing) + ", " + (vect.Magnitude / dMetersPerUnit).ToString("0.000"); lstAdjustedCourses.Add(sAdjusted); } int i = 0; foreach (IVector3D vect in Traverse) { pAngConv.SetAngle(vect.Azimuth, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); int iPrec = 7; if (Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds) { iPrec = 0; } string sBearing = pAngConv.GetString(Plan.DirectionFormat, Plan.AngleUnits, iPrec); string sDescription = Utils.FormatDirectionDashesToDegMinSecSymbols(sBearing) + ", " + (vect.Magnitude / dMetersPerUnit).ToString("0.000"); string sDistResidual = ((vect.Magnitude - AdjustedTraverse[i].Magnitude) / dMetersPerUnit).ToString("0.000"); //get the angle difference between the vectors IVector3D vec1 = new Vector3DClass(); vec1.PolarSet(vect.Azimuth, 0, 1); IVector3D vec2 = new Vector3DClass(); vec2.PolarSet(AdjustedTraverse[i].Azimuth, 0, 1); double dAngleDifference = Math.Acos(vec1.DotProduct(vec2)); pAngConv.SetAngle(dAngleDifference, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); string sAngResidual = pAngConv.GetString(esriDirectionType.esriDTPolar, Plan.AngleUnits, iPrec); sAngResidual = Utils.FormatDirectionDashesToDegMinSecSymbols(sAngResidual); TraverseGrid.Rows.Add(FromToList[i], sDescription, lstAdjustedCourses[i], sAngResidual + ", " + sDistResidual); i++; } }
public override IGeometry CreateGeometry() { IPointCollection pointCollection = new PolygonClass(); IZAware zAware = pointCollection as IZAware; zAware.ZAware = true; IPoint point = new PointClass(); point.X = -_width / 2; point.Y = -_height / 2; point.Z = 0; pointCollection.AddPoint(point); point = new PointClass(); point.X = -_width / 2; point.Y = _height / 2; point.Z = 0; pointCollection.AddPoint(point); point = new PointClass(); point.X = _width / 2; point.Y = _height / 2; point.Z = 0; pointCollection.AddPoint(point); point = new PointClass(); point.X = _width / 2; point.Y = -_height / 2; point.Z = 0; pointCollection.AddPoint(point); ((IPolygon)pointCollection).Close(); IConstructMultiPatch patch = new MultiPatchClass(); patch.ConstructExtrude(_polyline.Length, pointCollection as IGeometry); IVector3D vectorZ = new Vector3DClass(); vectorZ.SetComponents(0, 0, 1); IVector3D vector3D = new Vector3DClass(); vector3D.SetComponents(_polyline.ToPoint.X - _polyline.FromPoint.X, _polyline.ToPoint.Y - _polyline.FromPoint.Y, _zdgc - _qdgc); double rotateAngle = Math.Acos(vector3D.ZComponent / vector3D.Magnitude); IVector3D vectorAxis = vectorZ.CrossProduct(vector3D) as IVector3D; ITransform3D transform3D = patch as ITransform3D; transform3D.RotateVector3D(vectorAxis, rotateAngle); transform3D.Move3D(_polyline.FromPoint.X, _polyline.FromPoint.Y, _qdgc); return(patch as IGeometry); }
//根据两点构建3D向量 public static IVector3D CreateVector3DTwoPoints(IPoint toPoint, IPoint fromPoint) { if (fromPoint.Z.Equals(Double.NaN)) { fromPoint.Z = 0; } if (toPoint.Z.Equals(Double.NaN)) { toPoint.Z = 0; } IVector3D vector3D = new Vector3DClass(); vector3D.ConstructDifference(toPoint, fromPoint); return(vector3D); }
/// <summary> /// Occurs when this command is clicked /// </summary> public override void OnClick() { ICamera scenecamera = (ICamera)m_sceneHookHelper.Camera; IVector3D pvector3D = new Vector3DClass(); pvector3D.ConstructDifference(scenecamera.Observer, scenecamera.Target); ISphere pShere = new SphereClass(); pShere.Center = scenecamera.Target; pShere.Radius = scenecamera.ViewingDistance * Math.Tan(scenecamera.ViewFieldAngle * Math.PI / 180) * 0.5; IEnvelope penve = pShere.Envelope; m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation.VisibleBounds = penve; m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null); }
public void LoadModel(string sFile) { IImport3DFile file = new Import3DFileClass(); file.CreateFromFile(sFile); IGeometry geometry = file.Geometry; this.m_pMarker3DSymbol.Shape = geometry; if (System.IO.Path.GetExtension(sFile).ToLower() == ".wrl") { IVector3D pAxis = new Vector3DClass(); pAxis.SetComponents(1.0, 0.0, 0.0); this.RotateGeometry(this.m_pMarker3DSymbol, pAxis, 90.0); } this.m_pMarker3DSymbol.UseMaterialDraping = true; this.m_pMarker3DSymbol.RestrictAccessToShape(); }
public IGeometry CreateSphere(IPoint centerPoint, double radius, double minLon = 0.0, double maxLon = 360.0, double minLat = -90.0, double maxLat = 90.0, double stepAngle = 18.0, bool bSmooth = false, bool bFlipS = false, bool bFlipT = false) { IMultiPatch patch = new MultiPatchClass(); IGeometryCollection pGCol = patch as IGeometryCollection; IGeometry2 pGeom; IPoint pt; IPointCollection pStrip; IVector3D pVector = new Vector3DClass(); IEncode3DProperties pGE = new GeometryEnvironmentClass(); double xStep = (maxLon - minLon) / stepAngle; double yStep = (maxLat - minLat) / (stepAngle / 2.0); double lonRange = maxLon - minLon; double latRange = maxLat - minLat; object missing = Type.Missing; double lon = minLon; while (lon < maxLon) { pStrip = new TriangleStripClass(); double lat = minLat; while (lat < maxLat) { double azi = DegreesToRadians(lon); double inc = DegreesToRadians(lat); pVector.PolarSet(-azi, inc, radius); pt = new PointClass(); pt.X = centerPoint.X + pVector.XComponent; pt.Y = centerPoint.Y + pVector.YComponent; pt.Z = centerPoint.Z + pVector.ZComponent; double s = (lon - minLon) / lonRange; if (bFlipS) { s = 1 + (s * -1); } if (s <= 0) { s = 0.001; } else if (s >= 1) { s = 0.999; } double t = (maxLat - lat) / latRange; if (bFlipT) { t = 1 + (t * -1); } if (t <= 0) { t = 0.001; } else if (t >= 1) { t = 0.999; } double m = 0.0; pGE.PackTexture2D(s, t, out m); if (bSmooth) { pVector.Normalize(); pGE.PackNormal(pVector, out m); } pt.M = m; pStrip.AddPoint(pt, ref missing, ref missing); if ((lat != -90) && (lat != 90)) { azi = (lon + xStep) * Math.PI / 180.00; inc = lat * Math.PI / 180.00; pVector.PolarSet(-azi, inc, radius); pt = new PointClass(); pt.X = centerPoint.X + pVector.XComponent; pt.Y = centerPoint.Y + pVector.YComponent; pt.Z = centerPoint.Z + pVector.ZComponent; s = (lon + xStep - minLon) / lonRange; if (bFlipS) { s = 1 + (s * -1); } if (s <= 0) { s = 0.001; } else if (s >= 1) { s = 0.999; } t = (maxLat - lat) / latRange; if (bFlipT) { t = 1 + (t * -1); } if (t <= 0) { t = 0.001; } else if (t >= 1) { t = 0.999; } m = 0.0; pGE.PackTexture2D(s, t, out m); if (bSmooth) { pVector.Normalize(); pGE.PackNormal(pVector, out m); } pt.M = m; pStrip.AddPoint(pt, ref missing, ref missing); } lat = lat + yStep; } pGeom = pStrip as IGeometry2; pGCol.AddGeometry(pGeom, ref missing, ref missing); lon = lon + xStep; } IMAware pMAware = patch as IMAware; pMAware.MAware = true; return(patch); }
private IVector GetClosingVector(List<IVector3D> TraverseCourses, IPoint StartPoint, IPoint EndPoint, out double SUMofLengths) { IVector SumVec = null; SUMofLengths = 0; for (int i = 0; i < TraverseCourses.Count - 1; i++) { if (i == 0) { SUMofLengths = TraverseCourses[0].Magnitude + TraverseCourses[1].Magnitude; SumVec = TraverseCourses[0].AddVector(TraverseCourses[1]); } else { IVector3D SumVec3D = SumVec as IVector3D; SUMofLengths += TraverseCourses[i + 1].Magnitude; SumVec = SumVec3D.AddVector(TraverseCourses[i + 1]); } } double dCalcedEndX = StartPoint.X + SumVec.ComponentByIndex[0]; double dCalcedEndY = StartPoint.Y + SumVec.ComponentByIndex[1]; IVector3D CloseVector3D = new Vector3DClass(); CloseVector3D.SetComponents(dCalcedEndX - EndPoint.X, dCalcedEndY - EndPoint.Y, 0); IVector CloseVector = CloseVector3D as IVector; return CloseVector; }
private bool TraceLines(ref IGSForwardStar FwdStar, int StartNodeId, ref int BranchCount, ref int TracedLinesCount, ref int LoopCount, ref int TerminusCount, ref List<string> FromToLine, ref List<int> FromList, ref List<int> ToList, int iInfinityChecker) { iInfinityChecker++; if (iInfinityChecker > 5000) return false; //(This is a self-calling function.) In this context 5000 downstream lines is like infinity, //so exit gracefully, and avoid probable endless loop. //Possible cause of endless loop? Corrupted data; example, a line with the same from and to point id IVector3D vect = new Vector3DClass(); try { ILongArray iLngArr = FwdStar.get_ToNodes(StartNodeId); //get_ToNodes returns an array of radiated points, not "TO" points in the fabric data model sense int iCnt2 = 0; iCnt2 = iLngArr.Count; if (iCnt2 == 1) TerminusCount++; IGSLine pGSLine = null; for (int i = 0; i < iCnt2; i++) { int i2 = iLngArr.get_Element(i); string sFromTo = StartNodeId.ToString() + "," + i2.ToString(); string sToFrom = i2.ToString() + "," + StartNodeId.ToString(); if (FromToLine.Contains(sFromTo) || FromToLine.Contains(sToFrom)) { if (FromToLine.Contains(sFromTo)) LoopCount++; continue; } if (iCnt2 > 2) BranchCount++; TracedLinesCount++; FromToLine.Add(StartNodeId.ToString() + "," + i2.ToString()); bool bIsReversed = FwdStar.GetLine(StartNodeId, i2, ref pGSLine); if (bIsReversed) { FromList.Add(-StartNodeId); ToList.Add(-i2); vect.PolarSet(pGSLine.Bearing + Math.PI, 0, pGSLine.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north } else { FromList.Add(StartNodeId); ToList.Add(i2); vect.PolarSet(pGSLine.Bearing, 0, pGSLine.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north } if (!TraceLines(ref FwdStar, i2, ref BranchCount, ref TracedLinesCount,ref LoopCount, ref TerminusCount, ref FromToLine,ref FromList, ref ToList, iInfinityChecker)) return false; } return true; } catch { return false; } }
/// <summary> /// 生成可视与不可视域的多面体 张琪 20110621 /// </summary> /// <param name="bIsVis">是否可视</param> /// <param name="pObsPt">观察点</param> /// <param name="pTarPt">目标点</param> /// <param name="pVisLine">可视线要素</param> /// <param name="pInVisLine">不可视线要素</param> /// <param name="pVisPatch">可视多面体</param> /// <param name="pInVisPatch">不可视多面体</param> /// <param name="dTargetHeight"></param> public void CreateVerticalLOSPatches(bool bIsVis, ESRI.ArcGIS.Geometry.IPoint pObsPt, ESRI.ArcGIS.Geometry.IPoint pTarPt, IPolyline pVisLine, IPolyline pInVisLine, IGeometryCollection pVisPatch, IGeometryCollection pInVisPatch, double dTargetHeight) { IGeometryCollection pGeomColl = pVisLine as IGeometryCollection; //存储可视域线要素 IMultiPatch pVisMPatch = pVisPatch as IMultiPatch; IMultiPatch pInVisMPatch = pInVisPatch as IMultiPatch; //生成不可视域要素 dTargetHeight = pTarPt.Z; double dist1 = 0; double dist2; IPointCollection pPc; IClone pClone; ESRI.ArcGIS.Geometry.IPoint pLastVisPoint = null; IPointCollection pVisFan = new TriangleFanClass();//用于存储可视域多面体要素 object before = Type.Missing; object after = Type.Missing; for (int i = 0; i < pGeomColl.GeometryCount; i++)//遍历可视域线要素 { pPc = pGeomColl.get_Geometry(i) as IPointCollection; if (i == 0)//当为第一个可视域线要素是先要存储观察点要素 { pClone = pObsPt as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pClone = pPc.get_Point(0) as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); ESRI.ArcGIS.Geometry.IPoint pStartPoint = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; } pClone = pPc as IClone; pVisFan.AddPointCollection(pClone.Clone() as IPointCollection); //将可视域线要素的点集合存储于pVisFan中 if (i == pGeomColl.GeometryCount - 1) //当为可视域最后一个线要素时 { IVector3D pV = new Vector3DClass(); ESRI.ArcGIS.Geometry.IPoint p1; pClone = pObsPt as IClone; p1 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p1.Z = 0; ESRI.ArcGIS.Geometry.IPoint p2; pClone = pPc.get_Point(pPc.PointCount - 1) as IClone; p2 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p2.Z = 0; pV.ConstructDifference(p1, p2); dist1 = pV.Magnitude; pLastVisPoint = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; if (pInVisLine == null) { if (pTarPt.Z > pPc.get_Point(pPc.PointCount - 1).Z)//当被观察点高程高于最后一点要素时则到被观点都是可视的 { pClone = pTarPt as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); } } } pVisPatch.AddGeometry(pVisFan as IGeometry, ref before, ref after); //根据获得的点要素集生成TriangleFanClass } if (pInVisLine != null) //当不可视域的线要素不为空时 { pGeomColl = pInVisLine as IGeometryCollection; IPointCollection pInVisRing = new RingClass();//用于存储不可视域点要素集并生成RingClass for (int i = 0; i < pGeomColl.GeometryCount; i++) { pPc = pGeomColl.get_Geometry(i) as IPointCollection; pClone = pPc.get_Point(0) as IClone; pInVisRing.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pClone = pPc as IClone; pInVisRing.AddPointCollection(pClone.Clone() as IPointCollection); if (i == pGeomColl.GeometryCount - 1) { IVector3D pV = new Vector3DClass(); pClone = pObsPt as IClone; ESRI.ArcGIS.Geometry.IPoint p1 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p1.Z = 0; pClone = pPc.get_Point(pPc.PointCount - 1) as IClone; ESRI.ArcGIS.Geometry.IPoint p2 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p2.Z = 0; pV.ConstructDifference(p1, p2); dist2 = pV.Magnitude; if (dist1 < dist2) { pClone = pObsPt as IClone; p1 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p1.Z = 0; pClone = pPc.get_Point(0) as IClone; p2 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p2.Z = 0; pV.ConstructDifference(p1, p2); double theDist1; theDist1 = pV.Magnitude; double slope = (pObsPt.Z - pPc.get_Point(0).Z) / theDist1; pClone = pPc.get_Point(pPc.PointCount - 1) as IClone; ESRI.ArcGIS.Geometry.IPoint pEndPoint = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p2 = pClone.Clone() as ESRI.ArcGIS.Geometry.IPoint; p2.Z = 0; pV.ConstructDifference(p1, p2); double theDist2 = pV.Magnitude; double deltaZ = theDist2 * slope; double theHeight = pObsPt.Z - deltaZ; pEndPoint.Z = theHeight; pClone = pEndPoint as IClone; pInVisRing.AddPoint(pClone.Clone() as IPoint, ref before, ref after); if (bIsVis)//为True时说明不可视域线要素空间范围内存在可视区域 { pVisFan = new TriangleFanClass(); pClone = pObsPt as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pClone = pTarPt as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pVisPatch.AddGeometry(pVisFan as IGeometry, ref before, ref after); } else { dTargetHeight = pEndPoint.Z; } } else { if (bIsVis) { if (pTarPt.Z > pLastVisPoint.Z) { pVisFan = new TriangleFanClass(); pClone = pObsPt as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pClone = pTarPt as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pClone = pLastVisPoint as IClone; pVisFan.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pVisPatch.AddGeometry(pVisFan as IGeometry, ref before, ref after); } } } } pClone = pPc.get_Point(0) as IClone; pInVisRing.AddPoint(pClone.Clone() as IPoint, ref before, ref after); pInVisPatch.AddGeometry(pInVisRing as IGeometry, ref before, ref after);//获取每段不可视域线要素点集合并生成RingClass pInVisMPatch.PutRingType(pInVisRing as IRing, esriMultiPatchRingType.esriMultiPatchRing); } } }
protected void AddTraverseInfoToGrid(IGSPlan Plan, DataGridView TraverseGrid, List<IVector3D> Traverse, List<IVector3D> AdjustedTraverse, List<string> FromToList) { ICadastralUnitConversion pCadUnitConverter = new CadastralUnitConversionClass(); double dMetersPerUnit = pCadUnitConverter.ConvertDouble(1, Plan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter); IAngularConverter pAngConv = new AngularConverterClass(); Utilities Utils = new Utilities(); List<string> lstAdjustedCourses = new List<string>(); List<string> lstResiduals = new List<string>(); foreach (IVector3D vect in AdjustedTraverse) { pAngConv.SetAngle(vect.Azimuth, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); int iPrec = 7; if (Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds) iPrec = 0; string sBearing = pAngConv.GetString(Plan.DirectionFormat, Plan.AngleUnits, iPrec); string sAdjusted = Utils.FormatDirectionDashesToDegMinSecSymbols(sBearing) + ", " + (vect.Magnitude / dMetersPerUnit).ToString("0.000"); lstAdjustedCourses.Add(sAdjusted); } int i = 0; foreach (IVector3D vect in Traverse) { pAngConv.SetAngle(vect.Azimuth, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); int iPrec = 7; if(Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds) iPrec=0; string sBearing = pAngConv.GetString(Plan.DirectionFormat, Plan.AngleUnits, iPrec); string sDescription = Utils.FormatDirectionDashesToDegMinSecSymbols(sBearing) + ", " + (vect.Magnitude/dMetersPerUnit).ToString("0.000"); string sDistResidual= ((vect.Magnitude-AdjustedTraverse[i].Magnitude)/dMetersPerUnit).ToString("0.000"); //get the angle difference between the vectors IVector3D vec1 = new Vector3DClass(); vec1.PolarSet(vect.Azimuth, 0, 1); IVector3D vec2 = new Vector3DClass(); vec2.PolarSet(AdjustedTraverse[i].Azimuth, 0, 1); double dAngleDifference = Math.Acos(vec1.DotProduct(vec2)); pAngConv.SetAngle(dAngleDifference, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); string sAngResidual = pAngConv.GetString(esriDirectionType.esriDTPolar, Plan.AngleUnits, iPrec); sAngResidual = Utils.FormatDirectionDashesToDegMinSecSymbols(sAngResidual); TraverseGrid.Rows.Add(FromToList[i], sDescription, lstAdjustedCourses[i], sAngResidual + ", " + sDistResidual); i++; } }
private bool TraceLines(ref IGSForwardStar FwdStar, int StartNodeId, ref int BranchCount, ref int TracedLinesCount, ref int LoopCount, ref int TerminusCount, ref List <string> FromToLine, ref List <int> FromList, ref List <int> ToList, int iInfinityChecker) { iInfinityChecker++; if (iInfinityChecker > 5000) { return(false); } //(This is a self-calling function.) In this context 5000 downstream lines is like infinity, //so exit gracefully, and avoid probable endless loop. //Possible cause of endless loop? Corrupted data; example, a line with the same from and to point id IVector3D vect = new Vector3DClass(); try { ILongArray iLngArr = FwdStar.get_ToNodes(StartNodeId); //get_ToNodes returns an array of radiated points, not "TO" points in the fabric data model sense int iCnt2 = 0; iCnt2 = iLngArr.Count; if (iCnt2 == 1) { TerminusCount++; } IGSLine pGSLine = null; for (int i = 0; i < iCnt2; i++) { int i2 = iLngArr.get_Element(i); string sFromTo = StartNodeId.ToString() + "," + i2.ToString(); string sToFrom = i2.ToString() + "," + StartNodeId.ToString(); if (FromToLine.Contains(sFromTo) || FromToLine.Contains(sToFrom)) { if (FromToLine.Contains(sFromTo)) { LoopCount++; } continue; } if (iCnt2 > 2) { BranchCount++; } TracedLinesCount++; FromToLine.Add(StartNodeId.ToString() + "," + i2.ToString()); bool bIsReversed = FwdStar.GetLine(StartNodeId, i2, ref pGSLine); if (bIsReversed) { FromList.Add(-StartNodeId); ToList.Add(-i2); vect.PolarSet(pGSLine.Bearing + Math.PI, 0, pGSLine.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north } else { FromList.Add(StartNodeId); ToList.Add(i2); vect.PolarSet(pGSLine.Bearing, 0, pGSLine.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north } if (!TraceLines(ref FwdStar, i2, ref BranchCount, ref TracedLinesCount, ref LoopCount, ref TerminusCount, ref FromToLine, ref FromList, ref ToList, iInfinityChecker)) { return(false); } } return(true); } catch { return(false); } }
protected override void OnClick() { ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension"); IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd; ICadastralPacketManager pCadPacketMan = (ICadastralPacketManager)pCadEd; //bool bStartedWithPacketOpen = pCadPacketMan.PacketOpen; if (pParcEditorMan == null) { return; } IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); if (pEd.EditState == esriEditState.esriStateNotEditing) { MessageBox.Show("Please start editing and try again."); return; } IParcelConstruction pConstr = pParcEditorMan.ParcelConstruction; IParcelConstruction4 pConstr4 = pConstr as IParcelConstruction4; ICadastralPoints pCadastralPts = pConstr4 as ICadastralPoints; ICadastralEditorSettings2 pCadastralEditorSettings2 = pCadEd as ICadastralEditorSettings2; ICadastralFixedPoints pFixedPoints = pCadastralPts as ICadastralFixedPoints; IPointCalculation pPointCalc = new PointCalculationClass(); if (pConstr == null) { return; } IGSLine pParcelLine = null; IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd; IGSPoint pStartPoint = null; List <int> lstPointIds = new List <int>(); List <IVector3D> Traverse = new List <IVector3D>(); //get rotation here IParcelConstructionData pConstrData = pConstr4.ConstructionData; IConstructionParentParcels pConstructionParentParcels = pConstrData as IConstructionParentParcels; ICadastralUndoRedo pCadUndoRedo = pConstr as ICadastralUndoRedo; try { int iParcelID = -1; if (pConstructionParentParcels.ParentParcelCount > 0) { pConstructionParentParcels.GetParentParcel(0, ref iParcelID); } ICadastralParcel pCadaParcel = pCadPacketMan.JobPacket as ICadastralParcel; IGSParcel pGSParcel = null; if (pCadaParcel != null) { pGSParcel = pCadaParcel.GetParcel(iParcelID); } //if in measurement view then rotation is 0 double TheRotation = 0; if (pGSParcel == null) { pGSParcel = pConstr.Parcel; } if (!pCadastralEditorSettings2.MeasurementView) { TheRotation = pGSParcel.Rotation;//radians } if (TheRotation == 123456789) { TheRotation = 0; } pPointCalc.Rotation = TheRotation; IGSPoint pClosingPoint = null; #region simple method as fall-back bool bUseSimpleStackSelection = false; if (bUseSimpleStackSelection) { //bool bLineSelectionSequence = false; //IGSLine pLastSelectedGSLineInGrid = null; //for (int i = 0; i < pConstr.LineCount; i++) //{ // if (pConstr.GetLineSelection(i)) // { // if (pConstr.GetLine(i, ref pParcelLine)) // { // if (!bLineSelectionSequence) //first line // { // pStartPoint = pCadastralPts.GetPoint(pParcelLine.FromPoint); // pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint); // } // pPointCalc.AddLine(pParcelLine); // pLastSelectedGSLineInGrid = pParcelLine; // pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint); // lstPointIds.Add(pToPoint.Id); // } // bLineSelectionSequence = true; // double dBear = pParcelLine.Bearing; //Azimuth of IVector3D is north azimuth radians zero degrees north // double dDist = pParcelLine.Distance; // IVector3D vec = new Vector3DClass(); // vec.PolarSet(dBear, 0, dDist); ////Azimuth of IVector3D is north azimuth radians zero degrees north // Traverse.Add(vec); // } // else // { // if (bLineSelectionSequence && pConstr.GetLine(i, ref pParcelLine) && HasLineSelectionAfter(pConstr, i)) // //if there was a prior selection and this line is a complete line, and there is no later selection // { // MessageBox.Show("Please select a continuous set of lines for closure."); // return; // } // } //} //pClosingPoint = pCadastralPts.GetPoint(pLastSelectedGSLineInGrid.ToPoint); } else #endregion {//build a forward star for the selected lines IEnumCELines pCELines = new EnumCELinesClass(); IEnumGSLines pEnumGSLines = (IEnumGSLines)pCELines; ILongArray pLongArray = new LongArrayClass(); int iFirstToNode = -1; for (int i = 0; i < pConstr.LineCount; i++) { if (pConstr.GetLineSelection(i)) { if (pConstr.GetLine(i, ref pParcelLine)) { if (iFirstToNode < 0) { iFirstToNode = pParcelLine.ToPoint; } pLongArray.Add(i); pCELines.Add(pParcelLine); } } } if (pCELines.Count == 0) { MessageBox.Show("No lines selected. Please select a continuous set of lines for closure." + Environment.NewLine + "Line selection should not have branches.", "Traverse"); return; } IParcelLineFunctions3 ParcelLineFx = new ParcelFunctionsClass(); IGSForwardStar pFwdStar = ParcelLineFx.CreateForwardStar(pEnumGSLines); //forward star object is now created for all the selected lines, //need to first re-sequence the lines, and test for branching and discontinuity int iBranches = 0; int iTracedLines = 0; int iLoops = 0; int iTerminals = 0; List <int> LineIDList = new List <int>(); List <int> FromList = new List <int>(); List <int> ToList = new List <int>(); List <string> FromToLine = new List <string>(); bool bTraceSucceeded = TraceLines(ref pFwdStar, iFirstToNode, ref iBranches, ref iTracedLines, ref iLoops, ref iTerminals, ref FromToLine, ref FromList, ref ToList, 0); if (iBranches > 0) { MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine + "Line selection should not have branches.", "Traverse"); return; } if (iTracedLines < pLongArray.Count) { MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine + "Selected Lines should be connected in a single sequence without branches.", "Traverse"); return; } //if it's a single loop check to see if the sequence needs to be reversed //CW or CCW based on bearings if (iLoops == 1) { bool bIsReversed = false; foreach (int i in FromList) { if (i < 0) { bIsReversed = true; } else { bIsReversed = false; break; } } if (bIsReversed) {//all courses are running reversed, so reverse the whole sequence FromToLine.Clear(); FromList.Reverse(); ToList.Reverse(); int iNewFrom = -ToList[ToList.Count - 1]; int iNewTo = -FromList[ToList.Count - 1]; string sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString(); FromToLine.Add(sNewFromTo); for (int i = 1; i < ToList.Count; i++) { iNewFrom = -ToList[i - 1]; iNewTo = -FromList[i - 1]; sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString(); FromToLine.Add(sNewFromTo); } } } LineIDList.Clear(); FromList.Clear(); ToList.Clear(); pLongArray.RemoveAll(); pCadUndoRedo.StartUndoRedoSession("Adjust Traverse"); if (iLoops == 0) { //re-sequence using TraceLines function based on either end point, because the order of //selected construction lines in grid don't control start or end point FromToLine.Clear(); int iTerminus = -1; iTracedLines = 0; iBranches = 0; iLoops = 0; iTerminals = 0; FindTerminusForSequence(ref pFwdStar, iFirstToNode, ref iTerminus, 0); if (iTerminus == -1) { pCadUndoRedo.WriteUndoRedoSession(false); return; } TraceLines(ref pFwdStar, iTerminus, ref iBranches, ref iTracedLines, ref iLoops, ref iTerminals, ref FromToLine, ref FromList, ref ToList, 0); } List <IVector3D> SequencedTraverse = new List <IVector3D>(); IGSLine pGSLineInPath = null; foreach (string s in FromToLine) { string[] sFromTo = s.Split(','); int iFrom = Convert.ToInt32(sFromTo[0]); int iTo = Convert.ToInt32(sFromTo[1]); bool bReversed = pFwdStar.GetLine(iFrom, iTo, ref pGSLineInPath); if (bReversed) { IGSLine pGSLine180 = new GSLineClass(); pGSLine180.FromPoint = pGSLineInPath.ToPoint; pGSLine180.ToPoint = pGSLineInPath.FromPoint; pGSLine180.Bearing = pGSLineInPath.Bearing + Math.PI; pGSLine180.Distance = pGSLineInPath.Distance; IVector3D vec180 = new Vector3DClass(); vec180.PolarSet(pGSLine180.Bearing, 0, pGSLine180.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north Traverse.Add(vec180); lstPointIds.Add(pGSLine180.ToPoint); pPointCalc.AddLine(pGSLine180); } else { double dBear = pGSLineInPath.Bearing; double dDist = pGSLineInPath.Distance; IVector3D vec = new Vector3DClass(); vec.PolarSet(dBear, 0, dDist); //Azimuth of IVector3D is north azimuth radians zero degrees north Traverse.Add(vec); lstPointIds.Add(pGSLineInPath.ToPoint); pPointCalc.AddLine(pGSLineInPath); } if (pStartPoint == null) { if (bReversed) { pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint); } else { pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint); } } if (bReversed) { pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint); } else { pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint); } } } if (pStartPoint == null) { pCadUndoRedo.WriteUndoRedoSession(false); return; } IPoint pStart = new PointClass(); pStart.X = pStartPoint.X; pStart.Y = pStartPoint.Y; string sAdjustMethod = "Compass"; esriParcelAdjustmentType eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass; if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentNone || pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCompass) { eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass; } else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCrandall) { sAdjustMethod = "Crandall"; eAdjMethod = pCadastralEditorSettings2.ParcelAdjustment; } else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentTransit) { sAdjustMethod = "Transit"; eAdjMethod = pCadastralEditorSettings2.ParcelAdjustment; } pPointCalc.CalculatePoints(eAdjMethod, pStartPoint.Id, pStartPoint, pClosingPoint.Id, pClosingPoint, true); ITraverseClosure pClose = pPointCalc.Closure; List <string> lstCoursesFromTo = new List <string>(); List <IVector3D> AdjustedTraverse = new List <IVector3D>(); double dAdjustedPointX = 0; double dAdjustedPointY = 0; double dPreviousPointX = 0; double dPreviousPointY = 0; for (int i = 0; i < pClose.CourseCount; i++) { IGSPoint pPt = pCadastralPts.GetPoint(lstPointIds[i]); dAdjustedPointY = pPointCalc.GetCalculatedPoint(lstPointIds[i], ref dAdjustedPointX); string sFromTo = ""; IVector3D pAdjustedLine = new Vector3DClass(); if (i == 0) { sFromTo = pStartPoint.Id.ToString() + "-" + lstPointIds[i].ToString(); pAdjustedLine.SetComponents(dAdjustedPointX - pStartPoint.X, dAdjustedPointY - pStartPoint.Y, 0); } else { sFromTo = lstPointIds[i - 1].ToString() + "-" + lstPointIds[i].ToString(); pAdjustedLine.SetComponents(dAdjustedPointX - dPreviousPointX, dAdjustedPointY - dPreviousPointY, 0); } lstCoursesFromTo.Add(sFromTo); IVector3D Z_Axis = new Vector3DClass(); Z_Axis.SetComponents(0, 0, 100); pAdjustedLine.Rotate(TheRotation, Z_Axis); AdjustedTraverse.Add(pAdjustedLine); dPreviousPointX = dAdjustedPointX; dPreviousPointY = dAdjustedPointY; pPt.X = dAdjustedPointX; pPt.Y = dAdjustedPointY; if (!pCadastralEditorSettings2.MeasurementView) { pFixedPoints.SetFixedPoint(lstPointIds[i], true); } } double dMisclosureDistance = pClose.MisclosureDistance; double dMisclosureBearing = pClose.MisclosureDirection; IVector MiscloseVector = new Vector3DClass(); IEditProperties2 pEdProps = pEd as IEditProperties2; IAngularConverter pAngConv = new AngularConverterClass(); pAngConv.SetAngle(dMisclosureBearing, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); //int iPrec = 7; //if (pConstr.Parcel.Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds) // iPrec = 0; string sMiscloseBearing = pAngConv.GetString(pEdProps.DirectionType, pEdProps.DirectionUnits, pEdProps.AngularUnitPrecision); Utilities UTIL = new Utilities(); string sRatio = "High Accuracy"; if (pClose.RelativeErrorRatio < 10000) { sRatio = "1:" + pClose.RelativeErrorRatio.ToString("0"); } if (dMisclosureDistance >= 0.001) { sMiscloseBearing = UTIL.FormatDirectionDashesToDegMinSecSymbols(sMiscloseBearing); } else { sMiscloseBearing = "----"; } ICadastralUnitConversion pCadUnitConverter = new CadastralUnitConversionClass(); double dMetersPerUnit = pCadUnitConverter.ConvertDouble(1, pConstr.Parcel.Plan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter); string sReport = "Closure:" + Environment.NewLine + " error: " + sRatio + Environment.NewLine + " distance: " + (dMisclosureDistance / dMetersPerUnit).ToString("0.000") + Environment.NewLine + " bearing: " + sMiscloseBearing + Environment.NewLine + " xdist: " + (pClose.MisclosureX / dMetersPerUnit).ToString("0.000") + Environment.NewLine + " ydist: " + (pClose.MisclosureY / dMetersPerUnit).ToString("0.000") + Environment.NewLine + " courses: " + (pClose.CourseCount) + Environment.NewLine + Environment.NewLine + "Adjustment:" + Environment.NewLine + " method: " + sAdjustMethod; dlgTraverseResults dlgTraverseResults = new dlgTraverseResults(); AddTraverseInfoToGrid(pConstr.Parcel.Plan, dlgTraverseResults.dataGridView1, Traverse, AdjustedTraverse, lstCoursesFromTo); dlgTraverseResults.txtMiscloseReport.Text = sReport; DialogResult dRes = dlgTraverseResults.ShowDialog(); if (dRes == DialogResult.Cancel) { //since we cancelled, set the points back foreach (int i in lstPointIds) { pFixedPoints.SetFixedPoint(i, false); } pCadUndoRedo.WriteUndoRedoSession(false); } else { pCadUndoRedo.WriteUndoRedoSession(true); } } catch (Exception ex) { MessageBox.Show(ex.Message + Environment.NewLine + "Line number:" + ex.LineNumber().ToString() + " in " + ex.TargetSite.Name, "Traverse"); pCadUndoRedo.WriteUndoRedoSession(false); } }
/// <summary> /// 构造函数 /// </summary> /// <param name="graphicsLayer">图层</param> /// <param name="kmlCircle">圆的kml</param> public Circle_ArcGlobe(IGlobeGraphicsLayer _graphicsLayer, KmlCircle kmlCircle) { this.ElementType = Core.Model.ElementTypeEnum.Circle; graphicsLayer = _graphicsLayer; lineSymbol = new SimpleLineSymbolClass(); lineSymbol.Color = new RgbColorClass() { Red = kmlCircle.StrokeColor.R, Green = kmlCircle.StrokeColor.G, Blue = kmlCircle.StrokeColor.B }; if (kmlCircle.StrokeWidth == 0) { kmlCircle.StrokeWidth = 2; } lineSymbol.Width = kmlCircle.StrokeWidth; fillSymbol = new SimpleFillSymbolClass(); fillSymbol.Outline = lineSymbol; fillSymbol.Color = new RgbColorClass() { Red = kmlCircle.FillColor.R, Green = kmlCircle.FillColor.G, Blue = kmlCircle.FillColor.B }; radius = kmlCircle.Radius; outlineColor = kmlCircle.StrokeColor; fillColor = kmlCircle.FillColor; centerPoint = new PointClass();//圆心坐标 centerPoint.PutCoords(kmlCircle.Position.Lng, kmlCircle.Position.Lat); centerPoint.Z = kmlCircle.Position.Alt; missing = System.Type.Missing; IZAware zAware = (IGeometry)centerPoint as IZAware; zAware.ZAware = true; upperAxisVector3D = new Vector3DClass(); upperAxisVector3D.SetComponents(0, 0, 2); lowerAxisVector3D = new Vector3DClass(); lowerAxisVector3D.SetComponents(0, 0, -2); lowerAxisVector3D.XComponent -= vectorComponentOffset; lowerAxisVector3D.YComponent -= vectorComponentOffset;//TODO normalVector3D = upperAxisVector3D.CrossProduct(lowerAxisVector3D) as IVector3D; normalVector3D.Magnitude = kmlCircle.Radius; double rotationAngleInRadians = 2 * (Math.PI / 180); //geometryCollection = new MultiPatchClass(); pointCollection = new PolygonClass(); for (int i = 0; i < 180; i++) { normalVector3D.Rotate(-1 * rotationAngleInRadians, upperAxisVector3D); IPoint vertexPoint = new PointClass(); vertexPoint.X = centerPoint.X + normalVector3D.XComponent; vertexPoint.Y = centerPoint.Y + normalVector3D.YComponent; vertexPoint.Z = centerPoint.Z; pointCollection.AddPoint(vertexPoint, missing, missing); } base.Symbol = fillSymbol; base.Geometry = pointCollection as IGeometry; flashTimer = new System.Timers.Timer(); flashTimer.Elapsed += new System.Timers.ElapsedEventHandler(flashTimer_Elapsed); flashTimer.Interval = 500; }
public bool HasParallelCurveMatchFeatures(IFeatureClass FeatureClass, IPolycurve inPolycurve, string WhereClause, double AngleToleranceTangentCompareInDegrees, double OrthogonalSearchDistance, out int outFoundLinesCount, out int outFoundParallelCurvesCount, ref List<string> CurveInfoFromNeighbours) { outFoundLinesCount = 0; outFoundParallelCurvesCount = 0; ILine pOriginalChord = new Line(); pOriginalChord.PutCoords(inPolycurve.FromPoint, inPolycurve.ToPoint); IVector3D vecOriginalSelected = new Vector3DClass(); vecOriginalSelected.PolarSet(pOriginalChord.Angle, 0, 1); int idxRadius = FeatureClass.FindField("RADIUS"); if (idxRadius == -1) return false; int idxCenterPointID = FeatureClass.FindField("CENTERPOINTID"); if (idxCenterPointID == -1) return false; object val = null; IGeometryBag pGeomBag = new GeometryBagClass(); IGeometryCollection pGeomColl = (IGeometryCollection)pGeomBag; IGeometry MultiPartPolyLine = new PolylineClass(); //qi IGeoDataset pGeoDS = (IGeoDataset)FeatureClass; ISpatialReference spatialRef = pGeoDS.SpatialReference; MultiPartPolyLine.SpatialReference = spatialRef; IGeometryCollection geometryCollection2 = MultiPartPolyLine as IGeometryCollection; ILine pNormalLine = new Line(); //new for (int i = -1; i < 2; i = i + 2) { double dOffset = OrthogonalSearchDistance * i; inPolycurve.QueryNormal(esriSegmentExtension.esriNoExtension, 0.5, true, dOffset, pNormalLine); ILine pThisLine = new Line(); pThisLine.PutCoords(pNormalLine.FromPoint, pNormalLine.ToPoint); pGeomColl.AddGeometry(pThisLine); //Although each line is connected to the other, create a new path for each line //this allows for future changes in case the input needs to be altered to separate paths. ISegmentCollection newPath = new PathClass(); object obj = Type.Missing; newPath.AddSegment((ISegment)pThisLine, ref obj, ref obj); //The spatial reference associated with geometryCollection will be assigned to all incoming paths and segments. geometryCollection2.AddGeometry(newPath as IGeometry, ref obj, ref obj); } ISpatialFilter pSpatFilt = new SpatialFilter(); pSpatFilt.WhereClause = WhereClause; pSpatFilt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatFilt.SearchOrder = esriSearchOrder.esriSearchOrderSpatial; pSpatFilt.Geometry = pGeomBag; IFeatureCursor pFeatCursLines = null; try { pFeatCursLines = FeatureClass.Search(pSpatFilt, false); } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } IFeature pFeat = pFeatCursLines.NextFeature(); while (pFeat != null) { IGeometry pFoundLineGeom = pFeat.ShapeCopy; //if the feature has no radius attribute, skip. double dRadius = 0; int iCtrPoint = -1; val = pFeat.get_Value(idxRadius); if (val == DBNull.Value) dRadius = 0; else dRadius = (double)val; if (dRadius == 0) {//null or zero radius so skip. Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } val = pFeat.get_Value(idxCenterPointID); if (val == DBNull.Value) {//null centrpointID so skip. Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } iCtrPoint = (int)val; ITopologicalOperator6 pTopoOp6 = (ITopologicalOperator6)MultiPartPolyLine; IGeometry pResultGeom = pTopoOp6.IntersectEx(pFoundLineGeom, false, esriGeometryDimension.esriGeometry0Dimension); if (pResultGeom == null) { Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } if (pResultGeom.IsEmpty) { Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } ISegmentCollection pFoundLineGeomSegs = pFoundLineGeom as ISegmentCollection; bool bHasCurves = false; pFoundLineGeomSegs.HasNonLinearSegments(ref bHasCurves); if (!bHasCurves) { Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } IPointCollection5 PtColl = (IPointCollection5)pResultGeom; if (PtColl.PointCount > 1) { Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } IPolycurve pPolyCurve4Tangent = pFoundLineGeom as IPolycurve; for (int j = 0; j < PtColl.PointCount; j++) { IPoint p = PtColl.get_Point(j); IPoint outPoint = new Point(); double dDistanceAlong = 0; double dDistanceFromCurve = 0; bool bOffsetRight = true; //work out if the point is to the left or right of the original inPolycurve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, p, false, outPoint, ref dDistanceAlong, ref dDistanceFromCurve, ref bOffsetRight); ILine pTangent = new Line(); dDistanceAlong = 0; dDistanceFromCurve = 0; bool bOnRight = true; pPolyCurve4Tangent.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, p, false, outPoint, ref dDistanceAlong, ref dDistanceFromCurve, ref bOnRight); pPolyCurve4Tangent.QueryTangent(esriSegmentExtension.esriNoExtension, dDistanceAlong, false, 100, pTangent); //compare the tangent bearing with the normal to check for orthogonality IVector3D vecTangent = new Vector3DClass(); vecTangent.PolarSet(pTangent.Angle, 0, 1); IVector3D vecNormal = new Vector3DClass(); vecNormal.PolarSet(pNormalLine.Angle, 0, 1); ILine pHitDistanceForRadiusDifference = new Line(); pHitDistanceForRadiusDifference.PutCoords(pNormalLine.FromPoint, outPoint); double dRadiusDiff = pHitDistanceForRadiusDifference.Length; double dDotProd = vecTangent.DotProduct(vecNormal); double dAngleCheck = Math.Acos(dDotProd) * 180 / Math.PI; //in degrees dAngleCheck = Math.Abs(dAngleCheck - 90); if (dAngleCheck < AngleToleranceTangentCompareInDegrees) { //work out concavity orientation with respect to the original line using the radius sign and dot product dDotProd = vecOriginalSelected.DotProduct(vecTangent); double dTangentCheck = Math.Acos(dDotProd) * 180 / Math.PI; // in degrees //dTangentCheck at this point should be close to 0 or 180 degrees. outFoundLinesCount++; bool bIsConvex = ((dTangentCheck < 90 && dRadius < 0 && !bOffsetRight) || (dTangentCheck > 90 && dRadius > 0 && !bOffsetRight) || (dTangentCheck < 90 && dRadius > 0 && bOffsetRight) || (dTangentCheck > 90 && dRadius < 0 && bOffsetRight)); double dUnitSignChange = 1; if (!bIsConvex) dUnitSignChange = -1; double dDerivedRadius = (Math.Abs(dRadius)) + dRadiusDiff * dUnitSignChange; dUnitSignChange = 1; //now compute inferred left/right for candidate if (bIsConvex && !bOffsetRight) dUnitSignChange = -1; if (!bIsConvex && bOffsetRight) dUnitSignChange = -1; dDerivedRadius = dDerivedRadius * dUnitSignChange; string sHarvestedCurveInfo = pFeat.OID.ToString() + "," + dDerivedRadius.ToString("#.000") + "," + iCtrPoint.ToString() + "," + dRadiusDiff.ToString("#.000"); CurveInfoFromNeighbours.Add(sHarvestedCurveInfo); } } Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursLines); bool bHasParallelCurveFeaturesNearby = (outFoundLinesCount > 0); return bHasParallelCurveFeaturesNearby; }
public bool HasTangentCurveMatchFeatures(IFeatureClass FeatureClass, IPolycurve inPolycurve, string WhereClause, double AngleToleranceTangentCompareInDegrees, double StraightLinesBreakLessThanInDegrees, double MaximumDeltaInDegrees, double ExcludeTangentsShorterThan, out int outFoundTangentCurvesCount, ref List<string> CurveInfoFromNeighbours) { outFoundTangentCurvesCount = 0; ILine pOriginalChord = new Line(); pOriginalChord.PutCoords(inPolycurve.FromPoint, inPolycurve.ToPoint); IVector3D vecOriginalSelected = new Vector3DClass(); vecOriginalSelected.PolarSet(pOriginalChord.Angle, 0, 1); int idxRadius = FeatureClass.FindField("RADIUS"); if (idxRadius == -1) return false; int idxCenterPointID = FeatureClass.FindField("CENTERPOINTID"); if (idxCenterPointID == -1) return false; object val = null; IGeometryBag pGeomBag = new GeometryBagClass(); IGeometryCollection pGeomColl = (IGeometryCollection)pGeomBag; IGeometry MultiPartPolyLine = new PolylineClass(); //qi IGeoDataset pGeoDS = (IGeoDataset)FeatureClass; ISpatialReference spatialRef = pGeoDS.SpatialReference; MultiPartPolyLine.SpatialReference = spatialRef; IGeometryCollection geometryCollection2 = MultiPartPolyLine as IGeometryCollection; ILine pTangentLineAtEnd = new Line(); //new ILine pTangentLineAtStart = new Line(); //new object objMissing = Type.Missing; for (int i = 0; i < 2; i++) { ILine pThisLine = null; if (i == 0) { inPolycurve.QueryTangent(esriSegmentExtension.esriExtendAtTo, 1.0, true, 0.2, pTangentLineAtEnd); pThisLine = new Line(); pThisLine.PutCoords(pTangentLineAtEnd.FromPoint, pTangentLineAtEnd.ToPoint); pGeomColl.AddGeometry(pThisLine); } else { inPolycurve.QueryTangent(esriSegmentExtension.esriExtendAtFrom, 0.0, true, 0.2, pTangentLineAtStart); pThisLine = new Line(); pThisLine.PutCoords(pTangentLineAtStart.FromPoint, pTangentLineAtStart.ToPoint); pGeomColl.AddGeometry(pThisLine); } //Create a new path for each line. ISegmentCollection newPath = new PathClass(); newPath.AddSegment((ISegment)pThisLine, ref objMissing, ref objMissing); //The spatial reference associated with geometryCollection will be assigned to all incoming paths and segments. geometryCollection2.AddGeometry(newPath as IGeometry, ref objMissing, ref objMissing); } //now buffer the lines IGeometryCollection outBufferedGeometryCol = new GeometryBagClass(); for (int jj = 0; jj < geometryCollection2.GeometryCount; jj++) { IPath pPath = geometryCollection2.get_Geometry(jj) as IPath; IGeometryCollection pPolyL = new PolylineClass(); pPolyL.AddGeometry((IGeometry)pPath); ITopologicalOperator topologicalOperator = (ITopologicalOperator)pPolyL; IPolygon pBuffer = topologicalOperator.Buffer(0.1) as IPolygon; outBufferedGeometryCol.AddGeometry(pBuffer, ref objMissing, ref objMissing); } ITopologicalOperator pUnionedBuffers = null; pUnionedBuffers = new PolygonClass() as ITopologicalOperator; pUnionedBuffers.ConstructUnion((IEnumGeometry)outBufferedGeometryCol); ISpatialFilter pSpatFilt = new SpatialFilter(); pSpatFilt.WhereClause = WhereClause; pSpatFilt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; pSpatFilt.SearchOrder = esriSearchOrder.esriSearchOrderSpatial; pSpatFilt.Geometry = (IGeometry)pUnionedBuffers; IFeatureCursor pFeatCursLines = null; try { pFeatCursLines = FeatureClass.Search(pSpatFilt, false); } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } IVector3D vecFoundGeom = new Vector3DClass(); IFeature pFeat = pFeatCursLines.NextFeature(); bool bHasTangentStraightLineAtJunction = false; List<int> lstLargeBreak = new List<int>(); while (pFeat != null) { IGeometry pFoundLineGeom = pFeat.ShapeCopy; IPolycurve pFoundLineAsPolyCurve = pFoundLineGeom as IPolycurve; int iRelativeOrientation = GetRelativeOrientation(pFoundLineAsPolyCurve, inPolycurve); //iRelativeOrientation == 1 --> closest points are original TO and found TO //iRelativeOrientation == 2 --> closest points are original TO and found FROM //iRelativeOrientation == 3 --> closest points are original FROM and found TO //iRelativeOrientation == 4 --> closest points are original FROM and found FROM //if the feature has no radius attribute, skip. double dRadius = 0; int iCtrPoint = -1; val = pFeat.get_Value(idxRadius); if (val == DBNull.Value) dRadius = 0; else dRadius = (double)val; val = pFeat.get_Value(idxCenterPointID); IPolycurve pPolyCurve = pFoundLineGeom as IPolycurve; ILine pFoundChordCandidate = new LineClass(); pFoundChordCandidate.PutCoords(pPolyCurve.FromPoint, pPolyCurve.ToPoint); //first check for liklihood that subject line is supposed to stay straight, by //geometry chord bearing angle break test vecFoundGeom.PolarSet(pFoundChordCandidate.Angle, 0, 1); double dDotProd = vecFoundGeom.DotProduct(vecOriginalSelected); double dAngleCheck = Math.Acos(dDotProd) * 180 / Math.PI; //in degrees dAngleCheck = Math.Abs(dAngleCheck); double dLargeAngleBreakInDegrees = 3; if (dAngleCheck > dLargeAngleBreakInDegrees && dAngleCheck < (180 - dLargeAngleBreakInDegrees)) //large angle break non-tangent, greater than 3 degrees { if (!lstLargeBreak.Contains(iRelativeOrientation)) lstLargeBreak.Add(iRelativeOrientation); } if ((dAngleCheck <= StraightLinesBreakLessThanInDegrees || (180 - dAngleCheck) < StraightLinesBreakLessThanInDegrees) && val == DBNull.Value && dRadius == 0 && !(pPolyCurve.Length< ExcludeTangentsShorterThan)) { if (lstLargeBreak.Contains(iRelativeOrientation)) bHasTangentStraightLineAtJunction = true; } if (val == DBNull.Value || dRadius == 0 || pPolyCurve.Length< ExcludeTangentsShorterThan) {//if the feature has a null centrpointID then skip. Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } if (Math.Abs(inPolycurve.Length / dRadius * 180 / Math.PI) > MaximumDeltaInDegrees) { //if the resulting curve would have a central angle more than MaximumDeltaInDegrees degrees then skip Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } iCtrPoint = (int)val; //if geometry of curve neighbour curves have been cracked then there can be more than one segment //however since all segments would be circular arcs, just need to test the first segment ISegmentCollection pFoundLineGeomSegs = pFoundLineGeom as ISegmentCollection; ISegment pSeg = pFoundLineGeomSegs.get_Segment(0); if (!(pSeg is ICircularArc)) { Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); continue; } dRadius = (double)pFeat.get_Value(idxRadius); IVector3D vect1 = new Vector3DClass(); IVector3D vect2 = new Vector3DClass(); ILine tang = new Line(); double dUnitSignChange = 1; if (iRelativeOrientation == 1) //closest points are original TO and found TO { dUnitSignChange = -1; vect1.PolarSet(pTangentLineAtEnd.Angle, 0, 1); pFoundLineAsPolyCurve.QueryTangent(esriSegmentExtension.esriExtendAtTo, 1.0, true, 1, tang); vect2.PolarSet(tang.Angle, 0, 1); } else if (iRelativeOrientation == 2)//closest points are original TO and found FROM { vect1.PolarSet(pTangentLineAtEnd.Angle, 0, 1); pFoundLineAsPolyCurve.QueryTangent(esriSegmentExtension.esriExtendAtFrom, 0.0, true, 1, tang); vect2.PolarSet(tang.Angle, 0, 1); } else if (iRelativeOrientation == 3)//closest points are original FROM and found TO { vect1.PolarSet(pTangentLineAtStart.Angle, 0, 1); pFoundLineAsPolyCurve.QueryTangent(esriSegmentExtension.esriExtendAtTo, 1.0, true, 1, tang); vect2.PolarSet(tang.Angle, 0, 1); } else if (iRelativeOrientation == 4)//closest points are original FROM and found FROM { dUnitSignChange = -1; vect1.PolarSet(pTangentLineAtStart.Angle, 0, 1); pFoundLineAsPolyCurve.QueryTangent(esriSegmentExtension.esriExtendAtFrom, 0.0, true, 1, tang); vect2.PolarSet(tang.Angle, 0, 1); } dDotProd = vect1.DotProduct(vect2); dAngleCheck = Math.Acos(dDotProd) * 180 / Math.PI; //in degrees dAngleCheck = Math.Abs(dAngleCheck); if (dAngleCheck < AngleToleranceTangentCompareInDegrees || (180 - dAngleCheck) < AngleToleranceTangentCompareInDegrees) { double dDerivedRadius = dRadius * dUnitSignChange; string sHarvestedCurveInfo = pFeat.OID.ToString() + "," + dDerivedRadius.ToString("#.000") + "," + iCtrPoint.ToString() + "," + "t"; CurveInfoFromNeighbours.Add(sHarvestedCurveInfo); outFoundTangentCurvesCount++; } Marshal.ReleaseComObject(pFeat); pFeat = pFeatCursLines.NextFeature(); } Marshal.FinalReleaseComObject(pFeatCursLines); if (bHasTangentStraightLineAtJunction) return false; //open to logic change to be less conservative bool bHasParallelCurveFeaturesNearby = (outFoundTangentCurvesCount > 0); return bHasParallelCurveFeaturesNearby; }
protected override void OnClick() { ICadastralEditor pCadEd = (ICadastralEditor)ArcMap.Application.FindExtensionByName("esriCadastralUI.CadastralEditorExtension"); IParcelEditManager pParcEditorMan = (IParcelEditManager)pCadEd; ICadastralPacketManager pCadPacketMan = (ICadastralPacketManager)pCadEd; //bool bStartedWithPacketOpen = pCadPacketMan.PacketOpen; if (pParcEditorMan == null) return; IEditor pEd = (IEditor)ArcMap.Application.FindExtensionByName("esri object editor"); if (pEd.EditState == esriEditState.esriStateNotEditing) { MessageBox.Show("Please start editing and try again."); return; } IParcelConstruction pConstr = pParcEditorMan.ParcelConstruction; IParcelConstruction4 pConstr4 = pConstr as IParcelConstruction4; ICadastralPoints pCadastralPts = pConstr4 as ICadastralPoints; ICadastralEditorSettings2 pCadastralEditorSettings2 = pCadEd as ICadastralEditorSettings2; ICadastralFixedPoints pFixedPoints = pCadastralPts as ICadastralFixedPoints; IPointCalculation pPointCalc = new PointCalculationClass(); if (pConstr == null) return; IGSLine pParcelLine = null; IMetricUnitConverter pMetricUnitConv = (IMetricUnitConverter)pCadEd; IGSPoint pStartPoint = null; List<int> lstPointIds = new List<int>(); List<IVector3D> Traverse = new List<IVector3D>(); //get rotation here IParcelConstructionData pConstrData = pConstr4.ConstructionData; IConstructionParentParcels pConstructionParentParcels = pConstrData as IConstructionParentParcels; ICadastralUndoRedo pCadUndoRedo = pConstr as ICadastralUndoRedo; try { int iParcelID = -1; if (pConstructionParentParcels.ParentParcelCount>0) pConstructionParentParcels.GetParentParcel(0, ref iParcelID); ICadastralParcel pCadaParcel = pCadPacketMan.JobPacket as ICadastralParcel; IGSParcel pGSParcel = null; if (pCadaParcel != null) pGSParcel = pCadaParcel.GetParcel(iParcelID); //if in measurement view then rotation is 0 double TheRotation = 0; if (pGSParcel == null) pGSParcel = pConstr.Parcel; if (!pCadastralEditorSettings2.MeasurementView) TheRotation = pGSParcel.Rotation;//radians if (TheRotation == 123456789) TheRotation = 0; pPointCalc.Rotation = TheRotation; IGSPoint pClosingPoint = null; #region simple method as fall-back bool bUseSimpleStackSelection = false; if (bUseSimpleStackSelection) { //bool bLineSelectionSequence = false; //IGSLine pLastSelectedGSLineInGrid = null; //for (int i = 0; i < pConstr.LineCount; i++) //{ // if (pConstr.GetLineSelection(i)) // { // if (pConstr.GetLine(i, ref pParcelLine)) // { // if (!bLineSelectionSequence) //first line // { // pStartPoint = pCadastralPts.GetPoint(pParcelLine.FromPoint); // pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint); // } // pPointCalc.AddLine(pParcelLine); // pLastSelectedGSLineInGrid = pParcelLine; // pToPoint = pCadastralPts.GetPoint(pParcelLine.ToPoint); // lstPointIds.Add(pToPoint.Id); // } // bLineSelectionSequence = true; // double dBear = pParcelLine.Bearing; //Azimuth of IVector3D is north azimuth radians zero degrees north // double dDist = pParcelLine.Distance; // IVector3D vec = new Vector3DClass(); // vec.PolarSet(dBear, 0, dDist); ////Azimuth of IVector3D is north azimuth radians zero degrees north // Traverse.Add(vec); // } // else // { // if (bLineSelectionSequence && pConstr.GetLine(i, ref pParcelLine) && HasLineSelectionAfter(pConstr, i)) // //if there was a prior selection and this line is a complete line, and there is no later selection // { // MessageBox.Show("Please select a continuous set of lines for closure."); // return; // } // } //} //pClosingPoint = pCadastralPts.GetPoint(pLastSelectedGSLineInGrid.ToPoint); } else #endregion {//build a forward star for the selected lines IEnumCELines pCELines = new EnumCELinesClass(); IEnumGSLines pEnumGSLines = (IEnumGSLines)pCELines; ILongArray pLongArray = new LongArrayClass(); int iFirstToNode = -1; for (int i = 0; i < pConstr.LineCount; i++) { if (pConstr.GetLineSelection(i)) { if (pConstr.GetLine(i, ref pParcelLine)) { if (iFirstToNode < 0) iFirstToNode = pParcelLine.ToPoint; pLongArray.Add(i); pCELines.Add(pParcelLine); } } } if (pCELines.Count==0) { MessageBox.Show("No lines selected. Please select a continuous set of lines for closure." + Environment.NewLine + "Line selection should not have branches.", "Traverse"); return; } IParcelLineFunctions3 ParcelLineFx = new ParcelFunctionsClass(); IGSForwardStar pFwdStar = ParcelLineFx.CreateForwardStar(pEnumGSLines); //forward star object is now created for all the selected lines, //need to first re-sequence the lines, and test for branching and discontinuity int iBranches = 0; int iTracedLines = 0; int iLoops = 0; int iTerminals = 0; List<int> LineIDList = new List<int>(); List<int> FromList = new List<int>(); List<int> ToList = new List<int>(); List<string> FromToLine = new List<string>(); bool bTraceSucceeded = TraceLines(ref pFwdStar, iFirstToNode, ref iBranches, ref iTracedLines, ref iLoops, ref iTerminals, ref FromToLine, ref FromList, ref ToList, 0); if (iBranches > 0) { MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine + "Line selection should not have branches.", "Traverse"); return; } if (iTracedLines < pLongArray.Count) { MessageBox.Show("Please select a continuous set of lines for closure." + Environment.NewLine + "Selected Lines should be connected in a single sequence without branches.", "Traverse"); return; } //if it's a single loop check to see if the sequence needs to be reversed //CW or CCW based on bearings if (iLoops == 1) { bool bIsReversed = false; foreach (int i in FromList) { if (i < 0) bIsReversed = true; else { bIsReversed = false; break; } } if (bIsReversed) {//all courses are running reversed, so reverse the whole sequence FromToLine.Clear(); FromList.Reverse(); ToList.Reverse(); int iNewFrom = -ToList[ToList.Count-1]; int iNewTo = -FromList[ToList.Count-1]; string sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString(); FromToLine.Add(sNewFromTo); for (int i =1; i < ToList.Count ;i++) { iNewFrom = -ToList[i-1]; iNewTo = -FromList[i-1]; sNewFromTo = iNewFrom.ToString() + "," + iNewTo.ToString(); FromToLine.Add(sNewFromTo); } } } LineIDList.Clear(); FromList.Clear(); ToList.Clear(); pLongArray.RemoveAll(); pCadUndoRedo.StartUndoRedoSession("Adjust Traverse"); if (iLoops == 0) { //re-sequence using TraceLines function based on either end point, because the order of //selected construction lines in grid don't control start or end point FromToLine.Clear(); int iTerminus = -1; iTracedLines = 0; iBranches = 0; iLoops = 0; iTerminals = 0; FindTerminusForSequence(ref pFwdStar, iFirstToNode, ref iTerminus, 0); if (iTerminus == -1) { pCadUndoRedo.WriteUndoRedoSession(false); return; } TraceLines(ref pFwdStar, iTerminus, ref iBranches, ref iTracedLines, ref iLoops, ref iTerminals, ref FromToLine, ref FromList, ref ToList, 0); } List<IVector3D> SequencedTraverse = new List<IVector3D>(); IGSLine pGSLineInPath = null; foreach (string s in FromToLine) { string[] sFromTo = s.Split(','); int iFrom = Convert.ToInt32(sFromTo[0]); int iTo = Convert.ToInt32(sFromTo[1]); bool bReversed = pFwdStar.GetLine(iFrom, iTo, ref pGSLineInPath); if (bReversed) { IGSLine pGSLine180 = new GSLineClass(); pGSLine180.FromPoint = pGSLineInPath.ToPoint; pGSLine180.ToPoint = pGSLineInPath.FromPoint; pGSLine180.Bearing = pGSLineInPath.Bearing + Math.PI; pGSLine180.Distance = pGSLineInPath.Distance; IVector3D vec180 = new Vector3DClass(); vec180.PolarSet(pGSLine180.Bearing, 0, pGSLine180.Distance); //Azimuth of IVector3D is north azimuth radians zero degrees north Traverse.Add(vec180); lstPointIds.Add(pGSLine180.ToPoint); pPointCalc.AddLine(pGSLine180); } else { double dBear = pGSLineInPath.Bearing; double dDist = pGSLineInPath.Distance; IVector3D vec = new Vector3DClass(); vec.PolarSet(dBear, 0, dDist); //Azimuth of IVector3D is north azimuth radians zero degrees north Traverse.Add(vec); lstPointIds.Add(pGSLineInPath.ToPoint); pPointCalc.AddLine(pGSLineInPath); } if (pStartPoint == null) { if (bReversed) pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint); else pStartPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint); } if (bReversed) pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.FromPoint); else pClosingPoint = pCadastralPts.GetPoint(pGSLineInPath.ToPoint); } } if (pStartPoint == null) { pCadUndoRedo.WriteUndoRedoSession(false); return; } IPoint pStart = new PointClass(); pStart.X = pStartPoint.X; pStart.Y = pStartPoint.Y; string sAdjustMethod = "Compass"; esriParcelAdjustmentType eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass; if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentNone || pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCompass) eAdjMethod = esriParcelAdjustmentType.esriParcelAdjustmentCompass; else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentCrandall) { sAdjustMethod = "Crandall"; eAdjMethod = pCadastralEditorSettings2.ParcelAdjustment; } else if (pCadastralEditorSettings2.ParcelAdjustment == esriParcelAdjustmentType.esriParcelAdjustmentTransit) { sAdjustMethod = "Transit"; eAdjMethod = pCadastralEditorSettings2.ParcelAdjustment; } pPointCalc.CalculatePoints(eAdjMethod, pStartPoint.Id, pStartPoint, pClosingPoint.Id, pClosingPoint, true); ITraverseClosure pClose = pPointCalc.Closure; List<string> lstCoursesFromTo = new List<string>(); List<IVector3D> AdjustedTraverse = new List<IVector3D>(); double dAdjustedPointX = 0; double dAdjustedPointY = 0; double dPreviousPointX = 0; double dPreviousPointY = 0; for (int i = 0; i < pClose.CourseCount; i++) { IGSPoint pPt = pCadastralPts.GetPoint(lstPointIds[i]); dAdjustedPointY = pPointCalc.GetCalculatedPoint(lstPointIds[i], ref dAdjustedPointX); string sFromTo = ""; IVector3D pAdjustedLine = new Vector3DClass(); if (i == 0) { sFromTo = pStartPoint.Id.ToString() + "-" + lstPointIds[i].ToString(); pAdjustedLine.SetComponents(dAdjustedPointX - pStartPoint.X, dAdjustedPointY - pStartPoint.Y, 0); } else { sFromTo = lstPointIds[i - 1].ToString() + "-" + lstPointIds[i].ToString(); pAdjustedLine.SetComponents(dAdjustedPointX - dPreviousPointX, dAdjustedPointY - dPreviousPointY, 0); } lstCoursesFromTo.Add(sFromTo); IVector3D Z_Axis = new Vector3DClass(); Z_Axis.SetComponents(0, 0, 100); pAdjustedLine.Rotate(TheRotation, Z_Axis); AdjustedTraverse.Add(pAdjustedLine); dPreviousPointX = dAdjustedPointX; dPreviousPointY = dAdjustedPointY; pPt.X = dAdjustedPointX; pPt.Y = dAdjustedPointY; if (!pCadastralEditorSettings2.MeasurementView) pFixedPoints.SetFixedPoint(lstPointIds[i], true); } double dMisclosureDistance = pClose.MisclosureDistance; double dMisclosureBearing = pClose.MisclosureDirection; IVector MiscloseVector = new Vector3DClass(); IEditProperties2 pEdProps = pEd as IEditProperties2; IAngularConverter pAngConv = new AngularConverterClass(); pAngConv.SetAngle(dMisclosureBearing, esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); //int iPrec = 7; //if (pConstr.Parcel.Plan.AngleUnits == esriDirectionUnits.esriDUDegreesMinutesSeconds) // iPrec = 0; string sMiscloseBearing = pAngConv.GetString(pEdProps.DirectionType, pEdProps.DirectionUnits, pEdProps.AngularUnitPrecision); Utilities UTIL = new Utilities(); string sRatio = "High Accuracy"; if (pClose.RelativeErrorRatio < 10000) sRatio = "1:" + pClose.RelativeErrorRatio.ToString("0"); if (dMisclosureDistance >= 0.001) sMiscloseBearing = UTIL.FormatDirectionDashesToDegMinSecSymbols(sMiscloseBearing); else sMiscloseBearing = "----"; ICadastralUnitConversion pCadUnitConverter = new CadastralUnitConversionClass(); double dMetersPerUnit = pCadUnitConverter.ConvertDouble(1, pConstr.Parcel.Plan.DistanceUnits, esriCadastralDistanceUnits.esriCDUMeter); string sReport = "Closure:" + Environment.NewLine + " error: " + sRatio + Environment.NewLine + " distance: " + (dMisclosureDistance / dMetersPerUnit).ToString("0.000") + Environment.NewLine + " bearing: " + sMiscloseBearing + Environment.NewLine + " xdist: " + (pClose.MisclosureX / dMetersPerUnit).ToString("0.000") + Environment.NewLine + " ydist: " + (pClose.MisclosureY / dMetersPerUnit).ToString("0.000") + Environment.NewLine + " courses: " + (pClose.CourseCount) + Environment.NewLine + Environment.NewLine + "Adjustment:" + Environment.NewLine + " method: " + sAdjustMethod; dlgTraverseResults dlgTraverseResults = new dlgTraverseResults(); AddTraverseInfoToGrid(pConstr.Parcel.Plan, dlgTraverseResults.dataGridView1, Traverse, AdjustedTraverse, lstCoursesFromTo); dlgTraverseResults.txtMiscloseReport.Text = sReport; DialogResult dRes = dlgTraverseResults.ShowDialog(); if (dRes == DialogResult.Cancel) { //since we cancelled, set the points back foreach (int i in lstPointIds) pFixedPoints.SetFixedPoint(i, false); pCadUndoRedo.WriteUndoRedoSession(false); } else pCadUndoRedo.WriteUndoRedoSession(true); } catch (Exception ex) { MessageBox.Show(ex.Message + Environment.NewLine + "Line number:" + ex.LineNumber().ToString() + " in " + ex.TargetSite.Name, "Traverse"); pCadUndoRedo.WriteUndoRedoSession(false); } }
/// <summary> /// 求导线(pRefPoint到pEndPoint)上的掘进点 /// </summary> /// <params name="pRefPoint">参考导线点</params> /// <params name="pEndPoint">导线的终点</params> /// <params name="dDistance">距离参考导线点的距离</params> /// <returns>距参考导线点一定距离的点</returns> public static IPoint GetJJPoint(IPoint pRefPoint, IPoint pEndPoint, double dDistance) { if (pRefPoint.Z.Equals(Double.NaN)) { pRefPoint.Z = 0; } if (pEndPoint.Z.Equals(Double.NaN)) { pEndPoint.Z = 0; } IVector3D vector3D = new Vector3DClass(); vector3D.ConstructDifference(pEndPoint, pRefPoint); //从参考点到导线终点的向量 vector3D.Normalize(); //向量单位化 IPoint pJjPoint = new PointClass(); pJjPoint.X = pRefPoint.X + dDistance * vector3D.XComponent; pJjPoint.Y = pRefPoint.Y + dDistance * vector3D.YComponent; pJjPoint.Z = pRefPoint.Z + dDistance * vector3D.ZComponent; return pJjPoint; }
protected override void OnClick() { IEditor pEd = (IEditor)ArcMap.Editor; IEditor2 pEd2 = (IEditor2)ArcMap.Editor; IEditProperties pEdProps1 = pEd as IEditProperties; IEditProperties2 pEdProps2 = pEd as IEditProperties2; IEditSketch2 pSketch2 = ArcMap.Editor as IEditSketch2; ISegmentCollection pSegColl = pSketch2.Geometry as ISegmentCollection; double dLineDirection = 0; ISketchTool sketchTool = ArcMap.Application.CurrentTool.Command as ISketchTool; if (sketchTool.Constraint == esriSketchConstraint.esriConstraintAngle) { dLineDirection = sketchTool.AngleConstraint; } else { ILine pRubberBandLine = new LineClass(); pRubberBandLine.PutCoords(pSketch2.LastPoint, pEd2.Location); dLineDirection = pRubberBandLine.Angle; } IAngularConverter pAngConv = new AngularConverterClass(); pAngConv.SetAngle(dLineDirection, esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); int iSegCnt = pSegColl.SegmentCount; dlgSpiralParameters SpiralEntryDialog = new dlgSpiralParameters(); string sBearing = pAngConv.GetString(pEdProps2.DirectionType, pEdProps2.DirectionUnits, pEdProps2.AngularUnitPrecision); SpiralEntryDialog.txtDirection.Text = sBearing; //Display the dialog DialogResult pDialogResult = SpiralEntryDialog.ShowDialog(); esriCurveDensifyMethod DensifyMethod = esriCurveDensifyMethod.esriCurveDensifyByAngle; //default double dDensifyParameter = 2 * Math.PI / 180; //2 degrees //default if (SpiralEntryDialog.optCustomDensification.Checked) { DensifyMethod = (esriCurveDensifyMethod)SpiralEntryDialog.cboDensificationType.SelectedIndex; if (DensifyMethod == esriCurveDensifyMethod.esriCurveDensifyByAngle) { dDensifyParameter = Convert.ToDouble(SpiralEntryDialog.numAngleDensification.Value) * Math.PI / 180; } else { if (!Double.TryParse(SpiralEntryDialog.txtDensifyValue.Text, out dDensifyParameter)) { dDensifyParameter = 2; } } } if (pDialogResult != DialogResult.OK) { return; } if (SpiralEntryDialog.txtStartRadius.Text.ToLower().Trim() == "infinity" && SpiralEntryDialog.txtEndRadius.Text.ToLower().Trim() == "infinity") { return; } double dSpiralRadius1 = Double.MaxValue; //default to infinity double dFromCurvature = 0; if (SpiralEntryDialog.txtStartRadius.Text.ToLower() != "infinity") { if (Double.TryParse(SpiralEntryDialog.txtStartRadius.Text, out dSpiralRadius1)) { dFromCurvature = 1 / dSpiralRadius1; } else { return; } } double dSpiralRadius2 = Double.MaxValue; //default to infinity double dToCurvature = 0; if (SpiralEntryDialog.txtEndRadius.Text.ToLower() != "infinity") { if (Double.TryParse(SpiralEntryDialog.txtEndRadius.Text, out dSpiralRadius2)) { dToCurvature = 1 / dSpiralRadius2; } else { return; } } bool bIsCCW = (dSpiralRadius1 > dSpiralRadius2) ? SpiralEntryDialog.optRight.Checked : SpiralEntryDialog.optLeft.Checked; bool bSpecialCaseCircularArc = (dSpiralRadius1 == dSpiralRadius2); if (!pAngConv.SetString(SpiralEntryDialog.txtDirection.Text, pEdProps2.DirectionType, pEdProps2.DirectionUnits)) { return; } double dNorthAzimuthRadians = pAngConv.GetAngle(esriDirectionType.esriDTNorthAzimuth, esriDirectionUnits.esriDURadians); IVector3D pVec = new Vector3DClass(); pVec.PolarSet(dNorthAzimuthRadians, 0, 500); IPoint pTangentPoint = new PointClass(); pTangentPoint.PutCoords(pSketch2.LastPoint.X + pVec.XComponent, pSketch2.LastPoint.Y + pVec.YComponent); //double dStreamingTol = pEdProps1.StreamTolerance; //if (dStreamingTol == 0) // dStreamingTol = 0.001 * 5000; //metric //double dSpiralOffsetGeometryPrecision = 0.001 * 250; //metric 0.25 m IPolyline6 theSpiralPolyLine = null; double dExitTangent = 0; if (SpiralEntryDialog.cboPathLengthParameter.SelectedIndex == 0) { double dSpiralArcLength; if (!Double.TryParse(SpiralEntryDialog.txtPathLengthParameter.Text, out dSpiralArcLength)) { return; } if (bSpecialCaseCircularArc) { ILine pInTangentLine = new LineClass(); pInTangentLine.PutCoords(pSketch2.LastPoint, pTangentPoint); ISegment pTangentSegment = (ISegment)pInTangentLine; IConstructCircularArc2 pCircArcConstr = new ESRI.ArcGIS.Geometry.CircularArcClass() as IConstructCircularArc2; pCircArcConstr.ConstructTangentRadiusArc(pTangentSegment, false, bIsCCW, dSpiralRadius1, dSpiralArcLength); ICircularArc pArcSegment = pCircArcConstr as ICircularArc; //Get chord Line from tangent curve constructor ILine pChordLine = new LineClass(); pChordLine.PutCoords(pArcSegment.FromPoint, pArcSegment.ToPoint); double dPolarRadians = pChordLine.Angle; //to get the chord azimuth pCircArcConstr.ConstructBearingRadiusArc(pSketch2.LastPoint, dPolarRadians, bIsCCW, dSpiralRadius1, dSpiralArcLength); dExitTangent = pArcSegment.ToAngle + Math.PI / 2; ISegmentCollection segCollection = new PolylineClass() as ISegmentCollection; object obj = Type.Missing; segCollection.AddSegment((ISegment)pArcSegment, ref obj, ref obj); theSpiralPolyLine = segCollection as IPolyline6; } else { theSpiralPolyLine = ConstructSpiralbyLength(pSketch2.LastPoint, pTangentPoint, dFromCurvature, dToCurvature, bIsCCW, dSpiralArcLength, DensifyMethod, dDensifyParameter, out dExitTangent); } } if (SpiralEntryDialog.cboPathLengthParameter.SelectedIndex == 1) { if (!pAngConv.SetString(SpiralEntryDialog.txtPathLengthParameter.Text, esriDirectionType.esriDTPolar, pEdProps2.DirectionUnits)) { return; } double dSpiralDeltaAngle = pAngConv.GetAngle(esriDirectionType.esriDTPolar, esriDirectionUnits.esriDURadians); if (bSpecialCaseCircularArc) { ILine pInTangentLine = new LineClass(); pInTangentLine.PutCoords(pSketch2.LastPoint, pTangentPoint); ISegment pTangentSegment = (ISegment)pInTangentLine; IConstructCircularArc2 pCircArcConstr = new ESRI.ArcGIS.Geometry.CircularArcClass() as IConstructCircularArc2; pCircArcConstr.ConstructTangentRadiusAngle(pTangentSegment, false, bIsCCW, dSpiralRadius1, dSpiralDeltaAngle); ICircularArc pArcSegment = pCircArcConstr as ICircularArc; //Get chord Line from tangent curve constructor ILine pChordLine = new LineClass(); pChordLine.PutCoords(pArcSegment.FromPoint, pArcSegment.ToPoint); double dPolarRadians = pChordLine.Angle; //to get the chord azimuth pCircArcConstr.ConstructBearingRadiusAngle(pSketch2.LastPoint, dPolarRadians, bIsCCW, dSpiralRadius1, dSpiralDeltaAngle); dExitTangent = pArcSegment.ToAngle + Math.PI / 2; ISegmentCollection segCollection = new PolylineClass() as ISegmentCollection; object obj = Type.Missing; segCollection.AddSegment((ISegment)pArcSegment, ref obj, ref obj); theSpiralPolyLine = segCollection as IPolyline6; } else { theSpiralPolyLine = ConstructSpiralbyDeltaAngle(pSketch2.LastPoint, pTangentPoint, dFromCurvature, dToCurvature, bIsCCW, dSpiralDeltaAngle, DensifyMethod, dDensifyParameter, out dExitTangent); } } if (theSpiralPolyLine == null) { MessageBox.Show("A spiral could not be created with the entered parameters."); return; } ISegmentCollection pSpiralSegCollection = theSpiralPolyLine as ISegmentCollection; //Start a sketch operation and insert the new envelope into the sketch ISketchOperation2 sketchOp = new SketchOperationClass(); sketchOp.Start(ArcMap.Editor); sketchOp.MenuString = "Add Spiral"; pSegColl.AddSegmentCollection(pSpiralSegCollection); IGeometry geom = pSegColl as IGeometry; pSketch2.Geometry = geom; //set the angle constraint to the exit tangent of the spiral sketchTool.Constraint = esriSketchConstraint.esriConstraintAngle; sketchTool.AngleConstraint = dExitTangent; sketchOp.Finish(ArcMap.Document.ActiveView.Extent, esriSketchOperationType.esriSketchOperationGeneral, null); }
public void CreateFeature() { //移动放缩矢量箭头 IVector3D VerticalVector = Material.ConstructVector3D(0, 0, 1); IPoint originPoint = Material.ConstructPoint3D(0, 0, 0); Material.MakeZAware(originPoint as IGeometry); //创建所有要素 for (int i = 0; i < VectorModel.TinCount; i++) { IFeature BarycentreFeature = BarycentreFeatureClass.CreateFeature(); BarycentreFeature.Shape = BARYCENTRE[i]; int index1 = BarycentreFeature.Fields.FindField("X"); BarycentreFeature.set_Value(index1, BARYCENTRE[i].X); int index2 = BarycentreFeature.Fields.FindField("Y"); BarycentreFeature.set_Value(index2, BARYCENTRE[i].Y); int index3 = BarycentreFeature.Fields.FindField("Z"); BarycentreFeature.set_Value(index3, BARYCENTRE[i].Z); int index4 = BarycentreFeature.Fields.FindField("Probability"); BarycentreFeature.set_Value(index4, 0.95 - (0.9 / 49) * i); BarycentreFeature.Store(); if (i == 0) { Ctxt.WriteLine("GOCAD VSet" + "\r\n" + "HEADER" + "\r\n" + "{name: Borehole}" + "\r\n" + "GOCAD_ORIGINAL_COORDINATE_SYSTEM\nNAME" + "\r\n" + "PROJECTION Unknown" + "\r\n" + "DATUM Unknown" + "\r\n" + "AXIS_NAME X Y Z" + "\r\n" + "AXIS_UNIT m m m" + "\r\n" + "ZPOSITIVE Elevation" + "\r\n" + "END_ORIGINAL_COORDINATE_SYSTEM" + "\r\n" + "PROPERTIES P" + "\r\n" + "PROP_LEGAL_RANGES **none** **none**" + "\r\n" + "NO_DATA_VALUES -99999" + "\r\n" + "PROPERTY_CLASSES p" + "\r\n" + "PROPERTY_KINDS \"Real Number\"" + "\r\n" + "PROPERTY_SUBCLASSES QUANTITY Float" + "\r\n" + "ESIZES 1" + "\r\n" + "UNITS unitless" + "\r\n" + "PROPERTY_CLASS_HEADER X {" + "\r\n" + "kind: X" + "\r\n" + "unit: m" + "\r\n" + "pclip: 99}" + "\r\n" + "PROPERTY_CLASS_HEADER Y {" + "\r\n" + "kind: Y" + "\r\n" + "unit: m" + "\r\n" + "pclip: 99}" + "\r\n" + "PROPERTY_CLASS_HEADER Z {" + "\r\n" + "kind: Depth\nunit: m" + "\r\n" + "is_z: on" + "\r\n" + "pclip: 99}" + "\r\n" + "PROPERTY_CLASS_HEADER p {" + "\r\n" + "kind: Real Number" + "\r\n" + "unit: unitless" + "\r\n" + "pclip: 99}" + "\r\n" ); } Ctxt.Write("PVRTX " + i + " "); Ctxt.Write(BARYCENTRE[i].X + " "); Ctxt.Write(BARYCENTRE[i].Y + " "); Ctxt.Write(BARYCENTRE[i].Z + " "); if (i == VectorModel.TinCount - 1) { Ctxt.WriteLine("0.5" + " "); } else { Ctxt.WriteLine(0.95 - (0.9 / 49) * i + " "); } if (i == VectorModel.TinCount - 1) { Ctxt.Write("END"); Ctxt.Close(); } ////创建重力线 IFeature VectorFeature = GravityVectorFeatureClass.CreateFeature(); IPoint endPoint = new PointClass(); Material.MakeZAware(endPoint as IGeometry); //根据体积设置末端点 endPoint.X = BARYCENTRE[i].X; endPoint.Y = BARYCENTRE[i].Y; endPoint.Z = BARYCENTRE[i].Z - VOLUME[i] * gLength; // //添加两点构成向量 IPointCollection VectorPointCollection = new PolylineClass(); Material.MakeZAware(VectorPointCollection as IGeometry); VectorPointCollection.AddPoint(BARYCENTRE[i], ref _missing, ref _missing); VectorPointCollection.AddPoint(endPoint, ref _missing, ref _missing); VectorFeature.Shape = VectorPointCollection as IGeometry; int index5 = VectorFeature.Fields.FindField("Gravity"); VectorFeature.set_Value(index5, VOLUME[i]); int index6 = VectorFeature.Fields.FindField("Probability"); VectorFeature.set_Value(index6, 0.95 - (0.9 / 49) * i); VectorFeature.Store(); ////添加矢量箭头 //得到重力矢量 IVector3D Gvector = Material.CreateVector3DTwoPoints(endPoint, BARYCENTRE[i]); IGeometry Arrow = Material.GetArrow(); double Inclination = Gvector.Inclination; //计算与竖向矢量夹角 double degreesOfRotation = Math.Acos((Gvector.DotProduct(VerticalVector)) / ((Gvector.Magnitude) * (VerticalVector.Magnitude))); ITransform3D transform3D = Arrow as ITransform3D; //放缩 transform3D.Scale3D(originPoint, XScale, YScale, ZScale); //转动 if (degreesOfRotation != 0) { double angleOfRotationInRadians = degreesOfRotation; IVector3D axisOfRotationVector3D = new Vector3DClass(); axisOfRotationVector3D.XComponent = 1; axisOfRotationVector3D.YComponent = 0; axisOfRotationVector3D.ZComponent = 0; transform3D.RotateVector3D(axisOfRotationVector3D, angleOfRotationInRadians); } //平移 if (endPoint.IsEmpty) { continue; } transform3D.Move3D(endPoint.X - originPoint.X, endPoint.Y - originPoint.Y, endPoint.Z - originPoint.Z); IFeature ArrowFeature = ArrowFeatureClass.CreateFeature(); ArrowFeature.Shape = Arrow as IMultiPatch; int index7 = ArrowFeature.Fields.FindField("Probability"); ArrowFeature.set_Value(index7, 0.95 - (0.9 / 49) * i); ArrowFeature.Store(); //墙壁 IFeature EnCloseFeature = EncloseFeatureClass[i].CreateFeature(); EnCloseFeature.Shape = multiPatchGeometryCollection[i] as IMultiPatch; int index17 = EnCloseFeature.Fields.FindField("Probability"); EnCloseFeature.set_Value(index7, 0.95 - (0.9 / 49) * i); EnCloseFeature.Store(); Vtxt.WriteLine(VOLUME[i]); if (i == VectorModel.TinCount - 1) { Vtxt.Close(); } } }