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); }
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); }
/// <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); }
/// <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); }
/// <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); }
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; }
/// <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); }
/// <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)); }
/// <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); }
public void Init(string mapFile, NpcManager npcMgr, ISpatialSystem spatialSys) { npc_manager_ = npcMgr; spatial_system_ = spatialSys; cell_manager_.Init(DashFire.HomePath.GetAbsolutePath(mapFile)); }
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(); }
/// <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); }