/// <summary> /// Builds a linestring into the graphics path, using minX, maxY, dx and dy for the transformations. /// </summary> internal static void BuildLineString(GraphicsPath path, IBasicLineString ls, double minX, double maxY, double dx, double dy) { IList <Coordinate> cs = ls.Coordinates; List <Point> points = new List <Point>(); Point previousPoint = new Point(); for (int iPoint = 0; iPoint < ls.NumPoints; iPoint++) { Coordinate c = cs[iPoint]; Point pt = new Point { X = Convert.ToInt32((c.X - minX) * dx), Y = Convert.ToInt32((maxY - c.Y) * dy) }; if (previousPoint.IsEmpty == false) { if (pt.X != previousPoint.X || pt.Y != previousPoint.Y) { points.Add(pt); } } else { points.Add(pt); } previousPoint = pt; } if (points.Count < 2) { return; } Point[] pointArray = points.ToArray(); path.StartFigure(); path.AddLines(pointArray); }
/// <summary> /// Converts a <c>LineString</c> to <LineString Text format, then /// appends it to the writer. /// </summary> /// <param name="lineString">The <c>LineString</c> to process.</param> /// <param name="level"></param> /// <param name="doIndent"></param> /// <param name="writer">The output writer to append to.</param> private void AppendLineStringText(IBasicLineString lineString, int level, bool doIndent, TextWriter writer) { if (lineString.Coordinates.Count == 0) { writer.Write("EMPTY"); } else { if (doIndent) { Indent(level, writer); } writer.Write("("); for (int i = 0; i < lineString.NumPoints; i++) { if (i > 0) { writer.Write(", "); if (i % 10 == 0) { Indent(level + 2, writer); } } AppendCoordinate(lineString.Coordinates[i], writer); } writer.Write(")"); } }
/// <summary> /// Clips a line string with an envelope. /// </summary> /// <param name="source">The line string to clip.</param> /// <param name="window">The clipping window.</param> /// <returns>The clipped coordinates.</returns> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The clipping window is null. /// </exception> public static IReadOnlyList <IReadOnlyList <Coordinate> > Clip(IBasicLineString source, Envelope window) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return(new LiangBarskyAlgorithm(source, window).Result); }
/// <summary> /// Determines whether a coordinate is inside a polygon. /// </summary> /// <param name="shell">The shell of the polygon.</param> /// <param name="holes">The holes of the polygon.</param> /// <param name="coordinate">The coordinate.</param> /// <param name="precisionModel">The precision model.</param> /// <returns><c>true</c> if the polygon contains <paramref name="coordinate" />; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The shell is null.</exception> /// <exception cref="System.ArgumentException">A hole is null.</exception> /// <remarks> /// This method might also result <c>true</c> for coordinates on the boundary of the polygon or the holes. /// </remarks> public static Boolean IsInsidePolygon(IBasicLineString shell, IEnumerable <IBasicLineString> holes, Coordinate coordinate, PrecisionModel precisionModel) { if (shell == null) { throw new ArgumentNullException("shell", "The shell is null."); } return(IsInsidePolygon(shell.Coordinates, holes != null ? holes.Select(hole => hole.Coordinates) : null, coordinate, precisionModel)); }
/// <summary> /// Clips a line string with an envelope. /// </summary> /// <param name="source">The line string to clip.</param> /// <param name="window">The clipping window.</param> /// <returns>The clipped coordinates.</returns> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The clipping window is null. /// </exception> public static IEnumerable <IList <Coordinate> > Clip(IBasicLineString source, Envelope window) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } return(new LiangBarskyAlgorithm(source.Coordinates, window).Result); }
/// <summary> /// Determines whether a coordinate is inside a polygon. /// </summary> /// <param name="shell">The shell of the polygon.</param> /// <param name="coordinate">The coordinate.</param> /// <param name="precisionModel">The precision model.</param> /// <returns><c>true</c> if the polygon contains <paramref name="coordinate"/>; otherwise, <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The shell is null.</exception> /// <remarks> /// This method might also result <c>true</c> for coordinates on the boundary of the polygon. /// </remarks> public static Boolean IsInsidePolygon(IBasicLineString shell, Coordinate coordinate, PrecisionModel precisionModel) { if (shell == null) { throw new ArgumentNullException("shell", "The shell is null."); } return(IsInsidePolygon(shell.Coordinates, null, coordinate, precisionModel)); }
/// <summary> /// Simplifies the specified line string. /// </summary> /// <param name="source">The line string.</param> /// <param name="delta">The tolerance.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The simplified line string.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">The delta is less than or equal to 0.</exception> public static IBasicLineString Simplify(IBasicLineString source, Double delta, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException(nameof(source)); } DouglasPeuckerAlgorithm algorithm = new DouglasPeuckerAlgorithm(source, delta, precisionModel); algorithm.Compute(); return(new BasicProxyLineString(algorithm.Result)); }
/// <summary> /// Initializes a new instance of the <see cref="ShamosHoeyAlgorithm" /> class. /// </summary> /// <param name="source">The line string.</param> /// <param name="precisionModel">The precision model.</param> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public ShamosHoeyAlgorithm(IBasicLineString source, PrecisionModel precisionModel = null) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } PrecisionModel = precisionModel ?? PrecisionModel.Default; _eventQueue = new PresortedEventQueue(source.Coordinates); _sweepLine = new SweepLine(source.Coordinates, precisionModel); _hasResult = false; }
/// <summary> /// Initializes a new instance of the <see cref="BentleyOttmannAlgorithm" /> class. /// </summary> /// <param name="source">The line string.</param> /// <param name="precisionModel">The precision model.</param> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public BentleyOttmannAlgorithm(IBasicLineString source, PrecisionModel precisionModel = null) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } _source = source.Coordinates; PrecisionModel = precisionModel ?? PrecisionModel.Default; _eventQueue = new EventQueue(source.Coordinates); _sweepLine = new SweepLine(source.Coordinates, PrecisionModel); _hasResult = false; }
/// <summary> /// Computes the distance between the specified geometries. /// </summary> /// <param name="first">The first line string.</param> /// <param name="second">The second line string.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The distance between the specified geometries.</returns> /// <exception cref="System.ArgumentNullException"> /// The first line string is null. /// or /// The second line string is null. /// </exception> public static Double Distance(IBasicLineString first, IBasicLineString second, PrecisionModel precisionModel) { if (first == null) { throw new ArgumentNullException(nameof(first)); } if (second == null) { throw new ArgumentNullException(nameof(second)); } return(new GeometryDistanceAlgorithm(first, second, precisionModel).Result); }
/// <summary> /// Computes the distance between the specified geometries. /// </summary> /// <param name="point">The point.</param> /// <param name="lineString">The line string.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The distance between the specified geometries.</returns> /// <exception cref="System.ArgumentNullException"> /// The point is null. /// or /// The line string is null. /// </exception> public static Double Distance(IBasicPoint point, IBasicLineString lineString, PrecisionModel precisionModel) { if (point == null) { throw new ArgumentNullException(nameof(point)); } if (lineString == null) { throw new ArgumentNullException(nameof(lineString)); } return(new GeometryDistanceAlgorithm(new[] { point.Coordinate }, lineString, precisionModel).Result); }
/// <summary> /// Constructor /// </summary> /// <param name="lineString"> /// The points of the linestring, or <c>null</c> /// to create the empty point. Consecutive points may not be equal. /// </param> /// <param name="factory"></param> public LineString(IBasicLineString lineString, IGeometryFactory factory) : base(factory) { if (lineString.Coordinates == null) { _points = new Coordinate[] { } } ; if (lineString.NumPoints == 1) { throw new ArgumentException("point array must contain 0 or >1 elements"); } _points = lineString.Coordinates; }
/// <summary> /// Creates a new topologically complete LineString from a LineStringBase /// </summary> /// <param name="lineStringBase"></param> public LineString(IBasicLineString lineStringBase) : base(DefaultFactory) { if (lineStringBase.NumPoints == 0) { _points = new Coordinate[] { } } ; if (lineStringBase.NumPoints == 1) { throw new ArgumentException("point array must contain 0 or > 1 elements"); } _points = lineStringBase.Coordinates; }
private void SetShell(IBasicLineString basicShell) { if (basicShell == null) { _shell = null; return; } ILinearRing ring = basicShell as ILinearRing; if (ring == null) { _shell = new LinearRing(basicShell); } }
/// <summary> /// Simplifies the specified line string. /// </summary> /// <param name="source">The line string.</param> /// <param name="delta">The tolerance.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The simplified line string.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">The delta is less than or equal to 0.</exception> public static IBasicLineString Simplify(IBasicLineString source, Double delta, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Coordinates == null) { return(null); } DouglasPeuckerAlgorithm algorithm = new DouglasPeuckerAlgorithm(source.Coordinates, delta, precisionModel); algorithm.Compute(); return(new BasicLineString(algorithm.Result)); }
/// <summary> /// If the input geometry is a singular basic geometry, this will become a collection of 1 geometry. /// If the input geometry is a multi- basic geometry, this will simply ensure that each member /// is upgraded to a full geometry. /// </summary> /// <param name="inGeometry"></param> /// <param name="inFactory"></param> public GeometryCollection(IBasicGeometry inGeometry, IGeometryFactory inFactory) : base(inFactory) { if (inGeometry == null) { _geometries = new IGeometry[] { }; return; } IBasicPolygon pg = inGeometry.GetBasicGeometryN(0) as IBasicPolygon; if (pg != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { pg = inGeometry.GetBasicGeometryN(iGeom) as IBasicPolygon; _geometries[iGeom] = new Polygon(pg); } return; } IBasicPoint pt = inGeometry.GetBasicGeometryN(0) as IBasicPoint; if (pt != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { pt = inGeometry.GetBasicGeometryN(iGeom) as IBasicPoint; _geometries[iGeom] = new Point(pt); } return; } IBasicLineString ls = inGeometry.GetBasicGeometryN(0) as IBasicLineString; if (ls != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { ls = inGeometry.GetBasicGeometryN(iGeom) as IBasicLineString; _geometries[iGeom] = new LineString(ls); } return; } }
/// <summary> /// Initializes a new instance of the <see cref="MinkowskiSumAlgorithm"/> class. /// </summary> /// <param name="source">The source.</param> /// <param name="buffer">The buffer.</param> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentNullException">The buffer is null.</exception> /// <exception cref="System.ArgumentException">The orientation of the source is not suitable.</exception> /// <exception cref="System.ArgumentException">The orientation of the buffer is not suitable.</exception> public MinkowskiSumAlgorithm(IBasicLineString source, IBasicPolygon buffer) { if (source == null) { throw new ArgumentNullException(nameof(source), "The source is null."); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer), "The buffer is null."); } _sourceShellCoordinates = new List <Coordinate>(); foreach (Coordinate coordinate in source.Coordinates) { _sourceShellCoordinates.Add(coordinate); } if (_sourceShellCoordinates.Count > 1 && _sourceShellCoordinates[_sourceShellCoordinates.Count - 1] != _sourceShellCoordinates[0]) { _sourceShellCoordinates.Add(_sourceShellCoordinates[0]); } if (_sourceShellCoordinates.Count > 3 && PolygonAlgorithms.Orientation(_sourceShellCoordinates) != Orientation.CounterClockwise) { throw new ArgumentException("The orientation of the source is not suitable.", nameof(source)); } _bufferCoordinates = new List <Coordinate>(); foreach (Coordinate coordinate in buffer.Shell.Coordinates) { _bufferCoordinates.Add(coordinate); } if (PolygonAlgorithms.Orientation(_bufferCoordinates) != Orientation.CounterClockwise) { throw new ArgumentException("The orientation of the buffer is not suitable.", nameof(buffer)); } _hasResult = false; }
/// <summary> /// Compares two <see cref="IBasicLineString" /> instances and returns a value indicating whether one is less than, equal to, or greater than the other. /// </summary> /// <param name="x">The first <see cref="IBasicLineString" /> to compare.</param> /// <param name="y">The second <see cref="IBasicLineString" /> to compare.</param> /// <returns>A signed integer that indicates the relative values of <paramref name="x" /> and <paramref name="y" />.</returns> /// <exception cref="System.ArgumentNullException"> /// The x argument is null. /// or /// The y argument is null. /// </exception> public Int32 Compare(IBasicLineString x, IBasicLineString y) { if (x == null) { throw new ArgumentNullException("x", "The x argument is null."); } if (y == null) { throw new ArgumentNullException("y", "The y argument is null."); } if (x == y) { return(0); } Int32 index = 0; // look for the first different coordinate in the linestring while (index < x.Count && index < y.Count) { Int32 comparison = _comparer.Compare(x.GetCoordinate(index), y.GetCoordinate(index)); if (comparison != 0) { return(comparison); } index++; } // check whether there are additional coordinates in either linestring if (index < x.Count) { return(1); } if (index < y.Count) { return(-1); } return(0); }
/// <summary> /// Computes the distance between the specified geometries. /// </summary> /// <param name="lineString">The line string.</param> /// <param name="polygon">The polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The distance between the specified geometries.</returns> /// <exception cref="System.ArgumentNullException"> /// The line string is null. /// or /// The polygon is null. /// </exception> public static Double Distance(IBasicLineString lineString, IBasicPolygon polygon, PrecisionModel precisionModel) { if (lineString == null) { throw new ArgumentNullException(nameof(lineString)); } if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } if (WindingNumberAlgorithm.InExterior(polygon, lineString[0])) { return(0); } if (polygon.HoleCount == 0) { return(Distance(lineString, polygon.Shell, precisionModel)); } return(Math.Min(Distance(lineString, polygon.Shell, precisionModel), polygon.Holes.Min(hole => Distance(lineString, hole, precisionModel)))); }
/// <summary> /// Draws a LineString. /// </summary> /// <param name="g"></param> /// <param name="p"></param> /// <param name="pens"></param> /// <param name="bls"></param> internal static void DrawLineString(Graphics g, IProj p, List <Pen> pens, IBasicLineString bls) { // Even if an entire multi-linestring is in view, entire parts may be outside the view if (bls.Envelope.Intersects(p.GeographicExtents.ToEnvelope()) == false) { return; } // get the coordinates once and cache them, because some data types have to create the array. IList <Coordinate> clist = bls.Coordinates; int count = clist.Count; Point[] points = new Point[count]; for (int i = 0; i < count; i++) { points[i] = p.ProjToPixel(clist[i]); } foreach (Pen currentPen in pens) { g.DrawLines(currentPen, points); } }
/// <summary> /// Creates a <c>MultiLineString</c> using the given <c>LineStrings</c>; a null or empty /// array will create an empty MultiLineString. /// </summary> /// <param name="lineStrings">LineStrings, each of which may be empty but not null-</param> public virtual IMultiLineString CreateMultiLineString(IBasicLineString[] lineStrings) { if (lineStrings == null) { return new MultiLineString(); } int count = lineStrings.Length; LineString[] ls = new LineString[count]; for (int i = 0; i < count; i++) { ls[i] = new LineString(lineStrings[i]); } MultiLineString temp = new MultiLineString(ls); return temp; }
/// <summary> /// Constructor /// </summary> /// <param name="lineString"> /// The points of the linestring, or <c>null</c> /// to create the empty point. Consecutive points may not be equal. /// </param> /// <param name="factory"></param> public LineString(IBasicLineString lineString, IGeometryFactory factory) : this(lineString.Coordinates, factory) { }
/// <summary> /// Creates a new topologically complete LineString from a LineStringBase /// </summary> /// <param name="lineStringBase"></param> public LineString(IBasicLineString lineStringBase) : this(lineStringBase.Coordinates, DefaultFactory) { }
/// <summary> /// Converts a <c>LineString</c> to <LineString Tagged Text /// format, then appends it to the writer. /// </summary> /// <param name="lineString">The <c>LineString</c> to process.</param> /// <param name="level"></param> /// <param name="writer">The output writer to append to.</param> private void AppendLineStringTaggedText(IBasicLineString lineString, int level, TextWriter writer) { writer.Write("LINESTRING "); AppendLineStringText(lineString, level, false, writer); }
/// <summary> /// Converts a <c>LineString</c> to <LineString Text format, then /// appends it to the writer. /// </summary> /// <param name="lineString">The <c>LineString</c> to process.</param> /// <param name="level"></param> /// <param name="doIndent"></param> /// <param name="writer">The output writer to append to.</param> private void AppendLineStringText(IBasicLineString lineString, int level, bool doIndent, TextWriter writer) { if (lineString.Coordinates.Count == 0) writer.Write("EMPTY"); else { if (doIndent) Indent(level, writer); writer.Write("("); for (int i = 0; i < lineString.NumPoints; i++) { if (i > 0) { writer.Write(", "); if (i % 10 == 0) Indent(level + 2, writer); } AppendCoordinate(lineString.Coordinates[i], writer); } writer.Write(")"); } }
/// <summary> /// Builds a linestring into the graphics path, using minX, maxY, dx and dy for the transformations. /// </summary> /// <param name="path"></param> /// <param name="ls"></param> /// <param name="minX"></param> /// <param name="maxY"></param> /// <param name="dx"></param> /// <param name="dy"></param> internal static void BuildLineString(GraphicsPath path, IBasicLineString ls, double minX, double maxY, double dx, double dy) { IList<Coordinate> cs = ls.Coordinates; List<Point> points = new List<Point>(); Point previousPoint = new Point(); for (int iPoint = 0; iPoint < ls.NumPoints; iPoint++) { Coordinate c = cs[iPoint]; Point pt = new Point { X = Convert.ToInt32((c.X - minX) * dx), Y = Convert.ToInt32((maxY - c.Y) * dy) }; if (previousPoint.IsEmpty == false) { if (pt.X != previousPoint.X || pt.Y != previousPoint.Y) { points.Add(pt); } } else { points.Add(pt); } previousPoint = pt; } if (points.Count < 2) return; Point[] pointArray = points.ToArray(); path.StartFigure(); path.AddLines(pointArray); }
/// <summary> /// Draws a LineString. /// </summary> /// <param name="g"></param> /// <param name="p"></param> /// <param name="pens"></param> /// <param name="bls"></param> internal static void DrawLineString(Graphics g, IProj p, List<Pen> pens, IBasicLineString bls) { // Even if an entire multi-linestring is in view, entire parts may be outside the view if (bls.Envelope.Intersects(p.GeographicExtents.ToEnvelope()) == false) return; // get the coordinates once and cache them, because some data types have to create the array. IList<Coordinate> clist = bls.Coordinates; int count = clist.Count; Point[] points = new Point[count]; for (int i = 0; i < count; i++) { points[i] = p.ProjToPixel(clist[i]); } foreach (Pen currentPen in pens) { g.DrawLines(currentPen, points); } }
/// <summary> /// Constructs a <c>MultiLineString</c>. /// </summary> /// <param name="lineStrings"> /// The <c>LineString</c>s for this <c>MultiLineString</c>, /// or <c>null</c> or an empty array to create the empty /// point. Elements may be empty <c>LineString</c>s, /// but not <c>null</c>s. /// </param> /// <remarks> /// For create this <see cref="Geometry"/> is used a standard <see cref="GeometryFactory"/> /// with <see cref="PrecisionModel" /> <c> == </c> <see cref="PrecisionModels.Floating"/>. /// </remarks> public MultiLineString(IBasicLineString[] lineStrings) : this(lineStrings, DefaultFactory) { }
/// <summary> /// Creates a new topologically complete LineString from a LineStringBase /// </summary> /// <param name="lineStringBase"></param> public LineString(IBasicLineString lineStringBase) : base(DefaultFactory) { if (lineStringBase.NumPoints == 0) _points = new Coordinate[] { }; if (lineStringBase.NumPoints == 1) throw new ArgumentException("point array must contain 0 or > 1 elements"); _points = lineStringBase.Coordinates; }
/// <summary> /// Saves the file to a new location /// </summary> /// <param name="fileName">The fileName to save</param> /// <param name="overwrite">Boolean that specifies whether or not to overwrite the existing file</param> public override void SaveAs(string fileName, bool overwrite) { if (IndexMode) { SaveAsIndexed(fileName, overwrite); return; } Filename = fileName; string dir = Path.GetDirectoryName(Path.GetFullPath(fileName)); if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (File.Exists(fileName)) { if (fileName != Filename && overwrite == false) { throw new IOException("File exists."); } File.Delete(fileName); string shx = Path.ChangeExtension(fileName, ".shx"); if (File.Exists(shx)) { File.Delete(shx); } } InvalidateEnvelope(); if (CoordinateType == CoordinateType.Regular) { Header.ShapeType = ShapeType.Polygon; } if (CoordinateType == CoordinateType.M) { Header.ShapeType = ShapeType.PolygonM; } if (CoordinateType == CoordinateType.Z) { Header.ShapeType = ShapeType.PolygonZ; } // Set ShapeType before setting extent. Header.SetExtent(Extent); Header.ShxLength = Features.Count * 4 + 50; Header.SaveAs(fileName); BufferedBinaryWriter bbWriter = new BufferedBinaryWriter(fileName); BufferedBinaryWriter indexWriter = new BufferedBinaryWriter(Header.ShxFilename); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (IFeature f in Features) { List <int> parts = new List <int>(); offset += contentLength; // adding the previous content length from each loop calculates the word offset List <Coordinate> points = new List <Coordinate>(); contentLength = 22; for (int iPart = 0; iPart < f.NumGeometries; iPart++) { parts.Add(points.Count); IBasicPolygon pg = f.GetBasicGeometryN(iPart) as IBasicPolygon; if (pg == null) { continue; } IBasicLineString bl = pg.Shell; IList <Coordinate> coords = bl.Coordinates; if (CgAlgorithms.IsCounterClockwise(coords)) { // Exterior rings need to be clockwise coords.Reverse(); } foreach (Coordinate coord in coords) { points.Add(coord); } foreach (IBasicLineString hole in pg.Holes) { parts.Add(points.Count); IList <Coordinate> holeCoords = hole.Coordinates; if (CgAlgorithms.IsCounterClockwise(holeCoords) == false) { // Interior rings need to be counter-clockwise holeCoords.Reverse(); } foreach (Coordinate coord in holeCoords) { points.Add(coord); } } } contentLength += 2 * parts.Count; if (Header.ShapeType == ShapeType.Polygon) { contentLength += points.Count * 8; } if (Header.ShapeType == ShapeType.PolygonM) { contentLength += 8; // mmin mmax contentLength += points.Count * 12; // x, y, m } if (Header.ShapeType == ShapeType.PolygonZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += points.Count * 16; // x, y, m, z } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- indexWriter.Write(offset, false); // Byte 0 Offset Integer 1 Big indexWriter.Write(contentLength, false); // Byte 4 Content Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- bbWriter.Write(fid + 1, false); // Byte 0 Record Number Integer 1 Big bbWriter.Write(contentLength, false); // Byte 4 Content Length Integer 1 Big bbWriter.Write((int)Header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (Header.ShapeType == ShapeType.NullShape) { continue; } bbWriter.Write(f.Envelope.Minimum.X); // Byte 12 Xmin Double 1 Little bbWriter.Write(f.Envelope.Minimum.Y); // Byte 20 Ymin Double 1 Little bbWriter.Write(f.Envelope.Maximum.X); // Byte 28 Xmax Double 1 Little bbWriter.Write(f.Envelope.Maximum.Y); // Byte 36 Ymax Double 1 Little bbWriter.Write(parts.Count); // Byte 44 NumParts Integer 1 Little bbWriter.Write(points.Count); // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little foreach (int iPart in parts) { bbWriter.Write(iPart); } double[] xyVals = new double[points.Count * 2]; int i = 0; // Byte X Points Point NumPoints Little foreach (Coordinate coord in points) { xyVals[i * 2] = coord.X; xyVals[i * 2 + 1] = coord.Y; i++; } bbWriter.Write(xyVals); if (Header.ShapeType == ShapeType.PolygonZ) { bbWriter.Write(f.Envelope.Minimum.Z); bbWriter.Write(f.Envelope.Maximum.Z); double[] zVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; i++) { zVals[ipoint] = points[ipoint].Z; ipoint++; } bbWriter.Write(zVals); } if (Header.ShapeType == ShapeType.PolygonM || Header.ShapeType == ShapeType.PolygonZ) { if (f.Envelope == null) { bbWriter.Write(0.0); bbWriter.Write(0.0); } else { bbWriter.Write(f.Envelope.Minimum.M); bbWriter.Write(f.Envelope.Maximum.M); } double[] mVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; i++) { mVals[ipoint] = points[ipoint].M; ipoint++; } bbWriter.Write(mVals); } fid++; offset += 4; // header bytes } bbWriter.Close(); indexWriter.Close(); offset += contentLength; //offset += 4; WriteFileLength(fileName, offset); WriteFileLength(Header.ShxFilename, 50 + fid * 4); UpdateAttributes(); SaveProjection(); }
/// <summary> /// Constructor /// </summary> /// <param name="linestringbase"></param> public LinearRing(IBasicLineString linestringbase) : base(linestringbase) { }
/// <summary> /// Computes the buffer of the source geometry. /// </summary> /// <param name="source">The source.</param> /// <param name="radius">The radius of the circle.</param> /// <param name="numberOfPoints">The number of points.</param> /// <returns>The result polygon.</returns> public static IBasicPolygon Buffer(IBasicLineString source, Double radius, Int32 numberOfPoints) { return(new MinkowskiSumAlgorithm(source, new BasicPolygon(CreateCircle(radius, numberOfPoints))).Result); }
/// <summary> /// Computes the distance between the specified geometries. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="lineString">The line string.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The distance between the specified geometries.</returns> /// <exception cref="System.ArgumentNullException"> /// The polygon is null. /// or /// The line string is null. /// </exception> public static Double Distance(IBasicPolygon polygon, IBasicLineString lineString, PrecisionModel precisionModel) { return(Distance(lineString, polygon, precisionModel)); }
/// <summary> /// Saves the file to a new location /// </summary> /// <param name="fileName">The fileName to save</param> /// <param name="overwrite">Boolean that specifies whether or not to overwrite the existing file</param> public override void SaveAs(string fileName, bool overwrite) { EnsureValidFileToSave(fileName, overwrite); Filename = fileName; // Set ShapeType before setting header. if (CoordinateType == CoordinateType.Regular) { Header.ShapeType = ShapeType.PolyLine; } if (CoordinateType == CoordinateType.M) { Header.ShapeType = ShapeType.PolyLineM; } if (CoordinateType == CoordinateType.Z) { Header.ShapeType = ShapeType.PolyLineZ; } HeaderSaveAs(fileName); if (IndexMode) { SaveAsIndexed(fileName); return; } var bbWriter = new BufferedBinaryWriter(fileName); var indexWriter = new BufferedBinaryWriter(Header.ShxFilename); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (IFeature f in Features) { List <int> parts = new List <int>(); offset += contentLength; // adding the previous content length from each loop calculates the word offset List <Coordinate> points = new List <Coordinate>(); contentLength = 22; for (int iPart = 0; iPart < f.NumGeometries; iPart++) { parts.Add(points.Count); IBasicLineString bl = f.GetBasicGeometryN(iPart) as IBasicLineString; if (bl == null) { continue; } foreach (Coordinate coord in bl.Coordinates) { points.Add(coord); } } contentLength += 2 * parts.Count; if (Header.ShapeType == ShapeType.PolyLine) { contentLength += points.Count * 8; // x, y } if (Header.ShapeType == ShapeType.PolyLineM) { contentLength += 8; // mmin mmax contentLength += points.Count * 12; // x, y, m } if (Header.ShapeType == ShapeType.PolyLineZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += points.Count * 16; // x, y, z, m } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- indexWriter.Write(offset, false); // Byte 0 Offset Integer 1 Big indexWriter.Write(contentLength, false); // Byte 4 Content Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // ------------------------------------------------------- bbWriter.Write(fid + 1, false); // Byte 0 Record Number Integer 1 Big bbWriter.Write(contentLength, false); // Byte 4 Content Length Integer 1 Big bbWriter.Write((int)Header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (Header.ShapeType == ShapeType.NullShape) { continue; } IEnvelope env = f.Envelope ?? new Envelope(); bbWriter.Write(env.Minimum.X); // Byte 12 Xmin Double 1 Little bbWriter.Write(env.Minimum.Y); // Byte 20 Ymin Double 1 Little bbWriter.Write(env.Maximum.X); // Byte 28 Xmax Double 1 Little bbWriter.Write(env.Maximum.Y); // Byte 36 Ymax Double 1 Little bbWriter.Write(parts.Count); // Byte 44 NumParts Integer 1 Little bbWriter.Write(points.Count); // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little foreach (int iPart in parts) { bbWriter.Write(iPart); } double[] xyVals = new double[points.Count * 2]; for (int ipoint = 0; ipoint < points.Count; ipoint++) { double[] c = points[ipoint].ToArray(); xyVals[ipoint * 2] = c[0]; xyVals[ipoint * 2 + 1] = c[1]; } bbWriter.Write(xyVals); if (Header.ShapeType == ShapeType.PolyLineZ) { if (f.Envelope != null) { bbWriter.Write(f.Envelope.Minimum.Z); bbWriter.Write(f.Envelope.Maximum.Z); } double[] zVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; ipoint++) { zVals[ipoint] = points[ipoint].Z; } bbWriter.Write(zVals); } if (Header.ShapeType == ShapeType.PolyLineM || Header.ShapeType == ShapeType.PolyLineZ) { if (f.Envelope == null) { bbWriter.Write(0.0); bbWriter.Write(0.0); } else { bbWriter.Write(f.Envelope.Minimum.M); bbWriter.Write(f.Envelope.Maximum.M); } double[] mVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; ipoint++) { mVals[ipoint] = points[ipoint].M; } bbWriter.Write(mVals); } fid++; offset += 4; // header bytes } bbWriter.Close(); indexWriter.Close(); offset += contentLength; //offset += 4; WriteFileLength(Filename, offset); WriteFileLength(Header.ShxFilename, 50 + fid * 4); UpdateAttributes(); SaveProjection(); }
/// <summary> /// Computes the buffer of the source geometry. /// </summary> /// <param name="source">The source.</param> /// <param name="buffer">The buffer.</param> /// <returns>The result polygon.</returns> public static IBasicPolygon Buffer(IBasicLineString source, IBasicPolygon buffer) { return(new MinkowskiSumAlgorithm(source, buffer).Result); }
/// <summary> /// Constructs a <c>MultiLineString</c>. /// </summary> /// <param name="lineStrings"> /// The <c>LineString</c>s for this <c>MultiLineString</c>, /// or <c>null</c> or an empty array to create the empty /// point. Elements may be empty <c>LineString</c>s, /// but not <c>null</c>s. /// </param> /// <param name="factory"></param> public MultiLineString(IBasicLineString[] lineStrings, IGeometryFactory factory) : base(lineStrings, factory) { }
/// <summary> /// Computes the intersection coordinates of a line string. /// </summary> /// <param name="source">The line string.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The list of intersection coordinates.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public static IList <Coordinate> Intersection(IBasicLineString source, PrecisionModel precisionModel = null) { return(new BentleyOttmannAlgorithm(source, precisionModel).Intersections); }
/// <summary> /// Constructor /// </summary> /// <param name="lineString"> /// The points of the linestring, or <c>null</c> /// to create the empty point. Consecutive points may not be equal. /// </param> /// <param name="factory"></param> public LineString(IBasicLineString lineString, IGeometryFactory factory) : base(factory) { if (lineString.Coordinates == null) _points = new Coordinate[] { }; if (lineString.NumPoints == 1) throw new ArgumentException("point array must contain 0 or >1 elements"); _points = lineString.Coordinates; }