private Feature ImportName(Ntx.Name name, Operation creator) { /* // Get pointer to the applicable map theme CeTheme theme(Name.GetTheme()); CeTheme* pTheme = theme.AddTheme(); // Get pointer to the entity type. GRAPHICSTYPE geom = ANNOTATION; if ( Name.IsLabel() ) geom = POLYGON; CeEntity* pEntity = AddEntity(Name.GetpFeatureCode(),pTheme,geom); */ IEntity entity = GetEntityType(name, SpatialType.Text); // Get the text string string text = name.Text; // Get the position of the centre of the 1st character Ntx.Position pos = name.Position(0); IPosition vcentre = new Position(pos.Easting, pos.Northing); // Get text metrics float height = name.Height; float spacing = name.Spacing; float rotation = name.Rotation; // Calculate the top left corner of the first character using // the text metrics we just got ... // Get the width of the first character. For names that contain // only one character, the spacing we have will be zero, so in // that case, deduce the width of the character via the covering // rectangle. float charwidth = spacing; if (charwidth < Constants.TINY) { // Get the covering rectangle. Ntx.Position nw = name.NorthWest; Ntx.Position se = name.SouthEast; // And get the dimensions. double dx = se.Easting - nw.Easting; double dy = nw.Northing - se.Northing; // If the cover is screwed up, assume the width is 80% of the text height. if (dy < Constants.TINY) charwidth = (float)(height * 0.8); else charwidth = (float)(height * (dx/dy)); } // Define the bearing from bottom to top of the text. double vbear = (double)rotation; // Get position directly above the centre of the 1st char. IPosition above = Geom.Polar(vcentre, vbear, 0.5 * (double)height); // Define the bearing from the point we just got to the // start of the text string. double hbear = vbear - Constants.PIDIV2; // Back up half a character to get the initial corner. PointGeometry topleft = new PointGeometry(Geom.Polar(above, hbear, 0.5 * (double)charwidth)); IFont font = null; double width = (double)text.Length * charwidth; TextFeature result = null; if (name.IsLabel) { // Create key text string keystr = name.Text; KeyTextGeometry kt = new KeyTextGeometry(topleft, font, height, width, rotation); InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); result = new TextFeature(creator, id, entity, kt); kt.Label = result; result.SetTopology(true); // Define the label's foreign ID and form a two-way association ForeignId fid = GetFeatureId(keystr); Debug.Assert(fid != null); fid.Add(result); // Remember the reference position of the label. Ntx.Position xp = name.RefPosition; IPointGeometry pp = new PointGeometry(xp.Easting, xp.Northing); result.SetPolPosition(pp); } else { // Create a miscellaneous text label. MiscTextGeometry mt = new MiscTextGeometry(text, topleft, font, height, width, rotation); InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); result = new TextFeature(creator, id, entity, mt); result.SetTopology(false); } return result; }
private Feature ImportSymbol(Ntx.Symbol symbol, Operation creator) { IEntity what = GetEntityType(symbol, SpatialType.Point); // Get the position Ntx.Position pos = symbol.Position; PointGeometry g = new PointGeometry(pos.Easting, pos.Northing); // Ignore positions at 0,0! if (g.Easting.Microns==0 && g.Northing.Microns==0) return null; InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); PointFeature p = new PointFeature(creator, id, what, g); /* static LOGICAL warned=FALSE; // debug // Get pointer to the map theme CeTheme theme(Symbol.GetTheme()); const CeTheme* const pTheme = theme.AddTheme(); // Get pointer to the entity CeEntity* pEntity = AddEntity(Symbol.GetpFeatureCode(),pTheme,VERTEX); // Get the position const CxPosition& pos = Symbol.GetPosition(); // For the time being ... if ( !warned && pos.Is3D() ) { AfxMessageBox("Elevation data is being stripped."); warned = TRUE; } // Add the position of the symbol. CeVertex vtx(pos.GetEasting(),pos.GetNorthing()) ; const CeLocation* pLoc = pMap->AddLocation(vtx); // If the location does not already have an associated point // feature, add one now (the location may have been previously // added via the import of a line). // Note that this version of AddPoint will always add a duplicate // point at the specified location. CePoint* pPoint = pMap->AddPoint((CeLocation* const)pLoc,pEntity); */ // Define foreign ID (if any) ... string keystr = symbol.Key; ForeignId fid = GetFeatureId(keystr); if (fid != null) fid.Add(p); return p; }
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; }
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; }
ILength GetPointMatchTolerance(Ntx.File file) { // Define line end point tolerance that matches the resolution of the input NTX file. // ...in the sample NTX file I've got, the resolution is supposedly 0.0001m, but // things like circle center points are frequently different by 0.0002 or so. // So be a bit more permissive as far as search tolerance is concerned. double res = file.Header.XYResolution; //ILength tol = new MicronValue(res); ILength tol = new MicronValue(res*10); return tol; }
private IEntity GetEntityType(Ntx.Feature f, SpatialType type) { if (m_Translator==null) return null; string fc = f.FeatureCode; return m_Translator.FindEntityTypeByExternalName(fc, type); }