private ArcFeature ImportArc(Ntx.Line line, Operation creator, ILength tol) { Debug.Assert(line.IsCurve); IEntity what = GetEntityType(line, SpatialType.Line); // Get positions defining the arc PointGeometry[] pts = GetPositions(line); // Ignore zero-length lines if (HasZeroLength(pts)) { return(null); } // Add a point at the center of the circle Ntx.Position pos = line.Center; PointGeometry pc = new PointGeometry(pos.Easting, pos.Northing); PointFeature center = EnsurePointExists(pc, tol, creator); // Calculate exact positions for the arc endpoints double radius = line.Radius; ICircleGeometry cg = new CircleGeometry(pc, radius); IPosition bc = CircleGeometry.GetClosestPosition(cg, pts[0]); IPosition ec = CircleGeometry.GetClosestPosition(cg, pts[pts.Length - 1]); // Round off to nearest micron PointGeometry bcg = PointGeometry.Create(bc); PointGeometry ecg = PointGeometry.Create(ec); // Ensure point features exist at both ends of the line. PointFeature ps = GetArcEndPoint(bcg, tol, creator); PointFeature pe = GetArcEndPoint(ecg, tol, creator); // Try to find a circle that's already been added by this import. Circle c = EnsureCircleExists(center, radius, tol, creator); // Determine which way the arc is directed bool iscw = LineStringGeometry.IsClockwise(pts, center); InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); ArcFeature arc = new ArcFeature(creator, id, what, c, ps, pe, iscw); // The toological status of the incoming arc may override the status that the // constructor derived from the entity type arc.SetTopology(line.IsTopologicalArc); #if DEBUG // Confirm the NTX data was valid (ensure it's consistent with what we've imported)... double readRad = c.Radius; double calcRad = BasicGeom.Distance(c.Center, ps); Debug.Assert(Math.Abs(readRad - calcRad) < tol.Meters); foreach (IPointGeometry pg in pts) { ILength check = arc.Geometry.Distance(pg); Debug.Assert(check.Meters < tol.Meters); } #endif return(arc); }
/// <summary> /// Creates the geometry that can be used to detect intersections with the map. /// </summary> /// <returns>The geometry for the new line (null if insufficient information has been specified)</returns> ArcGeometry CreateIntersectGeometry() { if (m_Circles == null) { return(null); } PointFeature start = StartPoint; if (start == null) { return(null); } IPointGeometry end = LastMousePosition; if (end == null) { return(null); } ITerminal endTerm = new FloatingTerminal(end); // Find the circle that is closest to the end (only looking at the valid circles // that are within a 1mm tolerance). Return null geometry if none of the circles // are within reach. Circle bestCircle = m_Circles[0]; double bestdist = bestCircle.Distance(end).Meters; if (m_Circles.Count > 1) { // See if there is any better choice for (int i = 1; i < m_Circles.Count; i++) { Circle c = m_Circles[i]; double dist = c.Distance(end).Meters; if (dist < bestdist) { bestCircle = c; bestdist = dist; } } } // Ignore if the best circle is too far away double tol = CircleTolerance.Meters; if (bestdist > tol) { return(null); } // Project the end point ON to the circle. //IPointGeometry center = bestCircle.Center; //Turn eturn = new Turn(center, end); //IAngle bearing = eturn.Bearing; //IPosition cirend = Geom.Polar(center, bearing.Radians, bestCircle.Radius.Meters); IPosition cirend = CircleGeometry.GetClosestPosition(bestCircle, end); // Get the clockwise angle from the start to the current end point. IPointGeometry center = bestCircle.Center; Turn sturn = new Turn(center, start); double angle = sturn.GetAngleInRadians(cirend); // Figure out which direction the curve should go, depending // on whether the user wants the short arc or the long one. bool iscw = (angle < MathConstants.PI ? m_IsShortArc : !m_IsShortArc); // Create the required geometry ITerminal ec = new FloatingTerminal(cirend); return(new ArcGeometry(bestCircle, start, ec, iscw)); }