/// <summary> /// Converts the GML element to linear ring. /// </summary> /// <param name="element">The GML element of the linear ring.</param> /// <param name="factory">The geometry factory.</param> /// <returns>The converted linear ring.</returns> private static ILinearRing ToLinearRing(XElement element, IGeometryFactory factory) { if (element.Elements() == null) { return(factory.CreateLinearRing()); } List <Coordinate> coordinates = new List <Coordinate>(); foreach (XElement innerElement in element.Elements()) { switch (innerElement.Name.LocalName) { case "coordinates": return(factory.CreateLinearRing(ConvertCoordinates(innerElement))); case "posList": return(factory.CreateLinearRing(ConvertPosList(innerElement, GetDimension(element, innerElement)))); case "coord": coordinates.Add(ConvertCoordinate(innerElement.Value.Split(','))); break; } } return(factory.CreateLinearRing(coordinates)); }
///<summary> /// Converts a flat path to a <see cref="IGeometry"/>. ///</summary> /// <param name="pathIt">The path iterator of the path to convert</param> /// <returns>A Geometry representing the path</returns> public IGeometry Read(WpfGeometry pathIt) { var pathPtSeq = ToCoordinates(pathIt); var polys = new List <IGeometry>(); var seqIndex = 0; while (seqIndex < pathPtSeq.Count) { // assume next seq is shell // TODO: test this var pts = pathPtSeq[seqIndex]; var shell = _geometryFactory.CreateLinearRing(pts); seqIndex++; var holes = new List <ILinearRing>(); Coordinate[] holePts; // add holes as long as rings are CCW while (seqIndex < pathPtSeq.Count && IsHole(holePts = pathPtSeq[seqIndex])) { var hole = _geometryFactory.CreateLinearRing(holePts); holes.Add(hole); seqIndex++; } var holeArray = holes.ToArray();//GeometryFactory.ToLinearRingArray(holes); polys.Add(_geometryFactory.CreatePolygon(shell, holeArray)); } return(_geometryFactory.BuildGeometry(polys)); }
public void write_polygon_with_hole() { Coordinate c0 = new Coordinate(10.1, 10); Coordinate c1 = new Coordinate(20.2, 20); Coordinate c2 = new Coordinate(30.3, 30); ILinearRing shell = Factory.CreateLinearRing(new[] { c0, c1, c2, c0 }); Coordinate h0 = new Coordinate(15, 15); Coordinate h1 = new Coordinate(17, 15); Coordinate h2 = new Coordinate(15, 17); ILinearRing hole = Factory.CreateLinearRing(new[] { h0, h1, h2, h0 }); IGeometry geometry = Factory.CreatePolygon(shell, new[] { hole }); AttributesTable attributes = new AttributesTable(); attributes.Add("prop0", "value0"); attributes.Add("prop1", "value1"); IFeature feature = new Feature(geometry, attributes); TopoJsonWriter writer = new TopoJsonWriter(); string actual = writer.Write(feature); Assert.That(actual, Is.Not.Null); Assert.That(actual, Is.Not.Empty); Console.WriteLine(actual); Assert.That(actual, Is.EqualTo(TopoWriterData.PolygonWithHole)); }
private static IGeometry ToSharpMapMultiPolygon(EsriShapeBuffer shapeBuffer) { if (shapeBuffer == null) { return(null); } var multiPartShapeBuffer = shapeBuffer as EsriMultiPartShapeBuffer; if (multiPartShapeBuffer == null) { Envelope box; return(FromShapeFilePolygon(shapeBuffer, out box)); } var hasZ = EsriShapeBuffer.HasZs(shapeBuffer.shapeType); IList <IPolygon> polygons = new List <IPolygon>(); //IPolygon poly = null; ILinearRing shell = null; IList <ILinearRing> holes = new List <ILinearRing>(); var offset = 0; for (var i = 0; i < multiPartShapeBuffer.NumParts; i++) { var vertices = new List <Coordinate>(multiPartShapeBuffer.Parts[i]); for (var j = 0; j < multiPartShapeBuffer.Parts[i]; j++) { var index = offset + j; var point = multiPartShapeBuffer.Points[index]; vertices.Add(hasZ ? new Coordinate(point.x, point.y, multiPartShapeBuffer.Zs[index]) : new Coordinate(point.x, point.y)); } var ring = geometryFactory.CreateLinearRing(vertices.ToArray()); if (shell == null || !ring.IsCCW()) { shell = ring; //poly = new Polygon(ring); //polygons.Add(poly); } else { holes.Add(ring); //poly.InteriorRings.Add(ring); } offset += multiPartShapeBuffer.Parts[i]; polygons.Add(geometryFactory.CreatePolygon(shell, holes.ToArray())); } if (polygons.Count == 1) { return(polygons[0]); } return(new MultiPolygon(polygons.ToArray())); }
public object ToLinearRing(CoordinateInfo[] coordinates) { if (coordinates.Length == 0) { return(LinearRing.Empty); } return(_geometryFactory.CreateLinearRing(coordinates.Select(MakeCoordinate).ToArray())); }
private IPolygon CreatePolygon(List <Coordinate[]> coordinates) { ILinearRing shell = _factory.CreateLinearRing(coordinates[0]); ILinearRing[] rings = new ILinearRing[coordinates.Count - 1]; for (int i = 1; i < coordinates.Count; i++) { rings[i - 1] = _factory.CreateLinearRing(coordinates[i]); } return(_factory.CreatePolygon(shell, rings)); }
private IPolygon CreatePolygon(List <Coordinate[]> list) { ILinearRing shell = _factory.CreateLinearRing(list[0]); List <ILinearRing> holes = new List <ILinearRing>(); for (int i = 1; i < list.Count; i++) { ILinearRing hole = _factory.CreateLinearRing(list[i]); holes.Add(hole); } return(_factory.CreatePolygon(shell, holes.ToArray())); }
private IGeometry ToGeoAPIPolygon(SpatialLite.Core.API.IPolygon geometry) { var exterior = _factory.CreateLinearRing(_clConverter.ToSequence(geometry.ExteriorRing)); var interior = new List <ILinearRing>(); foreach (var interiorRing in geometry.InteriorRings) { interior.Add(_factory.CreateLinearRing(_clConverter.ToSequence(interiorRing))); } return(_factory.CreatePolygon(exterior, interior.ToArray())); }
/// <summary> /// Transforms a <see cref="GeoAPI.Geometries.IPolygon"/>. /// </summary> /// <param name="p">Polygon to transform</param> /// <param name="from">Source Projection</param> /// <param name="to">Target Projection</param> /// <param name="toFactory">The factory to create geometries for <paramref name="to"/></param> /// <returns>Transformed Polygon</returns> public static IPolygon TransformPolygon(IPolygon p, ProjectionInfo from, ProjectionInfo to, IGeometryFactory toFactory) { var shell = toFactory.CreateLinearRing(TransformSequence(p.Shell.CoordinateSequence, from, to, toFactory.CoordinateSequenceFactory)); var holes = new ILinearRing[p.NumInteriorRings]; for (var i = 0; i < p.NumInteriorRings; i++) { holes[i] = toFactory.CreateLinearRing(TransformSequence(p.GetInteriorRingN(i).CoordinateSequence, from, to, toFactory.CoordinateSequenceFactory)); } return(toFactory.CreatePolygon(shell, holes)); }
private IPolygon CreatePolygon(int[][] data) { Coordinate[] cshell = InternalCreateLineString(data[0]); ILinearRing shell = _factory.CreateLinearRing(cshell); ILinearRing[] holes = new ILinearRing[data.Length - 1]; for (int i = 1; i < data.Length; i++) { Coordinate[] chole = InternalCreateLineString(data[i]); holes[i - 1] = _factory.CreateLinearRing(chole); } return(_factory.CreatePolygon(shell, holes)); }
/// <summary> /// Function to read a either a <see cref="IPolygon"/> or an <see cref="IMultiPolygon"/> from a ShapeFile stream using the specified <paramref name="reader"/>. /// </summary> /// <param name="reader">The reader to use</param> /// <param name="ordinates">The ordinates to read</param> /// <returns>The read polygonal geometry</returns> protected IGeometry ReadPolygon(BinaryReader reader, Ordinates ordinates) { /*var bbox = */ ReadBoundingBox(reader); // jump boundingbox var numParts = ReadNumParts(reader); var numPoints = ReadNumPoints(reader); var indexParts = ReadIndexParts(reader, numParts, numPoints); var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true); ReadCoordinates(reader, numPoints, indexParts, ordinates, buffer); return numParts == 1 ? _factory.CreatePolygon(_factory.CreateLinearRing(buffer.ToSequence()), null) : CreateSingleOrMultiPolygon(buffer); }
public void TestWritePolygon() { Coordinate[] coordinates = { new Coordinate(10, 10, 0), new Coordinate(10, 20, 0), new Coordinate(20, 20, 0), new Coordinate(20, 15, 0), new Coordinate(10, 10, 0) }; var linearRing = _factory.CreateLinearRing(coordinates); var polygon = _factory.CreatePolygon(linearRing, new LinearRing[] { }); Assert.AreEqual("POLYGON ((10 10, 10 20, 20 20, 20 15, 10 10))", _writer.Write(polygon)); }
public IGeometry Edit(IGeometry geometry, IGeometryFactory factory) { var linearRing = geometry as ILinearRing; if (linearRing != null) { return(factory.CreateLinearRing(EditSequence( (linearRing).CoordinateSequence, geometry))); } var lineString = geometry as ILineString; if (lineString != null) { return(factory.CreateLineString(EditSequence( (lineString).CoordinateSequence, geometry))); } var point = geometry as IPoint; if (point != null) { return(factory.CreatePoint(EditSequence( (point).CoordinateSequence, geometry))); } return(geometry); }
private ILineString ReprojectLineString(IGeometryFactory factory, ILineString line, ISpatialReference @from, ISpatialReference to, bool lineString = true) { return(lineString ? factory.CreateLineString(Reproject(line.CoordinateSequence, from, to)) : factory.CreateLinearRing(Reproject(line.CoordinateSequence, from, to))); }
public void linearring_should_be_written_as_wkb() { IGeometryFactory factory = GeometryFactory.Default; ILinearRing expected = factory.CreateLinearRing(new[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0) }); WKBWriter writer = new WKBWriter(); byte[] bytes = writer.Write(expected); Assert.That(bytes, Is.Not.Null); Assert.That(bytes, Is.Not.Empty); WKBReader reader = new WKBReader(); IGeometry actual = reader.Read(bytes); Assert.That(actual, Is.Not.Null); Assert.That(actual, Is.EqualTo(expected)); Assert.That(actual.OgcGeometryType, Is.EqualTo(expected.OgcGeometryType)); // WKBReader reads "ILinearRing" geometries as ILineString Assert.That(expected, Is.InstanceOf <ILinearRing>()); Assert.That(actual, Is.InstanceOf <ILineString>()); Assert.That(actual.GeometryType, Is.Not.EqualTo(expected.GeometryType)); }
public IGeometry Edit(IGeometry geometry, IGeometryFactory targetFactory) { var coordinates = geometry.Coordinates; if (geometry is LinearRing) { var edit = Edit(coordinates, geometry); return(targetFactory.CreateLinearRing(edit)); } if (geometry is LineString) { var edit = Edit(coordinates, geometry); return(targetFactory.CreateLineString(edit)); } if (geometry is Point) { var edit = Edit(coordinates, geometry); var coordinate = edit.Length > 0 ? edit[0] : null; return(targetFactory.CreatePoint(coordinate)); } return(geometry); }
private static GeoAPI.Geometries.IPolygon ReadPolygon(byte[] geom, ref int idx, bool isLittleEndian, IGeometryFactory factory) { double[] adfTuple = new double[2]; int nRings; nRings = ReadUInt32(geom, ref idx, isLittleEndian); if (nRings < 1 || nRings > Int32.MaxValue / (2 * 8)) { throw new ApplicationException("Currupt SpatialLite geom"); } List <GeoAPI.Geometries.ILineString> lineStrings = new List <GeoAPI.Geometries.ILineString>(); for (int i = 0; i < nRings; i++) { lineStrings.Add(ReadLineString(geom, ref idx, isLittleEndian, factory)); } List <GeoAPI.Geometries.ILinearRing> holes = null; var shell = factory.CreateLinearRing(lineStrings[0].Coordinates); if (lineStrings.Count > 1) { holes = new List <GeoAPI.Geometries.ILinearRing>(); for (int i = 1; i < lineStrings.Count; i++) { holes.Add(new NetTopologySuite.Geometries.LinearRing(lineStrings[i].Coordinates)); } } return(factory.CreatePolygon(shell, holes == null ? null : holes.ToArray())); }
public IEnumerable <IGeometry> CreateTestGeometries(int count, double minx, double miny, double maxx, double maxy) { double xrange = Math.Abs(maxx - minx); double yrange = Math.Abs(maxy - miny); for (int i = 0; i < count; i++) { double x1 = _rnd.NextDouble() * xrange + minx; double x2 = _rnd.NextDouble() * xrange + minx; double y1 = _rnd.NextDouble() * yrange + miny; double y2 = _rnd.NextDouble() * yrange + miny; double lrx = Math.Min(x1, x2); double lry = Math.Min(y1, y2); double trx = Math.Max(x1, x2); double @try = Math.Max(y1, y2); ICoordinate[] coords = new ICoordinate[] { new Coordinate(lrx, lry), new Coordinate(lrx, @try), new Coordinate(trx, @try), new Coordinate(trx, lry), new Coordinate(lrx, lry) }; yield return(_geometryFactory.CreatePolygon( _geometryFactory.CreateLinearRing( _geometryFactory.CoordinateSequenceFactory.Create(coords) ), new ILinearRing[] { })); } }
/// <summary> /// Gets the Voronoi cell around a site specified /// by the origin of a QuadEdge. /// </summary> /// <remarks> /// The userData of the polygon is set to be the <see cref="Coordinate" /> /// of the site. This allows attaching external /// data associated with the site to this cell polygon. /// </remarks> /// <param name="qe">a quadedge originating at the cell site</param> /// <param name="geomFact">a factory for building the polygon</param> /// <returns>a polygon indicating the cell extent</returns> public IPolygon GetVoronoiCellPolygon(QuadEdge qe, IGeometryFactory geomFact) { var cellPts = new List <Coordinate>(); QuadEdge startQE = qe; do { // Coordinate cc = circumcentre(qe); // use previously computed circumcentre Coordinate cc = qe.Rot.Orig.Coordinate; cellPts.Add(cc); // move to next triangle CW around vertex qe = qe.OPrev; } while (qe != startQE); var coordList = new CoordinateList(); coordList.AddAll(cellPts, false); coordList.CloseRing(); if (coordList.Count < 4) { Console.WriteLine(coordList); coordList.Add(coordList[coordList.Count - 1], true); } Coordinate[] pts = coordList.ToCoordinateArray(); IPolygon cellPoly = geomFact.CreatePolygon(geomFact.CreateLinearRing(pts), null); Vertex v = startQE.Orig; cellPoly.UserData = v.Coordinate; return(cellPoly); }
private static ILinearRing CreateEllipse(IGeometryFactory geometryFactory, ICoordinate center, double a, double b, bool reverse) { const double piHalf = Math.PI * 0.5d; const int segmentsPerQuadrant = 12; double step = piHalf / segmentsPerQuadrant; if (reverse) { step *= -1; } var coordFac = geometryFactory.CoordinateFactory; var coords = new ICoordinate[4 * segmentsPerQuadrant + 1]; var angle = 0d; for (var i = 0; i < 4 * segmentsPerQuadrant; i++) { coords[i] = coordFac.Create(center[Ordinates.X] + Math.Cos(angle) * a, center[Ordinates.Y] + Math.Sin(angle) * b); angle += step; } coords[coords.Length - 1] = (ICoordinate)coords[0].Clone(); return(geometryFactory.CreateLinearRing(coords)); }
/// <summary> /// Creates a <c>LinearRing</c> using the next token in the stream. /// </summary> /// <param name="tokens"> /// Tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a <LineString Text. /// </param> /// <param name="factory"> </param> /// <returns>A <c>LinearRing</c> specified by the next /// token in the stream.</returns> private ILinearRing ReadLinearRingText(IEnumerator <Token> tokens, IGeometryFactory factory) { var hasZ = false; var coords = GetCoordinates(tokens, false, ref hasZ); return(factory.CreateLinearRing(ToSequence(hasZ, coords))); }
private IGeometry ReadLineString(OgrGeometryType type, OgrGeometry geom) { var count = geom.GetPointCount(); var dimension = geom.GetDimension(); var cs = _factory.CoordinateSequenceFactory.Create(count, dimension); if (dimension > 2) { for (var i = 0; i < cs.Count; i++) { cs.SetOrdinate(i, Ordinate.X, geom.GetX(i)); cs.SetOrdinate(i, Ordinate.Y, geom.GetY(i)); cs.SetOrdinate(i, Ordinate.Z, geom.GetZ(i)); } } else { for (var i = 0; i < cs.Count; i++) { cs.SetOrdinate(i, Ordinate.X, geom.GetX(i)); cs.SetOrdinate(i, Ordinate.Y, geom.GetY(i)); } } return(_factory.CreateLinearRing(cs)); }
/// <summary> /// Reads the <see cref="ILinearRing" /> representation of the GM. /// </summary> /// <param name="node">The GM representation of the geometry.</param> /// <param name="factory">The factory used for geometry production.</param> /// <returns>The <see cref="ILinearRing" /> representation of the geometry.</returns> private static ILinearRing ReadLinearRing(IEnumerable <XElement> node, IGeometryFactory factory) { List <Coordinate> coordinates = new List <Coordinate>(); if (node.Any(r => r.Name.LocalName == "coordinates")) { XElement first = node.FirstOrDefault(n => n.Name.LocalName == "coordinates"); if (first == null) { throw new ArgumentException("The linearring geometry has no coordinates", "node"); } else { coordinates = first.Value.Split(' ') .Select(text => text.Split(',')) .Select(array => new Coordinate(Double.Parse(array[0], System.Globalization.CultureInfo.InvariantCulture.NumberFormat), Double.Parse(array[1], System.Globalization.CultureInfo.InvariantCulture.NumberFormat))).ToList(); } if (coordinates == null) { throw new ArgumentException("The linearring geometry has no coordinates", "node"); } } else { foreach (XElement coordNode in node.Where(n => n.Name.LocalName == "coord")) { coordinates.Add(ReadCoord(coordNode)); } } return(factory.CreateLinearRing(coordinates)); }
/// <summary> /// Reads a <see cref="ILinearRing"/> geometry. /// </summary> /// <param name="reader">The reader</param> /// <param name="cs">The coordinate system</param> ///<param name="srid">The spatial reference id for the geometry.</param> ///<returns>A <see cref="ILinearRing"/> geometry</returns> protected ILinearRing ReadLinearRing(BinaryReader reader, CoordinateSystem cs, int srid) { IGeometryFactory factory = _geometryServices.CreateGeometryFactory(_precisionModel, srid, _sequenceFactory); int numPoints = reader.ReadInt32(); ICoordinateSequence sequence = ReadCoordinateSequenceRing(reader, numPoints, cs); return(factory.CreateLinearRing(sequence)); }
private void EnsureRing() { if (_ring != null) { return; } _ring = _factory.CreateLinearRing(Coordinates); }
public static IPolygon CreateCircle( IGeometryFactory fact, double basex, double basey, double size, int nPts) { Coordinate[] pts = CreateCircle(basex, basey, size, nPts); var ring = fact.CreateLinearRing(pts); var poly = fact.CreatePolygon(ring, null); return poly; }
public IGeometry Edit(IGeometry geometry, IGeometryFactory factory) { var linearRing = geometry as ILinearRing; if (linearRing != null) { return factory.CreateLinearRing(EditSequence( (linearRing).CoordinateSequence, geometry)); } var lineString = geometry as ILineString; if (lineString != null) { return factory.CreateLineString(EditSequence( (lineString).CoordinateSequence, geometry)); } var point = geometry as IPoint; if (point != null) { return factory.CreatePoint(EditSequence( (point).CoordinateSequence, geometry)); } return geometry; }
/// <summary> /// Creates a <c>LinearRing</c> using the next token in the stream. /// </summary> /// <param name="tokens"> /// Tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a <LineString Text. /// </param> /// <param name="factory"> </param> /// <returns>A <c>LinearRing</c> specified by the next /// token in the stream.</returns> private ILinearRing ReadLinearRingText(IEnumerator<Token> tokens, IGeometryFactory factory) { return factory.CreateLinearRing(GetCoordinates(tokens, false)); }
private static void GeneratePolygons(IGeometryFactory factory, ICollection<IGeometry> geometry, Random rndGen) { int numPolygons = rndGen.Next(10, 100); for (var polyIndex = 0; polyIndex < numPolygons; polyIndex++) { var vertices = new GeoPoint[5]; var upperLeft = new GeoPoint(rndGen.NextDouble()*1000, rndGen.NextDouble()*1000); var sideLength = rndGen.NextDouble()*50; // Make a square vertices[0] = new GeoPoint(upperLeft.X, upperLeft.Y); vertices[1] = new GeoPoint(upperLeft.X + sideLength, upperLeft.Y); vertices[2] = new GeoPoint(upperLeft.X + sideLength, upperLeft.Y - sideLength); vertices[3] = new GeoPoint(upperLeft.X, upperLeft.Y - sideLength); vertices[4] = upperLeft; geometry.Add(factory.CreatePolygon(factory.CreateLinearRing(vertices), null)); } }
public static IPolygon CreateSineStar( IGeometryFactory fact, double basex, double basey, double size, double armLen, int nArms, int nPts) { Coordinate[] pts = CreateSineStar(basex, basey, size, armLen, nArms, nPts); var ring = fact.CreateLinearRing(pts); var poly = fact.CreatePolygon(ring, null); return poly; }
public static IPolygon CreateBox( IGeometryFactory fact, double minx, double miny, int nSide, double segLen) { Coordinate[] pts = CreateBox(minx, minx, nSide, segLen); var ring = fact.CreateLinearRing(pts); var poly = fact.CreatePolygon(ring, null); return poly; }
/// <summary> /// Transforms a <see cref="LinearRing" /> object. /// </summary> /// <param name="factory"></param> /// <param name="r"></param> /// <param name="transform"></param> /// <returns></returns> public static ILinearRing TransformLinearRing(IGeometryFactory factory, ILinearRing r, IMathTransform transform) { try { var coordSequence = transform.Transform(r.CoordinateSequence); return factory.CreateLinearRing(coordSequence); } catch { return null; } }
/// <summary> /// Transforms a <see cref="GeoAPI.Geometries.ILinearRing"/>. /// </summary> /// <param name="r">LinearRing to transform</param> /// <param name="from">Source Projection</param> /// <param name="to">Target Projection</param> /// <param name="toFactory">The factory to create geometries for <paramref name="to"/></param> /// <returns>Transformed LinearRing</returns> public static ILinearRing TransformLinearRing(ILinearRing r, ProjectionInfo from, ProjectionInfo to, IGeometryFactory toFactory) { try { var toSeq = TransformSequence(r.CoordinateSequence, from, to, toFactory.CoordinateSequenceFactory); return toFactory.CreateLinearRing(toSeq); } catch { return null; } }
/// <summary> /// Creates a Polygon or MultiPolygon from this Polygon shape. /// </summary> /// <param name="factory">The IGeometryFactory to use to create the new IGeometry.</param> /// <returns>The IPolygon or IMultiPolygon created from this shape.</returns> protected IGeometry FromPolygon(IGeometryFactory factory) { if (factory == null) factory = Geometry.DefaultFactory; var shells = new List<ILinearRing>(); var holes = new List<ILinearRing>(); foreach (var part in _shapeRange.Parts) { var coords = GetCoordinates(part); var ring = factory.CreateLinearRing(coords); if (_shapeRange.Parts.Count == 1) { shells.Add(ring); } else { if (CgAlgorithms.IsCounterClockwise(ring.Coordinates)) { holes.Add(ring); } else { shells.Add(ring); } } } //// Now we have a list of all shells and all holes List<ILinearRing>[] holesForShells = new List<ILinearRing>[shells.Count]; for (int i = 0; i < shells.Count; i++) { holesForShells[i] = new List<ILinearRing>(); } // Find holes foreach (ILinearRing t in holes) { ILinearRing testRing = t; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; Coordinate testPt = testRing.Coordinates[0]; for (int j = 0; j < shells.Count; j++) { ILinearRing tryRing = shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; var isContained = tryEnv.Contains(testEnv) && (CgAlgorithms.IsPointInRing(testPt, tryRing.Coordinates) || (PointInList(testPt, tryRing.Coordinates))); // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } holesForShells[j].Add(t); } } } var polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) { polygons[i] = factory.CreatePolygon(shells[i], holesForShells[i].ToArray()); } if (polygons.Length == 1) { return polygons[0]; } // It's a multi part return factory.CreateMultiPolygon(polygons); }
private static GeoAPI.Geometries.IPolygon ReadPolygon(byte[] geom, ref int idx, bool isLittleEndian, IGeometryFactory factory) { double[] adfTuple = new double[2]; int nRings; nRings = ReadUInt32(geom,ref idx, isLittleEndian); if (nRings < 1 || nRings > Int32.MaxValue / (2 * 8)) throw new ApplicationException("Currupt SpatialLite geom"); List<GeoAPI.Geometries.ILineString> lineStrings = new List<GeoAPI.Geometries.ILineString>(); for (int i = 0; i < nRings; i++) lineStrings.Add(ReadLineString(geom,ref idx, isLittleEndian, factory)); List<GeoAPI.Geometries.ILinearRing> holes = null; var shell = factory.CreateLinearRing(lineStrings[0].Coordinates); if (lineStrings.Count > 1) { holes = new List<GeoAPI.Geometries.ILinearRing>(); for (int i = 1; i < lineStrings.Count; i++) { holes.Add(new NetTopologySuite.Geometries.LinearRing(lineStrings[i].Coordinates)); } } return factory.CreatePolygon(shell, holes == null ? null : holes.ToArray()); }
private static ILinearRing CreateWKBLinearRing(BinaryReader reader, WkbByteOrder byteOrder, IGeometryFactory factory) { var points = new List<Coordinate>(ReadCoordinates(reader, byteOrder)); if (!points[0].Equals2D(points[points.Count-1])) points.Add(new Coordinate(points[0])); return factory.CreateLinearRing(points.ToArray()); }
internal static NTSLinearRing ToNTSLinearRing(Geometries.LinearRing geom, IGeometryFactory factory) { NTSCoordinate[] coordinates = new NTSCoordinate[geom.NumPoints]; int index = 0; foreach (Geometries.Point point in geom.Vertices) coordinates[index++] = ToNTSCoordinate(point, factory); return factory.CreateLinearRing(coordinates) as NTSLinearRing; }
/// <summary> /// Transforms a <see cref="LinearRing" /> object. /// </summary> /// <param name="factory"></param> /// <param name="r"></param> /// <param name="transform"></param> /// <returns></returns> public static ILinearRing TransformLinearRing(IGeometryFactory factory, ILinearRing r, IMathTransform transform) { try { ICoordinate[] coords = ExtractCoordinates(r, transform); return factory.CreateLinearRing(coords); } catch { return null; } }
/// <summary> /// Creates a <c>Polygon</c> using the next token in the stream. /// </summary> /// <param name="tokens"> /// Tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a Polygon Text. /// </param> /// <param name="factory"> </param> /// <returns> /// A <c>Polygon</c> specified by the next token /// in the stream. /// </returns> private IPolygon ReadPolygonText(IEnumerator<Token> tokens, IGeometryFactory factory) { string nextToken = GetNextEmptyOrOpener(tokens); if (nextToken.Equals("EMPTY")) return factory.CreatePolygon( factory.CreateLinearRing(new Coordinate[] { } ), new ILinearRing[] { } ); var holes = new List<ILinearRing>(); var shell = ReadLinearRingText(tokens, factory); nextToken = GetNextCloserOrComma(tokens); while (nextToken.Equals(",")) { ILinearRing hole = ReadLinearRingText(tokens, factory); holes.Add(hole); nextToken = GetNextCloserOrComma(tokens); } return factory.CreatePolygon(shell, holes.ToArray()); }
/// <summary> /// Creates a <c>LinearRing</c> using the next token in the stream. /// </summary> /// <param name="tokens"> /// Tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a <LineString Text. /// </param> /// <param name="factory"> </param> /// <returns>A <c>LinearRing</c> specified by the next /// token in the stream.</returns> private ILinearRing ReadLinearRingText(IEnumerator<Token> tokens, IGeometryFactory factory) { var hasZ = false; var coords = GetCoordinates(tokens, false, ref hasZ); return factory.CreateLinearRing(ToSequence(hasZ, coords)); }
/// <summary> /// Gets the Voronoi cell around a site specified /// by the origin of a QuadEdge. /// </summary> /// <remarks> /// The userData of the polygon is set to be the <see cref="Coordinate" /> /// of the site. This allows attaching external /// data associated with the site to this cell polygon. /// </remarks> /// <param name="qe">a quadedge originating at the cell site</param> /// <param name="geomFact">a factory for building the polygon</param> /// <returns>a polygon indicating the cell extent</returns> public IPolygon GetVoronoiCellPolygon(QuadEdge qe, IGeometryFactory geomFact) { var cellPts = new List<Coordinate>(); QuadEdge startQE = qe; do { // Coordinate cc = circumcentre(qe); // use previously computed circumcentre Coordinate cc = qe.Rot.Orig.Coordinate; cellPts.Add(cc); // move to next triangle CW around vertex qe = qe.OPrev; } while (qe != startQE); var coordList = new CoordinateList(); coordList.AddAll(cellPts, false); coordList.CloseRing(); if (coordList.Count < 4) { #if !PCL Debug.WriteLine(coordList); #endif coordList.Add(coordList[coordList.Count - 1], true); } Coordinate[] pts = coordList.ToCoordinateArray(); IPolygon cellPoly = geomFact.CreatePolygon(geomFact.CreateLinearRing(pts), null); Vertex v = startQE.Orig; cellPoly.UserData = v.Coordinate; return cellPoly; }
/// <summary> /// Creates a Polygon or MultiPolygon from this Polygon shape. /// </summary> /// <param name="factory">The IGeometryFactory to use to create the new IGeometry.</param> /// <returns>The IPolygon or IMultiPolygon created from this shape.</returns> protected IGeometry FromPolygon(IGeometryFactory factory) { if (factory == null) factory = Geometry.DefaultFactory; List<ILinearRing> shells = new List<ILinearRing>(); List<ILinearRing> holes = new List<ILinearRing>(); foreach (PartRange part in _shapeRange.Parts) { List<Coordinate> coords = new List<Coordinate>(); int i = part.StartIndex; foreach (Vertex d in part) { Coordinate c = new Coordinate(d.X, d.Y); if (M != null && M.Length > 0) c.M = M[i]; if (Z != null && Z.Length > 0) c.Z = Z[i]; i++; coords.Add(c); } ILinearRing ring = factory.CreateLinearRing(coords); if (_shapeRange.Parts.Count == 1) { shells.Add(ring); } else { if (CgAlgorithms.IsCounterClockwise(ring.Coordinates)) { holes.Add(ring); } else { shells.Add(ring); } } } //// Now we have a list of all shells and all holes List<ILinearRing>[] holesForShells = new List<ILinearRing>[shells.Count]; for (int i = 0; i < shells.Count; i++) { holesForShells[i] = new List<ILinearRing>(); } // Find holes foreach (ILinearRing t in holes) { ILinearRing testRing = t; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; Coordinate testPt = testRing.Coordinates[0]; ILinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; bool isContained = false; if (tryEnv.Contains(testEnv) && (CgAlgorithms.IsPointInRing(testPt, tryRing.Coordinates) || (PointInList(testPt, tryRing.Coordinates)))) { isContained = true; } // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } holesForShells[j].Add(t); } } } IPolygon[] polygons = new Polygon[shells.Count]; for (int i = 0; i < shells.Count; i++) { polygons[i] = factory.CreatePolygon(shells[i], holesForShells[i].ToArray()); } if (polygons.Length == 1) { return polygons[0]; } // It's a multi part return factory.CreateMultiPolygon(polygons); }
/// <summary> /// Gets the geometry for the triangles in a triangulated subdivision as a <see cref="IGeometryCollection"/> /// of triangular <see cref="IPolygon"/>s. /// </summary> /// <param name="geomFact">the GeometryFactory to use</param> /// <returns>a GeometryCollection of triangular Polygons</returns> public IGeometryCollection GetTriangles(IGeometryFactory geomFact) { var triPtsList = GetTriangleCoordinates(false); IPolygon[] tris = new Polygon[triPtsList.Count]; int i = 0; foreach (var triPt in triPtsList) { tris[i++] = geomFact .CreatePolygon(geomFact.CreateLinearRing(triPt), null); } return geomFact.CreateGeometryCollection(tris); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if ( ! ( shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM)) throw new ShapefileException("Attempting to load a non-polygon as polygon."); // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) box[i] = file.ReadDouble(); int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); int[] partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) partOffsets[i] = file.ReadInt32(); ArrayList shells = new ArrayList(); ArrayList holes = new ArrayList(); for (int part = 0; part < numParts; part++) { int start = partOffsets[part]; int finish; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; int length = finish - start; CoordinateList points = new CoordinateList(); for (int i = 0; i < length; i++) { Coordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble() ); new PrecisionModel(geometryFactory.PrecisionModel).MakePrecise(external); Coordinate internalCoord = external; points.Add(internalCoord); } ILinearRing ring = geometryFactory.CreateLinearRing(points.ToArray()); // If shape have only a part, jump orientation check and add to shells if (numParts == 1) shells.Add(ring); else { // Orientation check if (CGAlgorithms.IsCounterClockwise(points.ToArray())) holes.Add(ring); else shells.Add(ring); } } // Now we have a list of all shells and all holes ArrayList holesForShells = new ArrayList(shells.Count); for (int i = 0; i < shells.Count; i++) holesForShells.Add(new ArrayList()); // Find holes for (int i = 0; i < holes.Count; i++) { LinearRing testRing = (LinearRing) holes[i]; LinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; Coordinate testPt = testRing.GetCoordinateN(0); LinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = (LinearRing) shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; bool isContained = false; CoordinateList coordList = new CoordinateList(tryRing.Coordinates); if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, coordList.ToArray()) || (PointInList(testPt, coordList)))) isContained = true; // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) minShell = tryRing; // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. ArrayList holesForThisShell = (ArrayList)holesForShells[j]; holesForThisShell.Add(holes[i]); } } } IPolygon[] polygons = new Polygon[shells.Count]; for (int i = 0; i < shells.Count; i++) polygons[i] = geometryFactory.CreatePolygon((LinearRing) shells[i], (LinearRing[])((ArrayList) holesForShells[i]).ToArray(typeof(LinearRing))); if (polygons.Length == 1) return polygons[0]; // It's a multi part return geometryFactory.CreateMultiPolygon(polygons); }
private static ILinearRing CreateEllipse(IGeometryFactory geometryFactory, ICoordinate center, double a, double b, bool reverse) { const double piHalf = Math.PI * 0.5d; const int segmentsPerQuadrant = 12; double step = piHalf / segmentsPerQuadrant; if (reverse) step *= -1; var coordFac = geometryFactory.CoordinateFactory; var coords = new ICoordinate[4*segmentsPerQuadrant + 1]; var angle = 0d; for (var i = 0; i < 4 * segmentsPerQuadrant; i++) { coords[i] = coordFac.Create(center[Ordinates.X] + Math.Cos(angle) * a, center[Ordinates.Y] + Math.Sin(angle) * b); angle += step; } coords[coords.Length - 1] = (ICoordinate)coords[0].Clone(); return geometryFactory.CreateLinearRing(coords); }
/// <summary> /// Creates a Polygon using the next token in the stream. /// </summary> /// <param name="tokenizer">Tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a <Polygon Text>.</param> /// <param name="factory">The factory to create the result geometry</param> /// <returns>Returns a Polygon specified by the next token /// in the stream</returns> /// <remarks> /// ParseException is thrown if the coordinates used to create the Polygon /// shell and holes do not form closed linestrings, or if an unexpected /// token is encountered. /// </remarks> private static IPolygon ReadPolygonText(WktStreamTokenizer tokenizer, IGeometryFactory factory) { string nextToken = GetNextEmptyOrOpener(tokenizer); if (nextToken == "EMPTY") return factory.CreatePolygon(null, null); var exteriorRing = factory.CreateLinearRing(GetCoordinates(tokenizer)); nextToken = GetNextCloserOrComma(tokenizer); var interiorRings = new List<ILinearRing>(); while (nextToken == ",") { //Add holes interiorRings.Add(factory.CreateLinearRing(GetCoordinates(tokenizer))); nextToken = GetNextCloserOrComma(tokenizer); } return factory.CreatePolygon(exteriorRing, interiorRings.ToArray()); }
/// <summary> /// Transforms a <see cref="GeoAPI.Geometries.IPolygon"/>. /// </summary> /// <param name="p">Polygon to transform</param> /// <param name="from">Source Projection</param> /// <param name="to">Target Projection</param> /// <param name="toFactory">The factory to create geometries for <paramref name="to"/></param> /// <returns>Transformed Polygon</returns> public static IPolygon TransformPolygon(IPolygon p, ProjectionInfo from, ProjectionInfo to, IGeometryFactory toFactory) { var shell = toFactory.CreateLinearRing(TransformSequence(p.Shell.CoordinateSequence, from, to, toFactory.CoordinateSequenceFactory)); var holes = new ILinearRing[p.NumInteriorRings]; for (var i = 0; i < p.NumInteriorRings; i++) holes[i] = toFactory.CreateLinearRing(TransformSequence(p.GetInteriorRingN(i).CoordinateSequence, from, to, toFactory.CoordinateSequenceFactory)); return toFactory.CreatePolygon(shell, holes); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); type = (ShapeGeometryType) Enum.Parse(typeof(ShapeGeometryType), shapeTypeNum.ToString()); if (type == ShapeGeometryType.NullShape) return geometryFactory.CreatePolygon(null, null); if (!(type == ShapeGeometryType.Polygon || type == ShapeGeometryType.PolygonM || type == ShapeGeometryType.PolygonZ || type == ShapeGeometryType.PolygonZM)) throw new ShapefileException("Attempting to load a non-polygon as polygon."); // Read and for now ignore bounds. int bblength = GetBoundingBoxLength(); bbox = new double[bblength]; for (; bbindex < 4; bbindex++) { double d = file.ReadDouble(); bbox[bbindex] = d; } int[] partOffsets; int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) partOffsets[i] = file.ReadInt32(); ArrayList shells = new ArrayList(); ArrayList holes = new ArrayList(); int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; for (int i = 0; i < length; i++) { ICoordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble() ); geometryFactory.PrecisionModel.MakePrecise( external); ICoordinate internalCoord = external; // Thanks to Abhay Menon! if (!Double.IsNaN(internalCoord.Y) && !Double.IsNaN(internalCoord.X)) points.Add(internalCoord, false); } if (points.Count > 2) // Thanks to Abhay Menon! { if (points[0].Distance(points[points.Count - 1]) > .00001) points.Add(new Coordinate(points[0])); else if (points[0].Distance(points[points.Count - 1]) > 0.0) points[points.Count - 1].CoordinateValue = points[0]; ILinearRing ring = geometryFactory.CreateLinearRing(points.ToArray()); // If shape have only a part, jump orientation check and add to shells if (numParts == 1) shells.Add(ring); else { // Orientation check if (CGAlgorithms.IsCCW(points.ToArray())) holes.Add(ring); else shells.Add(ring); } } } // Now we have a list of all shells and all holes ArrayList holesForShells = new ArrayList(shells.Count); for (int i = 0; i < shells.Count; i++) holesForShells.Add(new ArrayList()); // Find holes for (int i = 0; i < holes.Count; i++) { ILinearRing testRing = (ILinearRing) holes[i]; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; ICoordinate testPt = testRing.GetCoordinateN(0); ILinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = (ILinearRing) shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; bool isContained = false; CoordinateList coordList = new CoordinateList(tryRing.Coordinates); if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, coordList.ToArray()) || (PointInList(testPt, coordList)))) isContained = true; // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) minShell = tryRing; // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. ArrayList holesForThisShell = (ArrayList) holesForShells[j]; holesForThisShell.Add(testRing); } } } IPolygon[] polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) polygons[i] = (geometryFactory.CreatePolygon((ILinearRing) shells[i], (ILinearRing[]) ((ArrayList) holesForShells[i]).ToArray(typeof(ILinearRing)))); if (polygons.Length == 1) geom = polygons[0]; else geom = geometryFactory.CreateMultiPolygon(polygons); GrabZMValues(file); return geom; }
public IGeometry ToGeometry(IGeometryFactory geomFactory) { if (IsNull) { return geomFactory.CreatePoint((ICoordinateSequence)null); } Coordinate px00 = new Coordinate(_minX, _minA - _minX); Coordinate px01 = new Coordinate(_minX, _minX - _minB); Coordinate px10 = new Coordinate(_maxX, _maxX - _maxB); Coordinate px11 = new Coordinate(_maxX, _maxA - _maxX); Coordinate py00 = new Coordinate(_minA - _minY, _minY); Coordinate py01 = new Coordinate(_minY + _maxB, _minY); Coordinate py10 = new Coordinate(_maxY + _minB, _maxY); Coordinate py11 = new Coordinate(_maxA - _maxY, _maxY); IPrecisionModel pm = geomFactory.PrecisionModel; pm.MakePrecise(px00); pm.MakePrecise(px01); pm.MakePrecise(px10); pm.MakePrecise(px11); pm.MakePrecise(py00); pm.MakePrecise(py01); pm.MakePrecise(py10); pm.MakePrecise(py11); CoordinateList coordList = new CoordinateList(); coordList.Add(px00, false); coordList.Add(px01, false); coordList.Add(py10, false); coordList.Add(py11, false); coordList.Add(px11, false); coordList.Add(px10, false); coordList.Add(py01, false); coordList.Add(py00, false); if (coordList.Count == 1) { return geomFactory.CreatePoint(px00); } Coordinate[] pts; if (coordList.Count == 2) { pts = coordList.ToCoordinateArray(); return geomFactory.CreateLineString(pts); } // must be a polygon, so add closing point coordList.Add(px00, false); pts = coordList.ToCoordinateArray(); return geomFactory.CreatePolygon(geomFactory.CreateLinearRing(pts), null); }
/// <summary> /// /// </summary> /// <param name="geometry"></param> /// <param name="factory"></param> /// <returns></returns> public virtual IGeometry Edit(IGeometry geometry, IGeometryFactory factory) { if (geometry is LinearRing) return factory.CreateLinearRing(Edit(geometry.Coordinates, geometry)); if (geometry is LineString) return factory.CreateLineString(Edit(geometry.Coordinates, geometry)); if (geometry is Point) { IList<Coordinate> newCoordinates = Edit(geometry.Coordinates, geometry); return factory.CreatePoint((newCoordinates.Count > 0) ? newCoordinates[0] : null); } return geometry; }
/// <summary> /// /// </summary> /// <param name="geometry"></param> /// <param name="factory"></param> /// <returns></returns> public IGeometry Edit(IGeometry geometry, IGeometryFactory factory) { if (geometry is ILinearRing) return factory.CreateLinearRing(Edit(geometry.Coordinates, geometry)); if (geometry is ILineString) return factory.CreateLineString(Edit(geometry.Coordinates, geometry)); if (geometry is Point) { ICoordinate[] newCoordinates = Edit(geometry.Coordinates, geometry); return factory.CreatePoint((newCoordinates.Length > 0) ? newCoordinates[0] : null); } return geometry; }
/// <summary> /// Transforms a <see cref="GeoAPI.Geometries.ILinearRing"/>. /// </summary> /// <param name="r">LinearRing to transform</param> /// <param name="transform">MathTransform</param> /// <param name="targetFactory">The factory to create the target geometry</param> /// <returns>Transformed LinearRing</returns> public static ILinearRing TransformLinearRing(ILinearRing r, IMathTransform transform, IGeometryFactory targetFactory) { try { return targetFactory.CreateLinearRing(TransformCoordinates(r.Coordinates, transform)); } catch { return null; } }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="totalRecordLength">Total length of the record we are about to read</param> /// <param name="factory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, int totalRecordLength, IGeometryFactory factory) { int totalRead = 0; var type = (ShapeGeometryType)ReadInt32(file, totalRecordLength, ref totalRead); if (type == ShapeGeometryType.NullShape) return factory.CreatePolygon(null, null); if (type != ShapeType) throw new ShapefileException(string.Format("Encountered a '{0}' instead of a '{1}'", type, ShapeType)); // Read and for now ignore bounds. var bblength = GetBoundingBoxLength(); boundingBox = new double[bblength]; for (; boundingBoxIndex < 4; boundingBoxIndex++) boundingBox[boundingBoxIndex] = ReadDouble(file, totalRecordLength, ref totalRead); var numParts = ReadInt32(file, totalRecordLength, ref totalRead); var numPoints = ReadInt32(file, totalRecordLength, ref totalRead); var partOffsets = new int[numParts]; for (var i = 0; i < numParts; i++) partOffsets[i] = ReadInt32(file, totalRecordLength, ref totalRead); var skippedList = new HashSet<int>(); //var allPoints = new List<Coordinate>(); var buffer = new CoordinateBuffer(numPoints, NoDataBorderValue, true); var pm = factory.PrecisionModel; for (var part = 0; part < numParts; part++) { var start = partOffsets[part]; var finish = (part == numParts - 1) ? numPoints : partOffsets[part + 1]; var length = finish - start; for (var i = 0; i < length; i++) { var x = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead)); var y = pm.MakePrecise(ReadDouble(file, totalRecordLength, ref totalRead)); // Thanks to Abhay Menon! if (!(Coordinate.NullOrdinate.Equals(x) || Coordinate.NullOrdinate.Equals(y))) buffer.AddCoordinate(x, y); else skippedList.Add(start + i); } //Add a marker that we have finished one part of the geometry buffer.AddMarker(); } // Trond Benum: We have now read all the parts, let's read optional Z and M values // and populate Z in the coordinate before we start manipulating the segments // We have to track corresponding optional M values and set them up in the // Geometries via ICoordinateSequence further down. GetZMValues(file, totalRecordLength, ref totalRead, buffer, skippedList); // Get the resulting sequences var sequences = buffer.ToSequences(factory.CoordinateSequenceFactory); var shells = new List<ILinearRing>(); var holes = new List<ILinearRing>(); for (var i = 0; i < sequences.Length; i++) { //Skip garbage input data with 0 points if (sequences[i].Count < 1) continue; var tmp = EnsureClosedSequence(sequences[i], factory.CoordinateSequenceFactory); var ring = factory.CreateLinearRing(tmp); if (ring.IsCCW) holes.Add(ring); else shells.Add(ring); } // Ensure the ring is encoded right if (shells.Count == 0 && holes.Count == 1) { shells.Add(factory.CreateLinearRing(holes[0].CoordinateSequence.Reversed())); holes.Clear(); } // Now we have lists of all shells and all holes var holesForShells = new List<List<ILinearRing>>(shells.Count); for (var i = 0; i < shells.Count; i++) holesForShells.Add(new List<ILinearRing>()); //Thanks to Bruno.Labrecque //Sort shells by area, rings should only be added to the smallest shell, that contains the ring shells.Sort(ProbeLinearRing); // Find holes foreach (var testHole in holes) { var testEnv = testHole.EnvelopeInternal; var testPt = testHole.GetCoordinateN(0); //We have the shells sorted for (var j = 0; j < shells.Count; j++) { var tryShell = shells[j]; var tryEnv = tryShell.EnvelopeInternal; var isContained = tryEnv.Contains(testEnv) && CGAlgorithms.IsPointInRing(testPt, tryShell.Coordinates); // Check if this new containing ring is smaller than the current minimum ring if (isContained) { // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. var holesForThisShell = holesForShells[j]; holesForThisShell.Add(testHole); //Suggested by Bruno.Labrecque //A LinearRing should only be added to one outer shell break; } } } var polygons = new IPolygon[shells.Count]; for (var i = 0; i < shells.Count; i++) polygons[i] = (factory.CreatePolygon(shells[i], holesForShells[i].ToArray())); if (polygons.Length == 1) geom = polygons[0]; else geom = factory.CreateMultiPolygon(polygons); return geom; }
private ILineString ReprojectLineString(IGeometryFactory factory, ILineString line, ISpatialReference @from, ISpatialReference to, bool lineString = true) { return lineString ? factory.CreateLineString(Reproject(line.CoordinateSequence, from, to)) : factory.CreateLinearRing(Reproject(line.CoordinateSequence, from, to)); }