/// <summary> /// Reads data that was previously written using <see cref="WriteData"/> /// </summary> /// <param name="editDeserializer">The mechanism for reading back content.</param> /// <param name="from">The point at the start of the line</param> /// <param name="to">The point at the end of the line</param> /// <param name="isTopological">Does the line act as a polygon boundary </param> /// <param name="geom">The geometry for the line.</param> static void ReadData(EditDeserializer editDeserializer, out PointFeature from, out PointFeature to, out bool isTopological, out LineGeometry geom) { from = editDeserializer.ReadFeatureRef<PointFeature>(DataField.From); to = editDeserializer.ReadFeatureRef<PointFeature>(DataField.To); isTopological = editDeserializer.ReadBool(DataField.Topological); if (editDeserializer.IsNextField(DataField.Type)) { geom = editDeserializer.ReadPersistent<LineGeometry>(DataField.Type); // Ensure terminals have been defined (since there was no easy way to pass them // through to the LineGeometry constructor). geom.StartTerminal = from; geom.EndTerminal = to; // If we're dealing with a circular arc, and the bc/ec points have defined // positions (e.g. coming from an import), we can calculate the radius now. // Otherwise we'll need to wait until geometry has been calculated. // The radius is defined here only because it's consistent with older code. // It may well be better to leave the definition of circle radius till later // (i.e. do all circles after geometry has been calculated). ArcGeometry arc = (geom as ArcGeometry); if (arc != null) { Circle c = (Circle)arc.Circle; PointFeature center = c.CenterPoint; if (center.PointGeometry != null && from.PointGeometry != null) c.Radius = Geom.Distance(center.PointGeometry, from.PointGeometry); } } else { geom = new SegmentGeometry(from, to); } }
void WriteSegment(SegmentGeometry line) { Line acLine = new Line(); IPointGeometry start = line.Start; acLine.StartPoint = new Vector3d(start.X, start.Y, 0.0); IPointGeometry end = line.End; acLine.EndPoint = new Vector3d(end.X, end.Y, 0.0); acLine.Layer = m_Layer; m_Dxf.AddEntity(acLine); }
/// <summary> /// Does any edge of this closed shape intersect a line segment? /// </summary> /// <param name="ps">The start of the segment</param> /// <param name="pe">The end of the segment</param> /// <returns>True if any edge of this shape intersects the segment</returns> bool IsOverlap(IPointGeometry ps, IPointGeometry pe) { Window segwin = new Window(ps, pe); if (!m_Extent.IsOverlap(segwin)) return false; // Define the test segment. ITerminal ts = new FloatingTerminal(ps); ITerminal te = new FloatingTerminal(pe); SegmentGeometry seg = new SegmentGeometry(ts, te); return IsIntersect(seg); }
/// <summary> /// Updates info on the longest horizontal span that crosses this polygon (used /// by <see cref="GetLabelPosition"/>) /// </summary> /// <param name="y">The Y-value of the scan line.</param> /// <param name="minx">The X-value for the western end of the scan line.</param> /// <param name="maxx">The X-value for the eastern end of the scan line.</param> /// <param name="weight">Weighting factor to use when comparing span lengths versus /// the initial best length.</param> /// <param name="beststart">The position of the start of the best span.</param> /// <param name="bestend">The position of the end of the best span.</param> /// <param name="bestlen">The weighted length of the best span. This is what defines /// the meaning of "best".</param> void GetLabelSpan(double y, double minx, double maxx, double weight, ref IPosition beststart, ref IPosition bestend, ref double bestlen) { // Define scan line. ITerminal sloc = new FloatingTerminal(minx, y); ITerminal eloc = new FloatingTerminal(maxx, y); SegmentGeometry seg = new SegmentGeometry(sloc, eloc); // Intersect with the map IntersectionFinder xseg = new IntersectionFinder(seg, true); // Arrange intersections along the scan line. IntersectionResult xres = new IntersectionResult(xseg); xres.Sort(true); // Define start of the first span IPosition start = sloc; IPosition end = null; // Go through each successive intersection, to locate spans // that run through the interior of the polygon. foreach (IntersectionData d in xres.Intersections) { // If the intersection is a graze if (d.IsGraze) { // Just define the end of the graze as the end point (there's // no point in trying to locate a label along the graze). end = d.P2; } else { // Simple intersection... // Get the next intersection end = d.P1; // Get the midpoint of the span. IPosition mid = Position.CreateMidpoint(start, end); // If the midpoint really falls inside this polygon, see whether the span // length is bigger than what we already have (if anything). if (this.IsEnclosing(mid)) { double len = (end.X - start.X)/weight; if (len>bestlen) { bestlen = len; beststart = start; bestend = end; } } } start = end; } }