/// <summary> /// Constructor used to combine a series of <c>IntersectResult</c> objects. This /// implementation is used to obtain a results object for a new topological line /// that has just been intersected against the map. /// </summary> /// <param name="xsect">The result of intersecting a line with the map</param> internal IntersectionResult(IntersectionFinder xsect) { m_IntersectedObject = xsect.Intersector; m_Geom = m_IntersectedObject.LineGeometry; m_Data = null; // Get the total number of intersections that were found (there's one // InteresectionResult for each intersected line) IList<IntersectionResult> results = xsect.Intersections; int nData = 0; foreach (IntersectionResult r in results) nData += r.m_Data.Count; // Return if no intersections. if (nData==0) return; // Copy over the info m_Data = new List<IntersectionData>(nData); foreach (IntersectionResult r in results) { List<IntersectionData> data = r.Intersections; foreach (IntersectionData d in data) m_Data.Add(d); } // Reverse all context codes. foreach (IntersectionData d in m_Data) d.ReverseContext(); }
/// <summary> /// Creates a new <c>DividerObject</c> that wraps the supplied divider. /// </summary> /// <param name="d">The divider to wrap</param> internal DividerObject(IDivider d) { if (d==null) throw new ArgumentNullException(); m_Divider = d; m_Geom = m_Divider.LineGeometry; }
/// <summary> /// Creates a new <c>FindPointsOnLineQuery</c> (and executes it). The result of the query /// can then be obtained through the <c>Result</c> property. /// </summary> /// <param name="index">The spatial index to search</param> /// <param name="line">The line of interest.</param> /// <param name="wantEnds">Specify true if you want points coincident with the line ends.</param> /// <param name="tol">The search tolerance (expected to be greater than zero).</param> internal FindPointsOnLineQuery(ISpatialIndex index, LineGeometry line, bool wantEnds, ILength tol) { m_Line = line; m_Tolerance = tol.Meters; m_Result = new List<PointFeature>(); IWindow w = m_Line.Extent; index.QueryWindow(w, SpatialType.Point, OnQueryHit); }
/// <summary> /// Obtains line geometry that isn't an instance of <see cref="SectionGeometry"/> /// </summary> /// <param name="geom">The geometry that could be a section</param> /// <returns>Concrete (unsectioned) geometry that corresponds to <paramref name="geom"/></returns> private UnsectionedLineGeometry GetUnsectionedLineGeometry(LineGeometry geom) { if (geom is UnsectionedLineGeometry) return (geom as UnsectionedLineGeometry); if (geom is SectionGeometry) return (geom as SectionGeometry).Make(); throw new NotImplementedException("Unexpected line geometry: "+geom.GetType().Name); }
/// <summary> /// Creates a new <c>FindIntersectionsQuery</c> (and executes it). The result of the query /// can then be obtained through the <c>Result</c> property. /// <para/> /// Use this constructor when intersecting with geometry that has been created ad-hoc. /// Note that if you are looking to intersect a line feature (already part of /// the spatial index), you should use the constructor that accepts the <c>LineFeature</c>. /// </summary> /// <param name="index">The spatial index to search</param> /// <param name="geom">The geometry to intersect.</param> /// <param name="wantEndEnd">Specify true if you want end-to-end intersections in the results.</param> internal FindIntersectionsQuery(ISpatialIndex index, LineGeometry geom, bool wantEndEnd) { m_Feature = null; m_Geom = GetUnsectionedLineGeometry(geom); m_WantEndEnd = wantEndEnd; m_Result = new List<IntersectionResult>(100); FindIntersections(index); }
/// <summary> /// Creates a new <c>IntersectionFinder</c> for the specified geometry. /// Use this constructor when intersecting geometry that has been created ad-hoc. /// </summary> /// <param name="geom">The geometry to intersect.</param> /// <param name="wantEndEnd">Specify true if you want end-to-end intersections in the results.</param> internal IntersectionFinder(LineGeometry geom, bool wantEndEnd) { m_Line = geom; ISpatialIndex index = CadastralMapModel.Current.Index; m_Intersects = new FindIntersectionsQuery(index, geom, wantEndEnd).Result; }
/// <summary> /// Creates a new <c>IntersectionResult</c> for the specified line. This /// implementation is used when intersecting ad-hoc geometry, as well as /// representing the results of intersecting a line feature with previously /// existing topology. /// </summary> /// <param name="intersectedObject"></param> internal IntersectionResult(IIntersectable intersectedObject) { m_IntersectedObject = intersectedObject; m_Geom = intersectedObject.LineGeometry; m_Data = new List<IntersectionData>(); }
/// <summary> /// Initializes a new instance of the <see cref="LineFeature"/> class, and records it /// as part of the map model. /// </summary> /// <param name="iid">The internal ID for the feature.</param> /// <param name="fid">The (optional) user-perceived ID for the feature. If not null, /// this will be modified by cross-referencing it to the newly created feature.</param> /// <param name="ent">The entity type for the feature (not null)</param> /// <param name="creator">The operation creating the feature (not null). Expected to /// refer to an editing session that is consistent with the session ID that is part /// of the feature's internal ID.</param> /// <param name="start">The point at the start of the line (not null)</param> /// <param name="end">The point at the end of the line (not null)</param> /// <param name="g">The geometry for the line (could be null, although this is only really /// expected during deserialization)</param> /// <param name="isTopological">Does the line form part of a polygon boundary?</param> /// <exception cref="ArgumentNullException">If either <paramref name="ent"/> or /// <paramref name="creator"/> or <paramref name="start"/> or <paramref name="end"/> is null. /// </exception> protected LineFeature(IFeature f, PointFeature start, PointFeature end, LineGeometry g, bool isTopological) : base(f) { if (start == null || end == null) throw new ArgumentNullException(); m_From = start; m_To = end; m_Geom = g; m_Topology = null; // Don't cross-reference if we're dealing with a temporary feature if (!f.InternalId.IsEmpty) AddReferences(); if (isTopological) SetTopology(true); }
/// <summary> /// Creates a new <c>LineFeature</c> /// </summary> /// <param name="creator">The operation that created the feature (not null)</param> /// <param name="id">The internal ID of this feature within the /// project that created it.</param> /// <param name="e">The entity type for the feature (not null)</param> /// <param name="g">The geometry defining the shape of the line (not null)</param> /// <note>To ensure that the start and end of all lines are instances of <see cref="PointFeature"/>, /// this constructor should always remain private.</note> protected LineFeature(Operation creator, InternalIdValue id, IEntity e, PointFeature start, PointFeature end, LineGeometry g) : base(creator, id, e, null) { if (g==null) throw new ArgumentNullException(); m_From = start; m_To = end; m_Geom = g; m_Topology = null; AddReferences(); // If the entity type denotes a topological boundary, initialize the topology. if (e.IsPolygonBoundaryValid) SetTopology(true); }
/// <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); } }
// Should try to get rid of this... protected void ChangeGeometry(ArcGeometry arc) { m_Geom = arc; }
/// <summary> /// Checks whether this closed shape overlaps a line /// </summary> /// <param name="shape">Positions defining a closed outline (the last position /// must coincide with the first position). At least 3 positions.</param> /// <param name="shapeWindow">The extent of <paramref name="shape"/></param> /// <param name="line">The line to compare with the shape</param> /// <returns>True if the shape overlaps the line</returns> internal bool IsOverlap(LineGeometry line) { // Get the window of the line IWindow lwin = line.Extent; // The two windows have to overlap. if (!m_Extent.IsOverlap(lwin)) return false; // If either end of the line falls inside this shape, we've got overlap. IPointGeometry p = line.Start; if (m_Extent.IsOverlap(p) && Geom.IsPointInClosedShape(this.Data, p)) return true; p = line.End; if (m_Extent.IsOverlap(p) && Geom.IsPointInClosedShape(this.Data, p)) return true; // The only thing left is a possible interesection between // the shape and the line. return IsIntersect(line); }
/// <summary> /// Checks whether this closed shape intersects (overlaps) a line. /// This assumes that a window-window overlap has already been checked for. /// </summary> /// <param name="line">The line to compare with the shape</param> /// <returns>True if intersection found.</returns> bool IsIntersect(LineGeometry line) { //IntersectionResult xres = new IntersectionResult(line); //return (xres.IntersectMultiSegment(this) > 0); IntersectionResult xres = new IntersectionResult(line); // Intersect each segment of this shape with the line. IPointGeometry[] data = this.Data; for (int i=1; i<data.Length; i++) { LineSegmentGeometry thisSeg = new LineSegmentGeometry(data[i-1], data[i]); if (xres.IntersectSegment(thisSeg) > 0) return true; } return false; }
void WriteLineGeometry(LineGeometry geom) { if (geom is SegmentGeometry) WriteSegment((SegmentGeometry)geom); else if (geom is ArcGeometry) WriteArc((ArcGeometry)geom); else if (geom is MultiSegmentGeometry) WriteMultiSegment((MultiSegmentGeometry)geom); else if (geom is SectionGeometry) WriteSection((SectionGeometry)geom); else throw new NotImplementedException("Unexpected line geometry type: " + geom.GetType().Name); }