/// <summary> /// Creates a new <c>FindClosestQuery</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="p">The search position.</param> /// <param name="radius">The search tolerance (expected to be greater than zero).</param> /// <param name="types">The type of objects to look for.</param> internal FindClosestQuery(ISpatialIndex index, IPosition p, ILength radius, SpatialType types) { if (types == 0) { throw new ArgumentNullException("Spatial type(s) not specified"); } // If the user hasn't been specific, ensure we don't search for polygons! SpatialType useTypes = (types == SpatialType.All ? SpatialType.Feature : types); Debug.Assert((useTypes & SpatialType.Polygon) == 0); // It's important to round off to the nearest micron. Otherwise you might not // get the desired results in situations where the search radius is zero. m_Position = PositionGeometry.Create(p); m_Radius = radius; m_Types = types; m_Result = null; m_Distance = m_Radius.Meters; // The query will actually involve a square window, not a circle. IWindow x = new Window(m_Position, radius.Meters * 2.0); index.QueryWindow(x, useTypes, OnQueryHit); }
/// <summary> /// Gets the point on this line that is closest to a specified position. /// </summary> /// <param name="p">The position to search from.</param> /// <param name="tol">Maximum distance from line to the search position</param> /// <returns>The closest position (null if the line is further away than the specified /// max distance)</returns> internal override IPosition GetClosest(IPointGeometry p, ILength tol) { // Get the perpendicular point (or closest end) IPointGeometry s = Start; IPointGeometry e = End; double xp, yp; BasicGeom.GetPerpendicular(p.X, p.Y, s.X, s.Y, e.X, e.Y, out xp, out yp); // Ignore if point is too far away double t = tol.Meters; double dx = p.X - xp; if (dx > t) { return(null); } double dy = p.Y - yp; if (dy > t) { return(null); } double dsq = (dx * dx + dy * dy); if (dsq > t * t) { return(null); } return(new Position(xp, yp)); }
/// <summary> /// Initializes a new instance of the <see cref="MathTime"/> with the specified /// time, offset and mathematical operation. /// </summary> /// <param name="time">The MIDI time to add <paramref name="offset"/> to or /// subtract <paramref name="offset"/> from.</param> /// <param name="offset"><see cref="ILength"/> that should be added to or subtracted /// from <paramref name="time"/>.</param> /// <param name="operation">Mathematical operation to perform on <paramref name="time"/>.</param> /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception> /// <exception cref="ArgumentNullException"><paramref name="offset"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="operation"/> specified /// an invalid value.</exception> public MathTime(long time, ILength offset, MathOperation operation = MathOperation.Sum) : this(offset, operation) { ThrowIfTimeArgument.IsNegative(nameof(time), time); MidiTime = time; }
/// <summary> /// Loads all circular arcs from an NTX file. /// </summary> /// <param name="fileName">The name of the NTX file to read from</param> /// <param name="creator">The edit that's being used to perform the import</param> /// <returns>The loaded features</returns> internal List <ArcFeature> LoadArcs(string fileName, Operation creator) { Ntx.File file = new Ntx.File(); try { file.Open(fileName); List <ArcFeature> result = new List <ArcFeature>(1000); ILength tol = GetPointMatchTolerance(file); while (file.GetMore()) { if (file.DataType == (int)Ntx.DataType.Line && file.Line.IsCurve) { ArcFeature f = ImportArc(file.Line, creator, tol); if (f != null) { result.Add((ArcFeature)f); } } } return(result); } finally { file.Close(); } }
public IConstraints15ConstraintElement Create( IaIndexElement aIndexElement, IrIndexElement rIndexElement, Isk sk, ILength Length, IORday ORday, ITPz z) { IConstraints15ConstraintElement constraintElement = null; try { constraintElement = new Constraints15ConstraintElement( aIndexElement, rIndexElement, sk, Length, ORday, z); } catch (Exception exception) { this.Log.Error( exception.Message, exception); } return(constraintElement); }
public long ConvertFrom(ILength length, long time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfTimeArgument.IsNegative(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); var mathLength = length as MathLength; if (mathLength == null) { throw new ArgumentException($"Length is not an instance of the {nameof(MathLength)}.", nameof(length)); } var convertedLength1 = LengthConverter.ConvertFrom(mathLength.Length1, time, tempoMap); var endTime1 = time + convertedLength1; switch (mathLength.Operation) { case MathOperation.Sum: return(convertedLength1 + LengthConverter.ConvertFrom(mathLength.Length2, endTime1, tempoMap)); case MathOperation.Subtract: return(convertedLength1 - LengthConverter.ConvertFrom(mathLength.Length2, endTime1, tempoMap.Flip(endTime1))); } throw new NotImplementedException($"Conversion from the {nameof(MathLength)} with {mathLength.Operation} operation is not implemented."); }
/// <summary> /// Sets default step for step back and step forward actions of the builder. /// </summary> /// <param name="step">New default step.</param> /// <returns>The current <see cref="PatternBuilder"/>.</returns> /// <remarks> /// Setting default step is not an action and thus will not be stored in a pattern. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="step"/> is null.</exception> public PatternBuilder SetStep(ILength step) { ThrowIfArgument.IsNull(nameof(step), step); _step = step; return(this); }
/// <summary> /// /// </summary> /// <param name="abbreviation"></param> /// <param name="toBase"></param> /// <param name="fromBase"></param> /// <param name="surfaceArea"></param> /// <param name="squareRadius"></param> protected SolidAngleBase(string abbreviation, IUnitConversion toBase, IUnitConversion fromBase, IArea surfaceArea, ILength squareRadius) : base(abbreviation, toBase, fromBase, surfaceArea, squareRadius) { VerifyDimensions(); }
public IConstraints16ConstraintElement Create( IaIndexElement aIndexElement, IsIndexElement sIndexElement, Ip p, Irk rk, Idur dur, ILength Length, IP P, ITPx x, ITPz z) { IConstraints16ConstraintElement constraintElement = null; try { constraintElement = new Constraints16ConstraintElement( aIndexElement, sIndexElement, p, rk, dur, Length, P, x, z); } catch (Exception exception) { this.Log.Error( exception.Message, exception); } return(constraintElement); }
/// <summary> /// The perimeter of a polygon as a single array of positions. /// </summary> /// <param name="curvetol">Approximation tolerance for any circular arcs along /// the edge of the ring.</param> /// <param name="ring">The ring of interest that the <paramref name="edge"/> contains</param> /// <param name="edge">The dividers to consider</param> /// <returns></returns> internal static IPosition[] GetOutline(ILength curvetol, Ring ring, IDivider[] edge) { List <IPosition> pts = new List <IPosition>(1000); // When doing the 1st arc, we need to utilize the very first position bool isFirst = true; // Loop through each divider in the ring to create a list of // positions defining the polygon... foreach (IDivider d in edge) { // Skip divider lines if they have the same ring on both sides. This is // meant to exclude dividers that radiate out from islands. Note that // potential bridges towards the interior of polygons are expected to // be weeded out prior to call. if (d.Left == ring && d.Right == ring) { continue; } // See which way the positions should be arranged. bool reverse = (d.Right == ring ? false : true); // Get the geometric primitive for the divider LineGeometry line = d.LineGeometry; line.AppendPositions(pts, reverse, isFirst, curvetol); isFirst = false; } return(pts.ToArray()); }
/// <summary> /// Adds a note by the specified definition using specified velocity and length. /// </summary> /// <param name="noteDefinition">The definition of a note.</param> /// <param name="length">The length of a note.</param> /// <param name="velocity">The velocity of a note.</param> /// <returns>The current <see cref="PatternBuilder"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="noteDefinition"/> is null. -or- /// <paramref name="length"/> is null.</exception> public PatternBuilder Note(NoteDefinition noteDefinition, ILength length, SevenBitNumber velocity) { ThrowIfArgument.IsNull(nameof(noteDefinition), noteDefinition); ThrowIfArgument.IsNull(nameof(length), length); return(AddAction(new AddNoteAction(noteDefinition, velocity, length))); }
internal override void MouseMove(IPosition p) { // The following is pretty much the same as what the controller would do to // cover auto-select... // The ground tolerance is 1mm at the draw scale. ISpatialDisplay draw = ActiveDisplay; ILength tol = new Length(0.001 * draw.MapScale); // Just return if we previously selected something, and the // search point lies within tolerance. if (m_Line != null) { ILength dist = m_Line.Distance(p); if (dist.Meters < tol.Meters) { return; } // Ensure the previously select line gets un-highlighted m_Line = null; ErasePainting(); } // Ask the map to find the closest line (if any) ISpatialIndex index = CadastralMapModel.Current.Index; m_Line = (index.QueryClosest(p, tol, SpatialType.Line) as LineFeature); Highlight(m_Line); }
/// <summary> /// Adds a chord by the specified notes definitions using specified velocity and length. /// </summary> /// <param name="noteDefinitions">Definitions of notes that represent a chord.</param> /// <param name="length">The length of a chord.</param> /// <param name="velocity">The velocity of a chord.</param> /// <returns>The current <see cref="PatternBuilder"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="noteDefinitions"/> is null. -or- /// <paramref name="length"/> is null.</exception> public PatternBuilder Chord(IEnumerable <NoteDefinition> noteDefinitions, ILength length, SevenBitNumber velocity) { ThrowIfArgument.IsNull(nameof(noteDefinitions), noteDefinitions); ThrowIfArgument.IsNull(nameof(length), length); return(AddAction(new AddChordAction(noteDefinitions, velocity, length))); }
/// <summary> /// Adds a chord by the specified notes names using specified velocity and length, and default octave. /// </summary> /// <param name="noteNames">Names of notes that represent a chord.</param> /// <param name="length">The length of a chord.</param> /// <param name="velocity">The velocity of a chord.</param> /// <returns>The current <see cref="PatternBuilder"/>.</returns> /// <remarks> /// To set default octave use <see cref="SetOctave(int)"/> method. By default the octave number is 4. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="noteNames"/> is null. -or- /// <paramref name="length"/> is null.</exception> public PatternBuilder Chord(IEnumerable <NoteName> noteNames, ILength length, SevenBitNumber velocity) { ThrowIfArgument.IsNull(nameof(noteNames), noteNames); ThrowIfArgument.IsNull(nameof(length), length); return(Chord(noteNames.Select(n => _octave.GetNoteDefinition(n)), length, velocity)); }
/// <summary> /// The length of this line, up to a specific position. /// </summary> /// <param name="g">The geometry for the line</param> /// <param name="asFarAs">Optional position on the line that the distance should /// be calculated to (null means return the length for the complete line). If this /// position doesn't actually coincide with the line, you'll get the length of the /// complete line.</param> /// <param name="tol">The tolerance for matching <c>asFarAs</c> with the line. Ignored /// if <c>asFarAs</c> is null.</param> /// <returns>The length of the specified line geometry</returns> public static ILength GetLength(IMultiSegmentGeometry g, IPosition asFarAs, ILength tol) { IPosition[] line = g.Data; double tsq = (tol == null ? 0.0 : (tol.Meters * tol.Meters)); double tx = (asFarAs == null ? 0.0 : asFarAs.X); double ty = (asFarAs == null ? 0.0 : asFarAs.Y); double x1 = line[0].X; double y1 = line[0].Y; double length = 0.0; // Total length so far bool finish = false; // True to break early for (int i = 1; i < line.Length && !finish; i++) { double x2 = line[i].X; double y2 = line[i].Y; if (asFarAs != null && IsCoincident(tx, ty, x1, y1, x2, y2, tsq)) { x2 = tx; y2 = ty; finish = true; } double dx = x2 - x1; double dy = y2 - y1; length += Math.Sqrt(dx * dx + dy * dy); x1 = x2; y1 = y2; } return(new Length(length)); }
/// <summary> /// Sets default note length that will be used by next actions of the builder. /// </summary> /// <param name="length">New default note length.</param> /// <returns>The current <see cref="PatternBuilder"/>.</returns> /// <remarks> /// Setting default note length is not an action and thus will not be stored in a pattern. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null.</exception> public PatternBuilder SetNoteLength(ILength length) { ThrowIfArgument.IsNull(nameof(length), length); _noteLength = length; return(this); }
public NoteInfo(SevenBitNumber noteNumber, ITime time, ILength length, SevenBitNumber velocity) { NoteNumber = noteNumber; Time = time; Length = length; Velocity = velocity; }
/// <summary> /// Initializes a new instance of the <see cref="MathTime"/> with the specified /// time, offset and mathematical operation. /// </summary> /// <param name="time">The <see cref="ITime"/> to add <paramref name="offset"/> to or /// subtract <paramref name="offset"/> from.</param> /// <param name="offset"><see cref="ILength"/> that should be added to or subtracted /// from <paramref name="time"/>.</param> /// <param name="operation">Mathematical operation to perform on <paramref name="time"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="time"/> is null. -or- /// <paramref name="offset"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="operation"/> specified /// an invalid value.</exception> public MathTime(ITime time, ILength offset, MathOperation operation = MathOperation.Sum) : this(offset, operation) { ThrowIfArgument.IsNull(nameof(time), time); Time = time; }
/// <summary> /// Generates an approximation of a circular arc. /// </summary> /// <param name="tol">The maximum chord-to-circumference distance.</param> /// <returns></returns> public static IPointGeometry[] GetApproximation(ICircularArcGeometry g, ILength tol) { // Get info about the circle the curve lies on. IPosition center = g.Circle.Center; double radius = g.Circle.Radius; // Determine the change in bearing which will satisfy the specified tolerance // (if no tolerance has been specified, arbitrarily use a tolerance of 1mm on the ground). double tolm = (tol.Meters > Double.Epsilon ? tol.Meters : 0.001); double dbear = Math.Acos((radius - tolm) / radius); IPointGeometry start = g.BC; IPointGeometry end = g.EC; bool iscw = g.IsClockwise; // Get the total angle subtended by the curve. Turn reft = new Turn(center, start); double totang = reft.GetAngleInRadians(end); // clockwise if (!iscw) { totang = MathConstants.PIMUL2 - totang; } // Figure out how many positions we'll generate int nv = (int)(totang / dbear); // truncate Debug.Assert(nv >= 0); // Handle special case of very short arc. if (nv == 0) { return new IPointGeometry[] { start, end } } ; // Sign the delta-bearing the right way. if (!iscw) { dbear = -dbear; } // Get the initial bearing to the first position along the curve. double curbear = reft.BearingInRadians + dbear; // Append positions along the length of the curve. List <IPointGeometry> result = new List <IPointGeometry>(nv); result.Add(start); for (int i = 0; i < nv; i++, curbear += dbear) { IPosition p = BasicGeom.Polar(center, curbear, radius); result.Add(PositionGeometry.Create(p)); } result.Add(end); return(result.ToArray()); }
/// <summary> /// Converts length from the specified length type to <see cref="long"/>. /// </summary> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as <see cref="long"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> public static long ConvertFrom(ILength length, ITime time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(ConvertFrom(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Creates a <c>DrawStyle</c> with a specific pen & fill color. /// </summary> /// <param name="c">The color for the pen & the fill</param> public DrawStyle(Color c) { m_Pen = new Pen(c); m_Fill = new Fill(c); m_Path = new GraphicsPath(); m_PointHeight = new Length(1.0); m_IsFixedStyle = false; }
/// <summary> /// Initializes a new instance of the <see cref="MathTime"/> with the specified /// offset and mathematical operation. /// </summary> /// <param name="offset"><see cref="ILength"/> that should be added to or subtracted /// from the specified time.</param> /// <param name="operation">Mathematical operation to perform on time.</param> /// <exception cref="ArgumentNullException"><paramref name="offset"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="operation"/> specified /// an invalid value.</exception> private MathTime(ILength offset, MathOperation operation = MathOperation.Sum) { ThrowIfArgument.IsNull(nameof(offset), offset); ThrowIfArgument.IsInvalidEnumValue(nameof(operation), operation); Offset = offset; Operation = operation; }
/// <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> /// Converts length from one length type to another one. /// </summary> /// <typeparam name="TLength">Type that will represent the length of an object.</typeparam> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as an instance of <typeparamref name="TLength"/>.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="NotSupportedException"><typeparamref name="TLength"/> is not supported.</exception> public static TLength ConvertTo <TLength>(ILength length, long time, TempoMap tempoMap) where TLength : ILength { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfTimeArgument.IsNegative(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(ConvertTo <TLength>(ConvertFrom(length, time, tempoMap), time, tempoMap)); }
/// <summary> /// Gets the position that is mid-way along this arc. /// </summary> /// <returns>The position that is mid-way along this arc.</returns> internal IPosition GetMidPosition() { ILength arcLength = this.Length; ILength midLength = new Length(arcLength.Meters * 0.5); IPosition result; GetPosition(midLength, out result); return(result); }
/// <summary> /// Converts length from the specified length type to <see cref="long"/>. /// </summary> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as <see cref="long"/>.</returns> /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> public static long ConvertFrom(ILength length, long time, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfTimeArgument.IsNegative(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(LengthConverterFactory.GetConverter(length.GetType()) .ConvertFrom(length, time, tempoMap)); }
/// <summary> /// Converts length from one length type to another one. /// </summary> /// <typeparam name="TLength">Type that will represent the length of an object.</typeparam> /// <param name="length">Length to convert.</param> /// <param name="time">Start time of an object to convert length of.</param> /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param> /// <returns>Length as an instance of <typeparamref name="TLength"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or- /// <paramref name="time"/> is null. -or- <paramref name="tempoMap"/> is null.</exception> /// <exception cref="NotSupportedException"><typeparamref name="TLength"/> is not supported.</exception> public static TLength ConvertTo <TLength>(ILength length, ITime time, TempoMap tempoMap) where TLength : ILength { ThrowIfArgument.IsNull(nameof(length), length); ThrowIfArgument.IsNull(nameof(time), time); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(ConvertTo <TLength>(length, TimeConverter.ConvertFrom(time, tempoMap), tempoMap)); }
/// <summary> /// Constructor /// </summary> /// <param name="length">The length</param> public FormLength(ILength length) : this() { this.length = length; IAssociatedObject ao = length as IAssociatedObject; label = ao.Object as IObjectLabel; UpdateFormUI(); textBoxLength.Text = length.Length + ""; }
/// <summary> /// Initializes a new instance of the <see cref="MathTime"/> with the specified /// lengths and mathematical operation. /// </summary> /// <param name="length1">The <see cref="ILength"/> to add <paramref name="length2"/> to or /// subtract <paramref name="length2"/> from.</param> /// <param name="length2">The <see cref="ILength"/> to add to or subtract from <paramref name="length1"/>.</param> /// <param name="operation">Mathematical operation to perform on <paramref name="length1"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="length1"/> is null. -or- /// <paramref name="length2"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="operation"/> specified /// an invalid value.</exception> public MathLength(ILength length1, ILength length2, MathOperation operation = MathOperation.Sum) { ThrowIfArgument.IsNull(nameof(length1), length1); ThrowIfArgument.IsNull(nameof(length2), length2); ThrowIfArgument.IsInvalidEnumValue(nameof(operation), operation); Length1 = length1; Length2 = length2; Operation = operation; }
/// <summary> /// Creates a new <c>FindCirclesQuery</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="p">The search position.</param> /// <param name="tol">The search tolerance (expected to be greater than zero).</param> internal FindCirclesQuery(EditingIndex index, IPosition p, ILength tol) { m_Position = p; m_Tolerance = tol.Meters; m_Result = new List<Circle>(); // The query will actually involve a square window, not a circle. IWindow x = new Window(p, m_Tolerance * 2.0); index.FindCircles(x, OnQueryHit); }
/// <summary> /// Creates a new <c>FindCirclesQuery</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="p">The search position.</param> /// <param name="tol">The search tolerance (expected to be greater than zero).</param> internal FindCirclesQuery(EditingIndex index, IPosition p, ILength tol) { m_Position = p; m_Tolerance = tol.Meters; m_Result = new List <Circle>(); // The query will actually involve a square window, not a circle. IWindow x = new Window(p, m_Tolerance * 2.0); index.FindCircles(x, OnQueryHit); }
/// <summary> /// Attempts to locate the circle closest to a position of interest. /// </summary> /// <param name="p">The search position (on the circumference of the circle)</param> /// <param name="tol">The search tolerance</param> /// <returns>The circle closest to the search position (null if nothing found)</returns> internal Circle QueryClosestCircle(IPosition p, ILength tol) { ISpatialObject so = m_ExtraData.QueryClosest(p, tol, SpatialType.Line); if (so == null) { return(null); } Debug.Assert(so is Circle); return(so as Circle); }
/// <summary> /// Creates a new <c>FindClosestQuery</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="p">The search position.</param> /// <param name="radius">The search tolerance (expected to be greater than zero).</param> /// <param name="types">The type of objects to look for.</param> internal FindClosestQuery(ISpatialIndex index, IPosition p, ILength radius, SpatialType types) { if (types==0) throw new ArgumentNullException("Spatial type(s) not specified"); // If the user hasn't been specific, ensure we don't search for polygons! SpatialType useTypes = (types==SpatialType.All ? SpatialType.Feature : types); Debug.Assert((useTypes & SpatialType.Polygon)==0); // It's important to round off to the nearest micron. Otherwise you might not // get the desired results in situations where the search radius is zero. m_Position = PositionGeometry.Create(p); m_Radius = radius; m_Types = types; m_Result = null; m_Distance = m_Radius.Meters; // The query will actually involve a square window, not a circle. IWindow x = new Window(m_Position, radius.Meters * 2.0); index.QueryWindow(x, useTypes, OnQueryHit); }
internal override bool GetPosition(ILength dist, out IPosition pos) { return Make().GetPosition(dist, out pos); }
/// <summary> /// Gets the point on this line that is closest to a specified position. /// </summary> /// <param name="p">The position to search from.</param> /// <param name="tol">Maximum distance from line to the search position</param> /// <returns>The closest position (null if the line is further away than the specified /// max distance)</returns> internal override IPosition GetClosest(IPointGeometry p, ILength tol) { return Make().GetClosest(p, tol); }
/// <summary> /// Loads a list of positions with data for this line. /// </summary> /// <param name="positions">The list to append to</param> /// <param name="reverse">Should the data be appended in reverse order?</param> /// <param name="wantFirst">Should the first position be appended? (last if <paramref name="reverse"/> is true)</param> /// <param name="arcTol">Tolerance for approximating circular arcs (used only if this section /// is based on an instance of <see cref="ArcGeometry"/>)</param> internal override void AppendPositions(List<IPosition> positions, bool reverse, bool wantFirst, ILength arcTol) { Make().AppendPositions(positions, reverse, wantFirst, arcTol); }
private Feature ImportLine(ILength tol, Ntx.Line line, Operation creator) { // Circular arcs are handled elsewhere if (line.IsCurve) return null; IEntity what = GetEntityType(line, SpatialType.Line); PointGeometry[] pts = GetPositions(line); // Ignore zero-length lines if (HasZeroLength(pts)) return null; // Ensure point features exist at both ends of the line. PointFeature ps = EnsurePointExists(pts[0], tol, creator); PointFeature pe = EnsurePointExists(pts[pts.Length-1], tol, creator); // Force end positions to match pts[0] = ps.PointGeometry; pts[pts.Length-1] = pe.PointGeometry; // It's possible we've now produced a zero-length line if (Object.ReferenceEquals(ps, pe) && HasZeroLength(pts)) return null; // If we're dealing with a multi-segment, I have occasionally seen tiny glitches // at the end of the incoming lines (whether this is a real data problem, or an // imperfection in the import software is unknown). So double check now. // In the longer term, the import software should also check for more complex // issues, like missing intersections. In the meantime, I assume that incoming // topological data is generally clean. if (pts.Length > 2 && line.IsTopologicalArc) pts = CheckMultiSegmentEnds(pts); LineFeature result; InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); if (pts.Length==2) result = new LineFeature(creator, id, what, ps, pe); else result = new LineFeature(creator, id, what, ps, pe, pts); // The toological status of the incoming arc may override the status that the // constructor derived from the entity type result.SetTopology(line.IsTopologicalArc); return result; }
private PointFeature EnsurePointExists(PointGeometry p, ILength tol, Operation creator) { PointFeature result = (PointFeature)m_Index.QueryClosest(p, tol, SpatialType.Point); if (result==null) { IEntity e = creator.MapModel.DefaultPointType; InternalIdValue id = CadastralMapModel.Current.WorkingSession.AllocateNextId(); result = new PointFeature(creator, id, e, p); m_Index.Add(result); m_Result.Add(result); } return result; }
internal static IVarSizeValue CreateVarSizeValue(IVarPropType VarPropType, ILength Length, byte[] buffer, ref int pos) { var int16Value = (VarPropType as PtypInteger16).Value; CreateVarPropValue createFunc = null; if (CreateVarPropValueDic.TryGetValue(int16Value, out createFunc)) { IVarSizeValue varValueObj = createFunc(); varValueObj.ParseValue(buffer, ref pos, (Length as PTypInteger32).Value); return varValueObj; } else if ((int16Value & 0x8000) == 0x8000) { IVarSizeValue varValueObj = PTypStrWithCodePage.CreateVarPropValue(VarPropType); varValueObj.ParseValue(buffer, ref pos, (Length as PTypInteger32).Value); return varValueObj; } throw new ArgumentException(string.Format("fixedPropType [{0}] is invalid.", int16Value.ToString("X4"))); }
/// <summary> /// Gets the position that is a specific distance from the start of a circular arc. /// </summary> /// <param name="g">The geometry for the circular arc</param> /// <param name="distance">The distance from the start of the arc.</param> /// <param name="result">The position found</param> /// <returns>True if the distance is somewhere ON the arc. False if the distance /// was less than zero, or more than the arc length (in that case, the position /// found corresponds to the corresponding terminal point).</returns> public static bool GetPosition(ICircularArcGeometry g, ILength distance, out IPosition result) { // Allow 1 micron tolerance const double TOL = 0.000001; // Check for invalid distances. double d = distance.Meters; if (d<0.0) { result = g.BC; return false; } double clen = g.Length.Meters; // Arc length if (d>(clen+TOL)) { result = g.EC; return false; } // Check for limiting values (if you don't do this, minute // roundoff at the BC & EC can lead to spurious locations). // (although it's possible to use TINY here, use 1 micron // instead, since we can't represent position any better // than that). if (d<TOL) { result = g.BC; return true; } if (Math.Abs(d-clen)<TOL) { result = g.EC; return true; } // Get the bearing of the BC ICircleGeometry circle = g.Circle; IPosition c = circle.Center; double radius = circle.Radius; double bearing = BasicGeom.BearingInRadians(c, g.BC); // Add the angle that subtends the required distance (or // subtract if the curve goes anti-clockwise). if (g.IsClockwise) bearing += (d/radius); else bearing -= (d/radius); // Figure out the required point from the new bearing. result = BasicGeom.Polar(c, bearing, radius); return true; }
/// <summary> /// Locates circles close to a specific position. /// </summary> /// <param name="p">The search position.</param> /// <param name="tol">The search tolerance (expected to be greater than zero).</param> /// <returns>The result of the query (may be an empty list).</returns> internal List<Circle> QueryCircles(IPosition p, ILength tol) { return new FindCirclesQuery(this, p, tol).Result; }
/// <summary> /// Protected Constructor /// </summary> /// <param name="abbreviation"></param> /// <param name="toBase"></param> /// <param name="fromBase"></param> /// <param name="arc"></param> /// <param name="radius"></param> protected PlanarAngleBase(string abbreviation, IUnitConversion toBase, IUnitConversion fromBase, ILength arc, ILength radius) : base(abbreviation, toBase, fromBase, arc, radius) { }
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; }
/// <summary> /// /// </summary> /// <param name="squareLength"></param> protected AreaBase(ILength squareLength) : base(squareLength) { }
private SolidAngle(string abbreviation, IUnitConversion toBase, IUnitConversion fromBase, IArea surfaceArea, ILength squareRadius) : base(abbreviation, toBase, fromBase, surfaceArea, squareRadius) { }
/// <summary> /// Generates an approximation of a circular arc. /// </summary> /// <param name="tol">The maximum chord-to-circumference distance.</param> /// <returns></returns> public static IPointGeometry[] GetApproximation(ICircularArcGeometry g, ILength tol) { // Get info about the circle the curve lies on. IPosition center = g.Circle.Center; double radius = g.Circle.Radius; // Determine the change in bearing which will satisfy the specified tolerance // (if no tolerance has been specified, arbitrarily use a tolerance of 1mm on the ground). double tolm = (tol.Meters > Double.Epsilon ? tol.Meters : 0.001); double dbear = Math.Acos((radius-tolm)/radius); IPointGeometry start = g.BC; IPointGeometry end = g.EC; bool iscw = g.IsClockwise; // Get the total angle subtended by the curve. Turn reft = new Turn(center, start); double totang = reft.GetAngleInRadians(end); // clockwise if (!iscw) totang = MathConstants.PIMUL2 - totang; // Figure out how many positions we'll generate int nv = (int)(totang/dbear); // truncate Debug.Assert(nv>=0); // Handle special case of very short arc. if (nv==0) return new IPointGeometry[] { start, end }; // Sign the delta-bearing the right way. if (!iscw) dbear = -dbear; // Get the initial bearing to the first position along the curve. double curbear = reft.BearingInRadians + dbear; // Append positions along the length of the curve. List<IPointGeometry> result = new List<IPointGeometry>(nv); result.Add(start); for (int i=0; i<nv; i++, curbear+=dbear) { IPosition p = BasicGeom.Polar(center, curbear, radius); result.Add(PositionGeometry.Create(p)); } result.Add(end); return result.ToArray(); }
/// <summary> /// /// </summary> /// <param name="cubicLength"></param> protected VolumeBase(ILength cubicLength) : base(cubicLength) { }
private MassDensity(IMass mass, ILength cubicLength) : base(mass, cubicLength) { }
internal override bool GetPosition(ILength dist, out IPosition pos) { return LineSegmentGeometry.GetPosition(this, dist.Meters, out pos); }
public void ParsePropValue(byte[] buffer, ref int pos) { PropInfo = StreamUtil.CreatePropInfo(buffer, ref pos); Length = PTypInteger32.CreateLength(buffer, ref pos); VarSizeValue = StreamUtil.CreateVarSizeValue(VarPropType, Length, buffer, ref pos); }
/// <summary> /// Gets the position that is a specific distance from the start of this line. /// </summary> /// <param name="distance">The distance from the start of the line.</param> /// <param name="result">The position found</param> /// <returns>True if the distance is somewhere ON the line. False if the distance /// was less than zero, or more than the line length (in that case, the position /// found corresponds to the corresponding terminal point).</returns> public bool GetPosition(ILength distance, out IPosition result) { return GetPosition(this, distance, out result); }
private Circle EnsureCircleExists(PointFeature center, double radius, ILength tol, Operation creator) { // The index refers to the data loaded from the current NTX file. It holds only // information for points & circles, so we should only find circles at this stage. Position p = new Position(center.X, center.Y+radius); ISpatialObject so = m_Index.QueryClosest(p, tol, SpatialType.Line); if (so==null) { so = new Circle(center, radius); m_Index.Add(so); } Debug.Assert(so is Circle); return (Circle)so; }
/// <summary> /// Attempts to locate the circle closest to a position of interest. /// </summary> /// <param name="p">The search position (on the circumference of the circle)</param> /// <param name="tol">The search tolerance</param> /// <returns>The circle closest to the search position (null if nothing found)</returns> internal Circle QueryClosestCircle(IPosition p, ILength tol) { ISpatialObject so = m_ExtraData.QueryClosest(p, tol, SpatialType.Line); if (so==null) return null; Debug.Assert(so is Circle); return (so as Circle); }
/// <summary> /// Gets the point on this line that is closest to a specified position. /// </summary> /// <param name="p">The position to search from.</param> /// <param name="tol">Maximum distance from line to the search position</param> /// <returns>The closest position (null if the line is further away than the specified /// max distance)</returns> internal override IPosition GetClosest(IPointGeometry p, ILength tol) { // Get the perpendicular point (or closest end) IPointGeometry s = Start; IPointGeometry e = End; double xp, yp; BasicGeom.GetPerpendicular(p.X, p.Y, s.X, s.Y, e.X, e.Y, out xp, out yp); // Ignore if point is too far away double t = tol.Meters; double dx = p.X - xp; if (dx > t) return null; double dy = p.Y - yp; if (dy > t) return null; double dsq = (dx*dx + dy*dy); if (dsq > t*t) return null; return new Position(xp, yp); }
private Velocity(ILength length, ITime time) : base(length, time) { }
PointFeature GetArcEndPoint(PointGeometry g, ILength tol, Operation creator) { // Ensure we've got a point at the required position PointFeature pt = EnsurePointExists(g, tol, creator); // If it's not exactly coincident, we've picked up a previously loaded point // that happens to be within tolerance. If it's not already connected to any // lines, shift it to where we want it. if (!pt.IsCoincident(g)) { if (!pt.HasDependents) { m_Index.Remove(pt); PointFeature[] pts = pt.Node.Points; pt.SetNode(new Node(pts, g)); m_Index.Add(pt); } } return pt; }
/// <summary> /// /// </summary> /// <param name="length"></param> /// <param name="perSquareTime"></param> protected AccelerationBase(ILength length, ITime perSquareTime) : base(length, perSquareTime) { VerifyDimensions(); }
/// <summary> /// Loads a list of positions with data for this line. /// </summary> /// <param name="positions">The list to append to</param> /// <param name="reverse">Should the data be appended in reverse order?</param> /// <param name="wantFirst">Should the first position be appended? (last if <paramref name="reverse"/> is true)</param> /// <param name="arcTol">Tolerance for approximating circular arcs (not used)</param> internal override void AppendPositions(List<IPosition> positions, bool reverse, bool wantFirst, ILength arcTol) { if (reverse) { if (wantFirst) positions.Add(End); positions.Add(Start); } else { if (wantFirst) positions.Add(Start); positions.Add(End); } }