Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Annotation"/> class with the
 /// <see cref="FontStyle"/> property set to <see cref="System.Drawing.FontStyle.Regular"/>.
 /// </summary>
 /// <param name="text">The annotation text.</param>
 /// <param name="position">The position for the text (center-baseline aligned).</param>
 /// <param name="height">The height of the text (in meters on the ground).</param>
 /// <param name="rotation">The rotation (in radians clockwise from horizontal).</param>
 internal Annotation(string text, IPosition position, double height, double rotation)
 {
     m_Text      = text;
     m_Position  = PointGeometry.Create(position);
     m_Height    = height;
     m_Rotation  = new RadianValue(rotation);
     m_FontStyle = FontStyle.Regular;
 }
Пример #2
0
        internal HorizontalRay(IPosition start, double distance)
        {
            if (distance < 0.0)
            {
                throw new ArgumentOutOfRangeException();
            }

            m_Start = PointGeometry.Create(start);
            m_EndX  = start.X + distance;
        }
Пример #3
0
        /// <summary>
        /// Remembers a new polygon reference position for this label.
        /// </summary>
        /// <param name="p">The reference position. Specify null if the default reference
        /// position should be used (the position associated with the text geometry).</param>
        internal void SetPolPosition(IPointGeometry p)
        {
            if (p == null)
            {
                m_PolygonPosition = null;
            }
            else
            {
                m_PolygonPosition = PointGeometry.Create(p);
            }

            // If the label was previously "built", re-calculate the relationship to any
            // enclosing polygon
            RecalculateEnclosingPolygon();
        }
Пример #4
0
        /// <summary>
        /// Creates a new <c>FindIslandContainerQuery</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="island">The island you want the container for</param>
        internal FindIslandContainerQuery(ISpatialIndex index, Island island)
        {
            m_Island = island;
            m_Result = null;

            // Get the most easterly point in the island.
            IPosition ep = m_Island.GetEastPoint();

            // Shift the east point ONE MICRON further to the east, to ensure
            // we don't pick up the interior of the island!
            PointGeometry eg = PointGeometry.Create(ep);

            m_EastPoint = new PointGeometry(eg.Easting.Microns + 1, eg.Northing.Microns);
            IWindow w = new Window(m_EastPoint, m_EastPoint);

            index.QueryWindow(w, SpatialType.Polygon, OnQueryHit);
        }
Пример #5
0
        private ISpatialObject SelectObject(ISpatialDisplay display, IPosition p, SpatialType spatialType)
        {
            ProjectSettings   ps         = m_Project.Settings;
            CadastralMapModel cmm        = this.CadastralMapModel;
            ISpatialSelection currentSel = this.SpatialSelection;
            ISpatialObject    oldItem    = currentSel.Item;
            ISpatialObject    newItem;

            // Try to find a point feature if points are drawn.
            if ((spatialType & SpatialType.Point) != 0 && display.MapScale <= ps.ShowPointScale)
            {
                ILength size = new Length(ps.PointHeight * 0.5);
                newItem = cmm.QueryClosest(p, size, SpatialType.Point);
                if (newItem != null)
                {
                    return(newItem);
                }
            }

            // If we are adding a line, don't bother trying to select
            // lines or polygons or text.

            /*
             * if (m_Op==ID_LINE_NEW || m_Op==ID_LINE_CURVE)
             *  return 0;
             */

            ILength tol = new Length(0.001 * display.MapScale);

            // Try to find a line, using a tolerance of 1mm at the draw scale.
            if ((spatialType & SpatialType.Line) != 0)
            {
                // If we previously selected something, see if the search point
                // lies within tolerance. If so, just return with what we've already got
                // ...just make the query (the issue here has to do with special highlighting
                // for topological sections -- if you point at another section of a line, the
                // highlighting doesn't move).

                // if (oldItem!=null && oldItem.SpatialType==SpatialType.Line)
                // {
                //     ILength dist = oldItem.Distance(p);
                //     if (dist.Meters < tol.Meters)
                //         return;
                // }

                newItem = cmm.QueryClosest(p, tol, SpatialType.Line);
                if (newItem != null)
                {
                    return(newItem);
                }
            }

            // Try for a text string if text is drawn.
            // The old software handles text by checking that the point is inside
            // the outline, not sure whether the new index provides acceptable alternative.
            if ((spatialType & SpatialType.Text) != 0 && display.MapScale <= ps.ShowLabelScale)
            {
                newItem = cmm.QueryClosest(p, tol, SpatialType.Text);
                if (newItem != null)
                {
                    return(newItem);
                }
            }

            // Just return if a command dialog is up,
            // since selecting a polygon is distracting at that stage
            // (really, this applies to things like intersect commands).
            // There MIGHT be cases at some later date where we really
            // do want to select pols...
            // For updates, allow polygon selection

            if (IsCommandRunning && !(m_Command is UpdateUI))
            {
                return(null);
            }

            if ((spatialType & SpatialType.Polygon) != 0)
            {
                // If we currently have a selected polygon, see if we're still inside it.

                /*
                 * if (oldItem is Polygon)
                 * {
                 *  Polygon oldPol = (oldItem is Polygon);
                 *  if (oldPol.IsEnclosing(p))
                 *
                 * }
                 */

                IPointGeometry pg    = PointGeometry.Create(p);
                ISpatialIndex  index = cmm.Index;
                Polygon        pol   = new FindPointContainerQuery(index, pg).Result;
                if (pol != null)
                {
                    return(pol);
                }
            }

            return(null);
        }
Пример #6
0
        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);
        }
Пример #7
0
        /// <summary>
        /// Obtains the geometry for spans along this leg.
        /// </summary>
        /// <param name="bc">The position for the start of the leg.
        /// <param name="bcBearing">The bearing on entry into the leg.</param>
        /// <param name="sfac">Scale factor to apply to distances.</param>
        /// <param name="spans">Information for the spans coinciding with this leg.</param>
        /// <returns>The sections along this leg</returns>
        internal override ILineGeometry[] GetSpanSections(IPosition bc, double bcBearing, double sfac, SpanInfo[] spans)
        {
            // Can't do anything if the leg radius isn't defined
            if (m_Metrics.ObservedRadius == null)
            {
                throw new InvalidOperationException("Cannot create sections for circular leg with undefined radius");
            }

            var result = new ILineGeometry[spans.Length];

            // Use supplied stuff to derive info on the center and EC.
            IPosition center;
            IPosition ec;
            double    bearingToBC;
            double    ecBearing;

            GetPositions(bc, bcBearing, sfac, out center, out bearingToBC, out ec, out ecBearing);

            // Define the underlying circle
            ICircleGeometry circle = new CircleGeometry(PointGeometry.Create(center), BasicGeom.Distance(center, bc));

            // Handle case where the leg is a cul-de-sac with no observed spans
            if (spans.Length == 1 && spans[0].ObservedDistance == null)
            {
                result[0] = new CircularArcGeometry(circle, bc, ec, m_Metrics.IsClockwise);
                return(result);
            }

            /// Initialize scaling factor for distances in cul-de-sacs (ratio of the length calculated from
            /// the CA & Radius, versus the observed distances that were actually specified). For curves that
            /// are not cul-de-sacs, this will be 1.0
            double culFactor = 1.0;

            if (m_Metrics.IsCulDeSac)
            {
                double obsv = PrimaryFace.GetTotal();
                if (obsv > MathConstants.TINY)
                {
                    culFactor = Length.Meters / obsv;
                }
            }

            IPosition sPos        = bc;
            IPosition ePos        = null;
            bool      isClockwise = m_Metrics.IsClockwise;
            double    radius      = RadiusInMeters;
            double    edist       = 0.0;

            for (int i = 0; i < result.Length; i++, sPos = ePos)
            {
                // Add on the unscaled distance
                edist += spans[i].ObservedDistance.Meters;

                // Get the angle subtended at the center of the circle. We use
                // unscaled values here, since the scale factors would cancel out.
                // However, we DO apply any cul-de-sac scaling factor, to account
                // for the fact that the distance may be inconsistent with the
                // curve length derived from the CA and radius. For example, it
                // is possible that the calculated curve length=200, although the
                // total of the observed spans is somehow only 100. In that case,
                // if the supplied distance is 50, we actually want to use a
                // value of 50 * (200/100) = 100.

                double angle = (edist * culFactor) / radius;

                // Get the bearing of the point with respect to the center of the circle.

                double bearing;

                if (isClockwise)
                {
                    bearing = bearingToBC + angle;
                }
                else
                {
                    bearing = bearingToBC - angle;
                }

                // Calculate the position using the scaled radius.
                ePos = Geom.Polar(center, bearing, radius * sfac);

                result[i] = new CircularArcGeometry(circle, sPos, ePos, isClockwise);
            }

            return(result);
        }
Пример #8
0
        /// <summary>
        /// Assigns sort values to the supplied intersections (each sort value
        /// indicates the distance from the start of this line).
        /// </summary>
        /// <param name="data">The intersection data to update</param>
        internal override void SetSortValues(List <IntersectionData> dataList)
        {
            // Get an array of cumulative distances for each segment.
            IPointGeometry[] data    = this.Data;
            double[]         cumdist = GetCumDist(data);

            foreach (IntersectionData xd in dataList)
            {
                // Get the first intersection
                IPointGeometry pos = PointGeometry.Create(xd.P1);
                double         xi  = pos.X;
                double         yi  = pos.Y;

                // Find the segment number
                // @devnote -- we may need to use a different function at
                // this point, because FindSegment currently assumes that
                // the intersection must lie within the window of the segment.
                int segnum = FindSegment(data, true, 0, pos);
                if (segnum < 0)
                {
                    throw new Exception("MultiSegmentGeometry.SetSortValues - intersection not on line");
                }

                // Get position of the start of segment
                double xs = data[segnum].X;
                double ys = data[segnum].Y;

                // Get the distance squared to the start of segment
                double dx  = xi - xs;
                double dy  = yi - ys;
                double dsq = (dx * dx + dy * dy);

                // If we have a graze, process the 2nd intersection too
                // (it MUST lie on the same segment, given that multisegments
                // are intersected by processing each segment in turn).
                // If it's closer than the distance we already have, use
                // the second intersection as the sort value, and treat
                // it subsequently as the first intersection.

                if (xd.IsGraze)
                {
                    xi = xd.P2.X;
                    yi = xd.P2.Y;

                    dx = xi - xs;
                    dy = yi - ys;

                    double dsq2 = (dx * dx + dy * dy);

                    if (dsq2 < dsq)
                    {
                        xd.Reverse();
                        dsq = dsq2;
                    }
                }

                // Set the sort value
                double dset = cumdist[segnum] + Math.Sqrt(dsq);
                xd.SortValue = dset;
            }
        }