private PointGeometry[] GetPositions(Ntx.Line line) { PointGeometry[] pts = new PointGeometry[line.NumPosition]; for (int i = 0; i < line.NumPosition; i++) { Ntx.Position xp = line.Position(i); pts[i] = new PointGeometry(xp.Easting, xp.Northing); } return(pts); }
private Feature ImportLine(ILength tol, Ntx.Line line, Operation creator) { // Circular arcs are handled elsewhere if (line.IsCurve) { return(null); } IEntity what = GetEntityType(line, SpatialType.Line); PointGeometry[] pts = GetPositions(line); // Ignore zero-length lines if (HasZeroLength(pts)) { return(null); } // Ensure point features exist at both ends of the line. PointFeature ps = EnsurePointExists(pts[0], tol, creator); PointFeature pe = EnsurePointExists(pts[pts.Length - 1], tol, creator); // Force end positions to match pts[0] = ps.PointGeometry; pts[pts.Length - 1] = pe.PointGeometry; // It's possible we've now produced a zero-length line if (Object.ReferenceEquals(ps, pe) && HasZeroLength(pts)) { return(null); } // If we're dealing with a multi-segment, I have occasionally seen tiny glitches // at the end of the incoming lines (whether this is a real data problem, or an // imperfection in the import software is unknown). So double check now. // In the longer term, the import software should also check for more complex // issues, like missing intersections. In the meantime, I assume that incoming // topological data is generally clean. if (pts.Length > 2 && line.IsTopologicalArc) { pts = CheckMultiSegmentEnds(pts); } LineFeature result; InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); if (pts.Length == 2) { result = new LineFeature(creator, id, what, ps, pe); } else { result = new LineFeature(creator, id, what, ps, pe, pts); } // The toological status of the incoming arc may override the status that the // constructor derived from the entity type result.SetTopology(line.IsTopologicalArc); return(result); }
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); }