예제 #1
0
        private void CoordSystemForm_Shown(object sender, EventArgs e)
        {
            CadastralMapModel map = CadastralMapModel.Current;
            ISpatialSystem    sys = map.SpatialSystem;

            systemNameLabel.Text = sys.Name;
            epsgNumberLabel.Text = sys.EpsgNumber.ToString();

            // Display mean elevation and geoid separation in the current data entry units.
            EditingController ec     = EditingController.Current;
            DistanceUnit      eUnit  = ec.EntryUnit;
            DistanceUnit      meters = EditingController.GetUnits(DistanceUnitType.Meters);

            // The mean elevation & geoid separation fields are always editable (even
            // if the map contains stuff). The values are used to calculate the ground
            // area of polygons.

            Distance elev = new Distance(sys.MeanElevation.Meters, meters);

            meanElevationTextBox.Text = elev.Format(eUnit, true);

            Distance sep = new Distance(sys.GeoidSeparation.Meters, meters);

            geoidSeparationTextBox.Text = sep.Format(eUnit, true);
        }
예제 #2
0
        public bool GetNearstPoint(ISpatialSystem spatialSystem, int bodySize, Vector3 pt, ref Vector3 tp)
        {
            bool ret = false;

            if (null != m_Path && m_PathStart >= 0 && m_PathStart + m_PathLength >= 1 && m_PathStart + m_PathLength <= m_Path.Count)
            {
                if (m_Path.Count > 0)
                {
                    float dist = Geometry.PointToPolylineDistance(pt, m_Path, m_PathStart, m_PathLength, ref tp);
                    float r    = Geometry.Relation(pt, m_StartPos, m_Path[0]);
                    if (r >= 0 && r <= 1)
                    {
                        Vector3 t = Geometry.Perpendicular(pt, m_StartPos, m_Path[0]);
                        if (Geometry.DistanceSquare(pt, t) < dist * dist)
                        {
                            tp = t;
                        }
                        ret = true;
                    }
                    else if (dist < 1000)
                    {
                        ret = true;
                    }
                }
            }
            return(ret);
        }
        /// <summary>
        /// Calculates the positions of the split point.
        /// </summary>
        /// <param name="line">The line being subdivided.</param>
        /// <param name="dist">The distance to the split point.</param>
        /// <param name="isFromEnd">Is the distance from the end of the line?</param>
        /// <returns>The calculated position (null if the distance is longer than the line being subdivided,
        /// or supplied information is incomplete)</returns>
        internal static IPosition Calculate(LineFeature line, Distance dist, bool isFromEnd)
        {
            // Can't calculate if there is insufficient data.
            if (line == null || dist == null)
            {
                return(null);
            }

            // The length must be defined.
            if (!dist.IsDefined)
            {
                return(null);
            }

            // Return if the observed distance is longer than the total
            // length of the line.
            double maxlen  = line.Length.Meters;
            double obsvlen = dist.Meters;

            if (obsvlen > maxlen)
            {
                return(null);
            }

            // Get the approximate position of the split point.
            IPosition    start, approx;
            LineGeometry g = line.LineGeometry;

            if (isFromEnd)
            {
                start = line.EndPoint;
                g.GetPosition(new Length(maxlen - obsvlen), out approx);
            }
            else
            {
                start = line.StartPoint;
                g.GetPosition(new Length(obsvlen), out approx);
            }

            // Get the distance to the approximate position on the mapping plane.
            ISpatialSystem sys     = CadastralMapModel.Current.SpatialSystem;
            double         planlen = dist.GetPlanarMetric(start, approx, sys);

            // Figure out the true position on the line.
            IPosition splitpos;

            if (isFromEnd)
            {
                g.GetPosition(new Length(maxlen - planlen), out splitpos);
            }
            else
            {
                g.GetPosition(new Length(planlen), out splitpos);
            }

            return(splitpos);
        }
예제 #4
0
        /// <summary>
        /// Retruns the equivalent distance on the mapping plane.
        /// </summary>
        /// <param name="from">The position the distance is measured from.</param>
        /// <param name="to">The approximate end position.</param>
        /// <param name="sys">The mapping system</param>
        /// <returns>The distance on the mapping plane.</returns>
        internal double GetPlanarMetric(IPosition from, IPosition to, ISpatialSystem sys)
        {
            if (!this.IsDefined)
            {
                return(0.0);
            }

            double sfac = sys.GetLineScaleFactor(from, to);

            return(m_ObservedMetric * sfac);
        }
예제 #5
0
        /// <summary>
        /// Gets the well known text for the coordinate system associated with the
        /// current map model.
        /// </summary>
        /// <returns>The WKT for the coordinate system</returns>
        /// <remarks>
        /// This aims to avoid the huge delay that arises when CSMap is asked to return
        /// the WKT for the first time (takes about 8 seconds on my machine). Given that
        /// it is highly likely that just one coordinate system will be in regular use,
        /// this method caches the last result as part of the application settings.
        /// <para/>
        /// It may be preferable to save the WKT as part of the cedx file.
        /// </remarks>
        internal string GetCoordinateSystemText()
        {
            ISpatialSystem ss = CadastralMapModel.Current.SpatialSystem;

            if (ss.Name != Settings.Default.LastSystemName)
            {
                string wkt = ss.GetWellKnownText();

                Settings.Default.LastSystemName = ss.Name;
                Settings.Default.LastSystemText = wkt;
                Settings.Default.Save();
            }

            return(Settings.Default.LastSystemText);
        }
예제 #6
0
        /// <summary>
        /// Returns the equivalent distance on the mapping plane.
        /// </summary>
        /// <param name="from">The position the distance is measured from.</param>
        /// <param name="bearing">The bearing for the distance, in radians.</param>
        /// <param name="sys">The mapping system</param>
        /// <returns>The distance on the mapping plane.</returns>
        internal double GetPlanarMetric(IPosition from, double bearing, ISpatialSystem sys)
        {
            // Return zero if this distance is undefined.
            if (!this.IsDefined)
            {
                return(0.0);
            }

            // Calculate approximation for the terminal position (treating
            // this distance as a planar distance).
            IPosition to = Geom.Polar(from, bearing, m_ObservedMetric);

            // Use the approximate location to determine line scale factor
            double sfac = sys.GetLineScaleFactor(from, to);

            return(m_ObservedMetric * sfac);
        }
예제 #7
0
        private void okButton_Click(object sender, EventArgs e)
        {
            // Get the coordinate system in case we need to make changes.
            ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem;

            // Mean elevation. If no units were specified, this
            // assumes the current data entry units.
            double   meanElev = sys.MeanElevation.Meters;
            Distance elev;

            if (Distance.TryParse(meanElevationTextBox.Text, out elev))
            {
                meanElev = elev.Meters;
            }

            // Geoid separation
            double   gSep = sys.GeoidSeparation.Meters;
            Distance sep;

            if (Distance.TryParse(geoidSeparationTextBox.Text, out sep))
            {
                gSep = sep.Meters;
            }

            if (Math.Abs(meanElev - sys.MeanElevation.Meters) > 0.0001 ||
                Math.Abs(gSep - sys.GeoidSeparation.Meters) > 0.0001)
            {
                sys.MeanElevation   = new Length(meanElev);
                sys.GeoidSeparation = new Length(gSep);

                // Update application settings too (the remembered settings become the default
                // for any new maps subsequently created -- see CoordinateSystem constructor).

                // TODO: The following expects the user to save. Should really utilize an editing op
                // at this stage.

                Settings.Default.MeanElevation   = meanElev;
                Settings.Default.GeoidSeparation = gSep;
                Settings.Default.Save();
            }

            DialogResult = DialogResult.OK;
            Close();
            return;
        }
예제 #8
0
        /// <summary>
        /// Returns a formatted distance string.
        /// </summary>
        /// <param name="metric">The distance on the mapping plane (in meters).</param>
        /// <param name="from">The start position.</param>
        /// <param name="to">The end position.</param>
        /// <returns>The formatted distance</returns>
        protected string Format(double metric, IPosition from, IPosition to)
        {
            if (m_Unit == null)
            {
                m_Distance = String.Empty;
            }
            else
            {
                // Get the fixed number of significant digits to show.
                int prec = -1;

                if (m_Unit.UnitType == DistanceUnitType.Meters)
                {
                    prec = 3;
                }
                else if (m_Unit.UnitType == DistanceUnitType.Feet)
                {
                    prec = 2;
                }
                else if (m_Unit.UnitType == DistanceUnitType.Chains)
                {
                    prec = 4;
                }

                // Get string for the planar distance.
                string pstring = m_Unit.Format(metric, true, prec);

                // Get string for the ground distance (don't bother with
                // units abbreviation).
                ISpatialSystem sys     = CadastralMapModel.Current.SpatialSystem;
                double         sfac    = sys.GetLineScaleFactor(from, to);
                double         gmetric = metric / sfac;
                string         gstring = m_Unit.Format(gmetric, false, prec);

                // Format the complete string.
                m_Distance = String.Format("{0} ({1} on ground)", pstring, gstring);
            }

            return(m_Distance);
        }
예제 #9
0
        /// <summary>
        /// Calculates the position of the sideshot point.
        /// </summary>
        /// <param name="dir">The direction observation (if any).</param>
        /// <param name="len">The length observation (if any). Could be a <c>Distance</c> or an
        /// <c>OffsetPoint</c>.</param>
        /// <returns>The position of the sideshot point (null if there is insufficient data
        /// to calculate a position)</returns>
        internal static IPosition Calculate(Direction dir, Observation len)
        {
            // Return if there is insufficient data.
            if (dir == null || len == null)
            {
                return(null);
            }

            // Get the position of the point the sideshot should radiate from.
            PointFeature from = dir.From;

            // Get the position of the start of the direction line (which may be offset).
            IPosition start = dir.StartPosition;

            // Get the bearing of the direction.
            double bearing = dir.Bearing.Radians;

            // Get the length of the sideshot arm.
            double length = len.GetDistance(from).Meters;

            // Calculate the resultant position. Note that the length is the length along the
            // bearing -- if an offset was specified, the actual length of the line from-to =
            // sqrt(offset*offset + length*length)
            IPosition to = Geom.Polar(start, bearing, length);

            // Return if the length is an offset point. In that case, the length we have obtained
            // is already a length on the mapping plane, so no further reduction should be done
            // (although it's debateable).
            if (len is OffsetPoint)
            {
                return(to);
            }

            // Using the position we've just got, reduce the length we used to a length on the
            // mapping plane (it's actually a length on the ground).
            ISpatialSystem sys  = CadastralMapModel.Current.SpatialSystem;
            double         sfac = sys.GetLineScaleFactor(start, to);

            return(Geom.Polar(start, bearing, length * sfac));
        }
예제 #10
0
        /// <summary>
        /// Calculates positions that are parallel to a line.
        /// </summary>
        /// <param name="line">The reference line.</param>
        /// <param name="offset">The offset to the parallel, in ground units. Signed to denote
        /// which side (less than zero means it's to the left of the reference line).</param>
        /// <param name="sres">The position of the start of the parallel.</param>
        /// <param name="eres">The position of the end of the parallel.</param>
        /// <returns>True if positions calculated ok</returns>
        static bool Calculate(LineFeature line, Distance offset, out IPosition sres, out IPosition eres)
        {
            // No result positions so far.
            sres = eres = null;

            // Get the ends of the reference line.
            IPosition spos = line.StartPoint;
            IPosition epos = line.EndPoint;

            ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem;

            // If the reference line is a circular arc, get the curve info.
            ArcFeature arc = line.GetArcBase();

            if (arc != null)
            {
                Circle    circle = arc.Circle;
                double    radius = circle.Radius;
                IPosition centre = circle.Center;
                bool      iscw   = arc.IsClockwise;

                // Get the midpoint of the curve. The reduction of the
                // ground distance will be along the line that goes
                // from the centre of the circle & through this position.

                ILength   len     = line.Length;
                ILength   halfLen = new Length(len.Meters * 0.5);
                IPosition middle;
                line.LineGeometry.GetPosition(halfLen, out middle);

                // Get the bearing from the centre to the mid-position
                // and use that to reduce the offset to the mapping plane.
                double bearing = Geom.BearingInRadians(centre, middle);
                double offdist = offset.GetPlanarMetric(middle, bearing, sys);

                // No parallel if the offset exceeds the radius.
                // if ( offdist > radius ) return FALSE;

                // Calculate the parallel points.
                double sbear = Geom.BearingInRadians(centre, spos);
                sres = Geom.Polar(centre, sbear, offdist + radius);

                double ebear = Geom.BearingInRadians(centre, epos);
                eres = Geom.Polar(centre, ebear, offdist + radius);
            }
            else
            {
                // Get the bearing.of the line.
                double bearing = Geom.BearingInRadians(spos, epos);

                // Get the planar distance for a perpendicular line that passes
                // through the midpoint of the reference line. The planar distance
                // will have the same sign as the ground value.

                IPosition middle = Position.CreateMidpoint(spos, epos);
                bearing += Constants.PIDIV2;
                double offdist = offset.GetPlanarMetric(middle, bearing, sys);

                // Calculate the parallel points.
                sres = Geom.Polar(spos, bearing, offdist);
                eres = Geom.Polar(epos, bearing, offdist);
            }

            return(true);
        }
예제 #11
0
 public void Init(string mapFile, NpcManager npcMgr, ISpatialSystem spatialSys)
 {
     npc_manager_    = npcMgr;
     spatial_system_ = spatialSys;
     cell_manager_.Init(DashFire.HomePath.GetAbsolutePath(mapFile));
 }
예제 #12
0
        void RunExport(string fileName)
        {
            CadastralMapModel mapModel = CadastralMapModel.Current;

            using (ICreateDataStore cmd = m_Connection.CreateCommand(CommandType.CommandType_CreateDataStore) as ICreateDataStore)
            {
                try
                {
                    cmd.DataStoreProperties.SetProperty("File", fileName);
                    cmd.Execute();
                }
                catch (OSGeo.FDO.Common.Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }

            // The connection after the created is ConnectionState_Closed, so open it!
            m_Connection.ConnectionInfo.ConnectionProperties.SetProperty("File", fileName);
            m_Connection.Open();

            // Define coordinate system
            using (ICreateSpatialContext cmd = m_Connection.CreateCommand(CommandType.CommandType_CreateSpatialContext) as ICreateSpatialContext)
            {
                ISpatialSystem ss = mapModel.SpatialSystem;
                cmd.CoordinateSystem = ss.Name; // CSMap key name
                cmd.ExtentType       = SpatialContextExtentType.SpatialContextExtentType_Static;
                IWindow         mapExtent = mapModel.Extent;
                IDirectPosition minxy     = m_Factory.CreatePositionXY(mapExtent.Min.X, mapExtent.Min.Y);
                IDirectPosition maxxy     = m_Factory.CreatePositionXY(mapExtent.Max.X, mapExtent.Max.Y);
                IEnvelope       extent    = m_Factory.CreateEnvelope(minxy, maxxy);
                IGeometry       gx        = m_Factory.CreateGeometry(extent);
                cmd.Extent              = m_Factory.GetFgf(gx);
                cmd.XYTolerance         = 0.000001; // resolution?
                cmd.CoordinateSystemWkt = EditingController.Current.GetCoordinateSystemText();
                cmd.Execute();
            }

            // Define feature schema
            FeatureSchema fs = new FeatureSchema("Steve", "This is a test");

            FeatureClass fc = new FeatureClass("FC", "Test feature class");

            fs.Classes.Add(fc);
            GeometricPropertyDefinition gp = new GeometricPropertyDefinition("Geometry", "Polygon property");

            // When you stick more than one geometric type into the output, you can't
            // convert to SHP (not with FDO Toolbox anyway).
            //gp.GeometryTypes = (int)GeometricType.GeometricType_Surface;
            gp.GeometryTypes = (int)GeometricType.GeometricType_All;
            fc.Properties.Add(gp);
            fc.GeometryProperty = gp;

            // c.f. FdoToolbox ExpressUtility
            DataPropertyDefinition dp = new DataPropertyDefinition("ID", "Test ID");

            dp.DataType        = DataType.DataType_Int32;
            dp.Nullable        = false;
            dp.ReadOnly        = true;
            dp.IsAutoGenerated = true;
            fc.Properties.Add(dp);

            // Feature class requires an identity column for the insert
            fc.IdentityProperties.Add(dp);

            using (IApplySchema cmd = m_Connection.CreateCommand(CommandType.CommandType_ApplySchema) as IApplySchema)
            {
                cmd.FeatureSchema = fs;
                cmd.Execute();
            }

            mapModel.Index.QueryWindow(null, SpatialType.Polygon | SpatialType.Point, ExportFeature);

            m_Connection.Flush();
            m_Connection.Close();
        }
예제 #13
0
        /// <summary>
        /// Calculates intersection points.
        /// </summary>
        /// <param name="dist1">1st distance observation.</param>
        /// <param name="from1">The point the 1st distance was observed from.</param>
        /// <param name="dist2">2nd distance observation.</param>
        /// <param name="from2">The point the 2nd distance was observed from.</param>
        /// <param name="usedefault">True if the default intersection is required (the one that has the
        /// lowest bearing with respect to the 2 from points). False for the other one (if any).</param>
        /// <param name="xsect">The position of the intersection (if any).</param>
        /// <param name="xsect1">The 1st choice intersection (if any).</param>
        /// <param name="xsect2">The 2nd choice intersection (if any).</param>
        /// <returns>True if intersections were calculated. False if the distance circles
        /// don't intersect.</returns>
        internal static bool Calculate(Observation dist1, PointFeature from1, Observation dist2, PointFeature from2, bool usedefault,
                                       out IPosition xsect, out IPosition xsect1, out IPosition xsect2)
        {
            // Initialize intersection positions.
            xsect = xsect1 = xsect2 = null;

            // Get the 2 distances.
            double d1 = dist1.GetDistance(from1).Meters;
            double d2 = dist2.GetDistance(from2).Meters;

            if (d1 < Constants.TINY || d2 < Constants.TINY)
            {
                return(false);
            }

            // Form circles with radii that match the observed distances.
            ICircleGeometry circle1 = new CircleGeometry(from1, d1);
            ICircleGeometry circle2 = new CircleGeometry(from2, d2);

            // See if there is actually an intersection between the two circles.
            IPosition x1, x2;
            uint      nx = IntersectionHelper.Intersect(circle1, circle2, out x1, out x2);

            if (nx == 0)
            {
                return(false);
            }

            // If we have 2 intersections, and we need the non-default one, pick up the 2nd
            // intersection. If only 1 intersection, use that, regardless of the setting for
            // the "use default" flag.

            if (nx == 2 && !usedefault)
            {
                xsect = x2;
            }
            else
            {
                xsect = x1;
            }

            // Return if both distances are offset points.
            OffsetPoint offset1 = (dist1 as OffsetPoint);
            OffsetPoint offset2 = (dist2 as OffsetPoint);

            if (offset1 != null && offset2 != null)
            {
                xsect1 = x1;
                xsect2 = x2;
                return(true);
            }

            // Reduce observed distances to the mapping plane.
            ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem;

            if (offset1 == null)
            {
                d1 = d1 * sys.GetLineScaleFactor(from1, xsect);
            }

            if (offset2 == null)
            {
                d2 = d2 * sys.GetLineScaleFactor(from2, xsect);
            }

            // And calculate the exact intersection (like above)...
            // Form circles with radii that match the observed distances.
            ICircleGeometry circle1p = new CircleGeometry(from1, d1);
            ICircleGeometry circle2p = new CircleGeometry(from2, d2);

            // See if there is still an intersection between the two circles.
            nx = IntersectionHelper.Intersect(circle1p, circle2p, out x1, out x2);
            if (nx == 0)
            {
                return(false);
            }

            // If we have 2 intersections, and we need the non-default one, pick up the 2nd
            // intersection. If only 1 intersection, use that, regardless of the setting for
            // the "use default" flag.

            if (nx == 2 && !usedefault)
            {
                xsect = x2;
            }
            else
            {
                xsect = x1;
            }

            xsect1 = x1;
            xsect2 = x2;

            return(true);
        }
        /// <summary>
        /// Calculates the intersection point.
        /// </summary>
        /// <param name="dir">Direction observation.</param>
        /// <param name="distance">Distance observation.</param>
        /// <param name="from">The point the distance was observed from.</param>
        /// <param name="usedefault">True if the default intersection is required (the one
        /// closer to the origin of the direction line). False for the other one (if any).</param>
        /// <param name="xsect">The position of the intersection (if any).</param>
        /// <param name="xsect1">The 1st choice intersection (if any).</param>
        /// <param name="xsect2">The 2nd choice intersection (if any).</param>
        /// <returns>True if intersections were calculated. False if the distance circles
        /// don't intersect.</returns>
        internal static bool Calculate(Direction dir, Observation distance, PointFeature from, bool usedefault,
                                       out IPosition xsect, out IPosition xsect1, out IPosition xsect2)
        {
            // Initialize intersection positions.
            xsect = xsect1 = xsect2 = null;

            // Get the distance.
            double dist = distance.GetDistance(from).Meters;

            if (dist < Constants.TINY)
            {
                return(false);
            }

            // Form circle with a radius that matches the observed distance.
            ICircleGeometry circle = new CircleGeometry(from, dist);

            // See if there is actually an intersection between the direction & the circle.
            IPosition x1, x2;
            uint      nx = dir.Intersect(circle, out x1, out x2);

            if (nx == 0)
            {
                return(false);
            }

            // If we have 2 intersections, and we need the non-default one, pick up the 2nd
            // intersection. If only 1 intersection, use that, regardless of the setting for
            // the "use default" flag.

            if (nx == 2 && !usedefault)
            {
                xsect = x2;
            }
            else
            {
                xsect = x1;
            }

            // Return if the distance is an offset point.
            OffsetPoint offset = (distance as OffsetPoint);

            if (offset != null)
            {
                xsect1 = x1;
                xsect2 = x2;
                return(true);
            }

            // Reduce observed distance to the mapping plane.
            ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem;

            dist = dist * sys.GetLineScaleFactor(from, xsect);

            // And calculate the exact intersection (like above)...
            // Form circle with a radius that matches the reduced distance.
            ICircleGeometry circlep = new CircleGeometry(from, dist);

            // See if there is actually an intersection between the direction & the circle.
            nx = dir.Intersect(circlep, out x1, out x2);
            if (nx == 0)
            {
                return(false);
            }

            // If we have 2 intersections, and we need the non-default one, pick up the 2nd
            // intersection. If only 1 intersection, use that, regardless of the setting for
            // the "use default" flag.

            if (nx == 2 && !usedefault)
            {
                xsect = x2;
            }
            else
            {
                xsect = x1;
            }

            xsect1 = x1;
            xsect2 = x2;

            return(true);
        }