/// <summary> /// Defines links for this face. A prior call to <c>SetLine</c> is required. /// </summary> /// <param name="prev">The preceding face (after it has been processed via a call to /// <c>SetLine</c>, Must refer to the same polygon as this face.</param> /// <returns>The links (the number of array elements will equal the value that came /// back from the <c>SetLine</c> call)</returns> internal PolygonLink[] CreateLinks(PolygonFace prev) { Debug.Assert(m_Polygon!=null); Debug.Assert(m_Divider!=null); Debug.Assert(prev.Divider!=null); Debug.Assert(Object.ReferenceEquals(prev.Polygon, m_Polygon)); // Try to obtain a point feature at the beginning of this face. ISpatialIndex index = CadastralMapModel.Current.Index; PointFeature beginPoint = new FindPointQuery(index, m_Begin).Result; // If the polygon to the left of the this face? (if so, curve-related // things may need to be reversed below) bool isPolLeft = (m_Divider.Left == m_Polygon); // Default geometric info we need to define bool isCurveEnd = false; bool isRadial = false; double bearing = 0.0; double angle = 0.0; // Is the position at the beginning of this face the start // or end of a circular arc (points between 2 curves (on // compound curve) are NOT considered to be curve ends). Note // that the line could either be a CircularArc, or a topological // section based on a circular arc. ICircularArcGeometry prevArc = (prev.Divider.LineGeometry as ICircularArcGeometry); ICircularArcGeometry thisArc = (m_Divider.LineGeometry as ICircularArcGeometry); bool isPrevCurve = (prevArc!=null); bool isThisCurve = (thisArc!=null); isCurveEnd = (isPrevCurve!=isThisCurve); // If we are dealing with a point between two curves try to // set the curve parameters and, if successful, we will treat // the point as a radial point. if (isPrevCurve && isThisCurve) { isRadial = true; // Get the curve parameters... IPosition prevcen = prevArc.Circle.Center; double prevrad = prevArc.Circle.Radius; IPosition thiscen = thisArc.Circle.Center; double thisrad = thisArc.Circle.Radius; // We only need to know the sense for one of the arcs bool iscw = thisArc.IsClockwise; // If the 2 curves do not have the same centre and radius, // see if they are really close (to the nearest centimeter // on the ground). In that case, use the average values for // the 2 curves. If they really are different curves, don't // treat this as a radial curve point -- treat it as a // curve end instead. IPosition centre = null; // The centre to actually use if (!(prevcen==thiscen && Math.Abs(prevrad-thisrad)<Constants.TINY)) { double xc1 = prevcen.X; double yc1 = prevcen.Y; double xc2 = thiscen.X; double yc2 = thiscen.Y; double dxc = xc2-xc1; double dyc = yc2-yc1; if (Math.Abs(dxc)<0.01 && Math.Abs(dyc)<0.01 && Math.Abs(prevrad-thisrad)<0.01) { // Close enough centre = new Position(xc1+dxc*0.5, yc1+dyc*0.5); } else { isRadial = false; isCurveEnd = true; } } else centre = prevcen; // If the centre and radius were the same (or close enough), // define the radial bearing from the centre of the circle. // If the polygon is actually on the other side, reverse the // bearing so that it's directed INTO the polygon. if (isRadial) { Debug.Assert(centre!=null); bearing = Geom.BearingInRadians(centre, m_Begin); angle = 0.0; if (iscw != isPolLeft) bearing += Constants.PI; } } // If we're not dealing with a radial curve (or we have curves that // don't appear to be radial) if (!isRadial) { // Get the clockwise angle from the last position of the // preceding face to the first position after the start // of this face. Since info is held in a clockwise cycle // around the polygon, this will always give us the exterior // angle. Turn reference = new Turn(m_Begin, prev.TailReference); angle = reference.GetAngleInRadians(this.HeadReference); // Define the bearing to use for projecting the point. It's // in the middle of the angle, but projected into the polygon. bearing = reference.BearingInRadians + angle*0.5 + Constants.PI; } // Initialize the link at the start of the face List<PolygonLink> links = new List<PolygonLink>(); PolygonLink link = new PolygonLink(beginPoint, isCurveEnd, isRadial, bearing, angle); links.Add(link); // Initialize links for any extra points if (m_ExtraPoints!=null) { // Intermediate points can never be curve ends isCurveEnd = false; // If the face is a curve, they're radial points isRadial = isThisCurve; // Note any curve info double radius; IPosition centre = null; bool iscw = false; if (isRadial) { Debug.Assert(m_Divider.Line.LineGeometry is ICircularArcGeometry); ICircularArcGeometry arc = (m_Divider.Line.LineGeometry as ICircularArcGeometry); centre = arc.Circle.Center; radius = arc.Circle.Radius; iscw = arc.IsClockwise; angle = 0.0; } for (uint i=0; i<m_ExtraPoints.Length; i++) { //IPointGeometry loc = m_ExtraPoints[i].Geometry; PointFeature loc = m_ExtraPoints[i]; // Figure out the orientation bearing for the point if (isRadial) { Debug.Assert(centre!=null); bearing = Geom.BearingInRadians(centre, loc); if (iscw != isPolLeft) bearing += Constants.PI; } else { // Get the exterior clockwise angle IPointGeometry back; IPointGeometry fore; if (i==0) back = m_Begin; else back = m_ExtraPoints[i-1].Geometry; if (i==(m_ExtraPoints.Length-1)) fore = m_End; else fore = m_ExtraPoints[i+1].Geometry; Turn reference = new Turn(loc, back); angle = reference.GetAngleInRadians(fore); // Define the bearing to use for projecting the point. It's // in the middle of the angle, but projected into the polygon. bearing = reference.BearingInRadians + angle*0.5 + Constants.PI; } link = new PolygonLink(m_ExtraPoints[i], isCurveEnd, isRadial, bearing, angle); links.Add(link); } } return links.ToArray(); }
/// <summary> /// Defines links for this face. A prior call to <c>SetLine</c> is required. /// </summary> /// <param name="prev">The preceding face (after it has been processed via a call to /// <c>SetLine</c>, Must refer to the same polygon as this face.</param> /// <returns>The links (the number of array elements will equal the value that came /// back from the <c>SetLine</c> call)</returns> internal PolygonLink[] CreateLinks(PolygonFace prev) { Debug.Assert(m_Polygon != null); Debug.Assert(m_Divider != null); Debug.Assert(prev.Divider != null); Debug.Assert(Object.ReferenceEquals(prev.Polygon, m_Polygon)); // Try to obtain a point feature at the beginning of this face. ISpatialIndex index = CadastralMapModel.Current.Index; PointFeature beginPoint = new FindPointQuery(index, m_Begin).Result; // If the polygon to the left of the this face? (if so, curve-related // things may need to be reversed below) bool isPolLeft = (m_Divider.Left == m_Polygon); // Default geometric info we need to define bool isCurveEnd = false; bool isRadial = false; double bearing = 0.0; double angle = 0.0; // Is the position at the beginning of this face the start // or end of a circular arc (points between 2 curves (on // compound curve) are NOT considered to be curve ends). Note // that the line could either be a CircularArc, or a topological // section based on a circular arc. ICircularArcGeometry prevArc = (prev.Divider.LineGeometry as ICircularArcGeometry); ICircularArcGeometry thisArc = (m_Divider.LineGeometry as ICircularArcGeometry); bool isPrevCurve = (prevArc != null); bool isThisCurve = (thisArc != null); isCurveEnd = (isPrevCurve != isThisCurve); // If we are dealing with a point between two curves try to // set the curve parameters and, if successful, we will treat // the point as a radial point. if (isPrevCurve && isThisCurve) { isRadial = true; // Get the curve parameters... IPosition prevcen = prevArc.Circle.Center; double prevrad = prevArc.Circle.Radius; IPosition thiscen = thisArc.Circle.Center; double thisrad = thisArc.Circle.Radius; // We only need to know the sense for one of the arcs bool iscw = thisArc.IsClockwise; // If the 2 curves do not have the same centre and radius, // see if they are really close (to the nearest centimeter // on the ground). In that case, use the average values for // the 2 curves. If they really are different curves, don't // treat this as a radial curve point -- treat it as a // curve end instead. IPosition centre = null; // The centre to actually use if (!(prevcen == thiscen && Math.Abs(prevrad - thisrad) < Constants.TINY)) { double xc1 = prevcen.X; double yc1 = prevcen.Y; double xc2 = thiscen.X; double yc2 = thiscen.Y; double dxc = xc2 - xc1; double dyc = yc2 - yc1; if (Math.Abs(dxc) < 0.01 && Math.Abs(dyc) < 0.01 && Math.Abs(prevrad - thisrad) < 0.01) { // Close enough centre = new Position(xc1 + dxc * 0.5, yc1 + dyc * 0.5); } else { isRadial = false; isCurveEnd = true; } } else { centre = prevcen; } // If the centre and radius were the same (or close enough), // define the radial bearing from the centre of the circle. // If the polygon is actually on the other side, reverse the // bearing so that it's directed INTO the polygon. if (isRadial) { Debug.Assert(centre != null); bearing = Geom.BearingInRadians(centre, m_Begin); angle = 0.0; if (iscw != isPolLeft) { bearing += Constants.PI; } } } // If we're not dealing with a radial curve (or we have curves that // don't appear to be radial) if (!isRadial) { // Get the clockwise angle from the last position of the // preceding face to the first position after the start // of this face. Since info is held in a clockwise cycle // around the polygon, this will always give us the exterior // angle. Turn reference = new Turn(m_Begin, prev.TailReference); angle = reference.GetAngleInRadians(this.HeadReference); // Define the bearing to use for projecting the point. It's // in the middle of the angle, but projected into the polygon. bearing = reference.BearingInRadians + angle * 0.5 + Constants.PI; } // Initialize the link at the start of the face List <PolygonLink> links = new List <PolygonLink>(); PolygonLink link = new PolygonLink(beginPoint, isCurveEnd, isRadial, bearing, angle); links.Add(link); // Initialize links for any extra points if (m_ExtraPoints != null) { // Intermediate points can never be curve ends isCurveEnd = false; // If the face is a curve, they're radial points isRadial = isThisCurve; // Note any curve info double radius; IPosition centre = null; bool iscw = false; if (isRadial) { Debug.Assert(m_Divider.Line.LineGeometry is ICircularArcGeometry); ICircularArcGeometry arc = (m_Divider.Line.LineGeometry as ICircularArcGeometry); centre = arc.Circle.Center; radius = arc.Circle.Radius; iscw = arc.IsClockwise; angle = 0.0; } for (uint i = 0; i < m_ExtraPoints.Length; i++) { //IPointGeometry loc = m_ExtraPoints[i].Geometry; PointFeature loc = m_ExtraPoints[i]; // Figure out the orientation bearing for the point if (isRadial) { Debug.Assert(centre != null); bearing = Geom.BearingInRadians(centre, loc); if (iscw != isPolLeft) { bearing += Constants.PI; } } else { // Get the exterior clockwise angle IPointGeometry back; IPointGeometry fore; if (i == 0) { back = m_Begin; } else { back = m_ExtraPoints[i - 1].Geometry; } if (i == (m_ExtraPoints.Length - 1)) { fore = m_End; } else { fore = m_ExtraPoints[i + 1].Geometry; } Turn reference = new Turn(loc, back); angle = reference.GetAngleInRadians(fore); // Define the bearing to use for projecting the point. It's // in the middle of the angle, but projected into the polygon. bearing = reference.BearingInRadians + angle * 0.5 + Constants.PI; } link = new PolygonLink(m_ExtraPoints[i], isCurveEnd, isRadial, bearing, angle); links.Add(link); } } return(links.ToArray()); }