private IPolygon GetResult() { IGeometryFactory gf = _poly.Factory; ILinearRing shell = (ILinearRing)_poly.ExteriorRing; IPreparedGeometry shellPrep = PreparedGeometryFactory.Prepare(gf.CreatePolygon(shell)); IList <IGeometry> holes = new List <IGeometry>(); for (int i = 0; i < _poly.NumInteriorRings; i++) { IGeometry hole = _poly.GetInteriorRingN(i); if (shellPrep.Covers(hole)) { holes.Add(hole); } } // all holes valid, so return original if (holes.Count == _poly.NumInteriorRings) { return(_poly); } // return new polygon with covered holes only ILinearRing[] arr = GeometryFactory.ToLinearRingArray(holes); IPolygon result = gf.CreatePolygon(shell, arr); return(result); }
/// <summary> /// Converts the GML element to polygon. /// </summary> /// <param name="element">The GML element of the polygon.</param> /// <param name="factory">The geometry factory.</param> /// <returns>The converted polygon.</returns> private static IPolygon ToPolygon(XElement element, IGeometryFactory factory) { if (element.Elements() == null) { return(factory.CreatePolygon(new Coordinate[0])); } ILinearRing shell = null; List <ILinearRing> holes = new List <ILinearRing>(); foreach (XElement innerElement in element.Elements()) { switch (innerElement.Name.LocalName) { case "outerBoundaryIs": shell = ToLinearRing(innerElement.Elements().FirstOrDefault(), factory); break; case "innerBoundaryIs": holes.Add(ToLinearRing(innerElement.Elements().FirstOrDefault(), factory)); break; } } return(factory.CreatePolygon(shell, holes)); }
/// <summary> /// Computes the <see cref="IMultiPolygon" /> representation of the WKB. /// </summary> /// <param name="geometryBytes">The WKB representation of the geometry.</param> /// <param name="byteOrder">The byte-order of the conversion.</param> /// <param name="geometryModel">The geometry model of the conversion.</param> /// <param name="factory">The factory used for geometry production.</param> /// <returns>The <see cref="IMultiPolygon" /> representation of the geometry.</returns> private static IMultiPolygon ComputeMultiPolygon(Byte[] geometryBytes, ByteOrder byteOrder, GeometryModel geometryModel, IGeometryFactory factory) { Int32 coordinateSize = (geometryModel == GeometryModel.Spatial3D) ? 24 : 16; Int32 polygonCount = EndianBitConverter.ToInt32(geometryBytes, 5, byteOrder); IPolygon[] polygons = new Polygon[polygonCount]; Int32 startIndex = 9; for (Int32 i = 0; i < polygonCount; i++) { Int32 ringCount = EndianBitConverter.ToInt32(geometryBytes, startIndex, byteOrder); Int32 shellCoordinateCount = EndianBitConverter.ToInt32(geometryBytes, startIndex + 4, byteOrder); startIndex += 8; Coordinate[] shellCoordinates = new Coordinate[shellCoordinateCount]; for (Int32 byteIndex = startIndex, coordinateIndex = 0; coordinateIndex < shellCoordinateCount; byteIndex += coordinateSize, coordinateIndex++) { shellCoordinates[coordinateIndex] = new Coordinate(EndianBitConverter.ToDouble(geometryBytes, byteIndex, byteOrder), EndianBitConverter.ToDouble(geometryBytes, byteIndex + 8, byteOrder), geometryModel == GeometryModel.Spatial3D ? EndianBitConverter.ToDouble(geometryBytes, byteIndex + 16, byteOrder) : 0); } startIndex += shellCoordinateCount * coordinateSize; if (ringCount > 1) { Coordinate[][] holes = new Coordinate[ringCount - 1][]; for (Int32 j = 1; j < ringCount; j++) { Int32 holeCoordianteCount = EndianBitConverter.ToInt32(geometryBytes, startIndex, byteOrder); startIndex += 4; Coordinate[] holeCoordinates = new Coordinate[holeCoordianteCount]; for (Int32 byteIndex = startIndex, coordinateIndex = 0; coordinateIndex < holeCoordianteCount; byteIndex += coordinateSize, coordinateIndex++) { holeCoordinates[coordinateIndex] = new Coordinate(EndianBitConverter.ToDouble(geometryBytes, byteIndex, byteOrder), EndianBitConverter.ToDouble(geometryBytes, byteIndex + 8, byteOrder), geometryModel == GeometryModel.Spatial3D ? EndianBitConverter.ToDouble(geometryBytes, byteIndex + 16, byteOrder) : 0); } holes[j - 1] = holeCoordinates; startIndex += holeCoordianteCount * coordinateSize; } polygons[i] = factory.CreatePolygon(shellCoordinates, holes); } else { polygons[i] = factory.CreatePolygon(shellCoordinates); } } return(factory.CreateMultiPolygon(polygons)); }
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())); }
private IGeometry BuildPolygon() { if (_rings.Count == 0) { return(_factory.CreatePolygon(null, null)); } var shell = _factory.CreateLinearRing(_rings[0]); var holes = _rings.GetRange(1, _rings.Count - 1) .ConvertAll(coordinates => _factory.CreateLinearRing(coordinates)).ToArray(); _rings.Clear(); return(_factory.CreatePolygon(shell, holes)); }
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)); }
/// <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); }
private static IPolygon CreateComb(Envelope env, int nArms, IGeometryFactory geomFact) { int npts = 4 * (nArms - 1) + 2 + 2 + 1; var pts = new Coordinate[npts]; double armWidth = env.Width / (2 * nArms - 1); double armLen = env.Height - armWidth; double xBase = env.MinX; double yBase = env.MinY; int ipts = 0; for (int i = 0; i < nArms; i++) { double x1 = xBase + i * 2 * armWidth; double y1 = yBase + armLen + armWidth; pts[ipts++] = new Coordinate(x1, y1); pts[ipts++] = new Coordinate(x1 + armWidth, y1); if (i < nArms - 1) { pts[ipts++] = new Coordinate(x1 + armWidth, yBase + armWidth); pts[ipts++] = new Coordinate(x1 + 2 * armWidth, yBase + armWidth); } } pts[ipts++] = new Coordinate(env.MaxX, yBase); pts[ipts++] = new Coordinate(xBase, yBase); pts[ipts++] = new Coordinate(pts[0]); return(geomFact.CreatePolygon(pts)); }
public IPolygon GetResult() { IGeometryFactory gf = _poly.Factory; IList <IGeometry> holes = new List <IGeometry>(); for (int i = 0; i < _poly.NumInteriorRings; i++) { ILinearRing hole = (ILinearRing)_poly.GetInteriorRingN(i); if (!_predicate.Value(hole)) { holes.Add(hole); } } // all holes valid, so return original if (holes.Count == _poly.NumInteriorRings) { return(_poly); } // return new polygon with covered holes only ILinearRing shell = (ILinearRing)_poly.ExteriorRing; ILinearRing[] rings = GeometryFactory.ToLinearRingArray(holes); IPolygon result = gf.CreatePolygon(shell, rings); return(result); }
/// <summary> /// Gets the computed variable-width line buffer. /// </summary> /// <returns>A polygon</returns> public IGeometry GetResult() { Utilities.Assert.IsTrue(_line.NumPoints == _width.Length); var parts = new List <IGeometry>(); var pts = _line.Coordinates; for (var i = 0; i < _line.NumPoints; i++) { var dist = _width[i] / 2; var ptBuf = _line.GetPointN(i).Buffer(dist); parts.Add(ptBuf); if (i >= 1) { var curvePts = GenerateSegmentCurve(pts[i - 1], pts[i], _width[i - 1], _width[i]); var segBuf = _geomFactory.CreatePolygon(curvePts); parts.Add(segBuf); } } var partsGeom = _geomFactory.CreateGeometryCollection(GeometryFactory.ToGeometryArray(parts)); var buffer = partsGeom.Union(); return(buffer); }
// see: https://github.com/NetTopologySuite/NetTopologySuite/issues/111 public void issue_111_polygonhandler_with_invalid_values() { IGeometryFactory factory = GeometryFactory.Default; Coordinate[] points = new Coordinate[5]; points[0] = new Coordinate(0, 0); points[1] = new Coordinate(1, 0); points[2] = new Coordinate(1, 1); points[3] = new Coordinate(0, 1); points[4] = new Coordinate(0, 0); IPolygon poly = factory.CreatePolygon(points); IMultiPolygon mpoly = factory.CreateMultiPolygon(new[] { poly }); IGeometry[] arr = new[] { mpoly, GeometryCollection.Empty }; IGeometryCollection geometries = factory.CreateGeometryCollection(arr); ShapeGeometryType shapeType = Shapefile.GetShapeType(geometries); Assert.AreEqual(ShapeGeometryType.PolygonZM, shapeType); string tempPath = Path.GetTempFileName(); ShapefileWriter sfw = new ShapefileWriter(Path.GetFileNameWithoutExtension(tempPath), shapeType); sfw.Write(geometries); }
/// <summary> /// Reads the <see cref="IPolygon" /> 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="IPolygon" /> representation of the geometry.</returns> private static IPolygon ReadPolygon(IEnumerable <XElement> node, IGeometryFactory factory) { IList <Coordinate> shellCoordinates; List <IList <Coordinate> > holeCoordinates = new List <IList <Coordinate> >(); XElement shellNode = node.FirstOrDefault(n => n.Name.LocalName == "outerBoundaryIs"); if (shellNode == null) { throw new ArgumentException("The polygon geometry has no outer boundary", "node"); } XElement linearRingNode = shellNode.Elements().First(); shellCoordinates = ReadLinearRing(linearRingNode.Elements(), factory).Coordinates; if (node.Any(r => r.Name.LocalName == "innerBoundaryIs")) { foreach (XElement boundaryNode in node.Where(n => n.Name.LocalName == "innerBoundaryIs")) { linearRingNode = boundaryNode.Elements().FirstOrDefault(); if (linearRingNode == null) { throw new ArgumentException("The polygon geometry's inner boundary has no linearrings", "node"); } holeCoordinates.Add(ReadLinearRing(linearRingNode.Elements(), factory).Coordinates); } } return(factory.CreatePolygon(shellCoordinates, holeCoordinates)); }
/// <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 void generatePolygons(IGeometryFactory geometryFactory, ICollection <IGeometry> geometry, Random rndGen) { ICoordinateSequenceFactory coordinateSequenceFactory = geometryFactory.CoordinateSequenceFactory; ICoordinateFactory coordinateFactory = geometryFactory.CoordinateFactory; ICoordinateSequence coords = coordinateSequenceFactory.Create(CoordinateDimensions.Two); Int32 polyCount = rndGen.Next(10, 100); for (Int32 polyIndex = 0; polyIndex < polyCount; polyIndex++) { ICoordinate upperLeft = coordinateFactory.Create(rndGen.NextDouble() * 1000, rndGen.NextDouble() * 1000); Double sideLength = rndGen.NextDouble() * 50; // Make a square coords.Add(upperLeft); coords.Add(coordinateFactory.Create(upperLeft[Ordinates.X] + sideLength, upperLeft[Ordinates.Y])); coords.Add(coordinateFactory.Create(upperLeft[Ordinates.X] + sideLength, upperLeft[Ordinates.Y] - sideLength)); coords.Add(coordinateFactory.Create(upperLeft[Ordinates.X], upperLeft[Ordinates.Y] - sideLength)); IPolygon polygon = geometryFactory.CreatePolygon(coords); geometry.Add(polygon); } }
///<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 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[] { })); } }
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 void SetUp() { _factory = new GeometryFactory(); _geometries = new IGeometry[] { _factory.CreatePoint(1, 1, 1), _factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i, i))), _factory.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i * i, i * i, i * i)), new Coordinate[][] { Enumerable.Range(1, 100).Select(i => new Coordinate(i, i, i)).ToArray(), Enumerable.Range(1, 4).Select(i => new Coordinate(i, i, i)).ToArray() }), _factory.CreateMultiPoint(Enumerable.Range(1, 4).Select(i => _factory.CreatePoint(i, i, i))), _factory.CreateMultiLineString(new ILineString[] { _factory.CreateLineString(Enumerable.Range(1, 4).Select(i => new Coordinate(i, i, i))) }), _factory.CreateMultiPolygon(new IPolygon[] { _factory.CreatePolygon(Enumerable.Range(1, 4).Select(i => new Coordinate(i * i, i * i, i * i)), new Coordinate[][] { Enumerable.Range(1, 4).Select(i => new Coordinate(i, i, i)).ToArray(), Enumerable.Range(1, 4).Select(i => new Coordinate(i, i, i)).ToArray() }) }) }; }
/// <summary> /// Computes the <see cref="IPolygon" /> representation of the WKB. /// </summary> /// <param name="geometryBytes">The WKB representation of the geometry.</param> /// <param name="byteOrder">The byte-order of the conversion.</param> /// <param name="geometryModel">The geometry model of the conversion.</param> /// <param name="factory">The factory used for geometry production.</param> /// <returns>The <see cref="IPolygon" /> representation of the geometry.</returns> private static IPolygon ComputePolygon(Byte[] geometryBytes, ByteOrder byteOrder, GeometryModel geometryModel, IGeometryFactory factory) { Int32 coordinateSize = (geometryModel == GeometryModel.Spatial3D) ? 24 : 16; Int32 ringCount = EndianBitConverter.ToInt32(geometryBytes, 5, byteOrder); Int32 shellCoordinateCount = EndianBitConverter.ToInt32(geometryBytes, 9, byteOrder); Coordinate[] shellCoordinates = new Coordinate[shellCoordinateCount]; for (Int32 byteIndex = 13, coordinateIndex = 0; coordinateIndex < shellCoordinateCount; byteIndex += coordinateSize, coordinateIndex++) { shellCoordinates[coordinateIndex] = new Coordinate(EndianBitConverter.ToDouble(geometryBytes, byteIndex, byteOrder), EndianBitConverter.ToDouble(geometryBytes, byteIndex + 8, byteOrder), geometryModel == GeometryModel.Spatial3D ? EndianBitConverter.ToDouble(geometryBytes, byteIndex + 16, byteOrder) : 0); } if (ringCount > 1) { Coordinate[][] holes = new Coordinate[ringCount - 1][]; Int32 holeStartIndex = 13 + shellCoordinateCount * coordinateSize; for (Int32 i = 1; i < ringCount; i++) { Int32 holeCoordianteCount = EndianBitConverter.ToInt32(geometryBytes, holeStartIndex, byteOrder); holeStartIndex += 4; Coordinate[] holeCoordinates = new Coordinate[holeCoordianteCount]; for (Int32 byteIndex = holeStartIndex, coordinateIndex = 0; coordinateIndex < holeCoordianteCount; byteIndex += coordinateSize, coordinateIndex++) { holeCoordinates[coordinateIndex] = new Coordinate(EndianBitConverter.ToDouble(geometryBytes, byteIndex, byteOrder), EndianBitConverter.ToDouble(geometryBytes, byteIndex + 8, byteOrder), geometryModel == GeometryModel.Spatial3D ? EndianBitConverter.ToDouble(geometryBytes, byteIndex + 16, byteOrder) : 0); } holes[i - 1] = holeCoordinates; holeStartIndex += holeCoordianteCount * coordinateSize; } return(factory.CreatePolygon(shellCoordinates, holes)); } else { return(factory.CreatePolygon(shellCoordinates)); } }
/// <summary> /// Converts the Well-known Binary (WKB) to a polygon. /// </summary> /// <param name="geometryBytes">The WKB representation of the polygon.</param> /// <param name="byteOrder">The byte-order of the conversion.</param> /// <param name="dimension">The dimension of the geometry.</param> /// <param name="factory">The geometry factory.</param> /// <returns>The converted polygon.</returns> private static IPolygon ToPolygon(Byte[] geometryBytes, ByteOrder byteOrder, Int32 dimension, IGeometryFactory factory) { Int32 coordinateSize = (dimension == 3) ? 24 : 16; Int32 ringCount = EndianBitConverter.ToInt32(geometryBytes, 5, byteOrder); Int32 shellCoordinateCount = EndianBitConverter.ToInt32(geometryBytes, 9, byteOrder); Coordinate[] shellCoordinates = new Coordinate[shellCoordinateCount]; for (Int32 byteIndex = 13, coordinateIndex = 0; coordinateIndex < shellCoordinateCount; byteIndex += coordinateSize, coordinateIndex++) { shellCoordinates[coordinateIndex] = new Coordinate(EndianBitConverter.ToDouble(geometryBytes, byteIndex, byteOrder), EndianBitConverter.ToDouble(geometryBytes, byteIndex + 8, byteOrder), dimension == 3 ? EndianBitConverter.ToDouble(geometryBytes, byteIndex + 16, byteOrder) : 0); } if (ringCount > 1) { Coordinate[][] holes = new Coordinate[ringCount - 1][]; Int32 holeStartIndex = 13 + shellCoordinateCount * coordinateSize; for (Int32 ringIndex = 1; ringIndex < ringCount; ringIndex++) { Int32 holeCoordianteCount = EndianBitConverter.ToInt32(geometryBytes, holeStartIndex, byteOrder); holeStartIndex += 4; Coordinate[] holeCoordinates = new Coordinate[holeCoordianteCount]; for (Int32 byteIndex = holeStartIndex, coordinateIndex = 0; coordinateIndex < holeCoordianteCount; byteIndex += coordinateSize, coordinateIndex++) { holeCoordinates[coordinateIndex] = new Coordinate(EndianBitConverter.ToDouble(geometryBytes, byteIndex, byteOrder), EndianBitConverter.ToDouble(geometryBytes, byteIndex + 8, byteOrder), dimension == 3 ? EndianBitConverter.ToDouble(geometryBytes, byteIndex + 16, byteOrder) : 0); } holes[ringIndex - 1] = holeCoordinates; holeStartIndex += holeCoordianteCount * coordinateSize; } return(factory.CreatePolygon(shellCoordinates, holes)); } else { return(factory.CreatePolygon(shellCoordinates)); } }
private void ProcessPolygonGeometry(Polygon f) { var outerRing = _geometryFactory.CreateLinearRing( f.OuterBoundary.LinearRing.Coordinates.Select(crd => new Coordinate(crd.Longitude, crd.Latitude)).ToArray()); var innerHoles = new List <ILinearRing>(); foreach (var hole in f.InnerBoundary) { innerHoles.Add(_geometryFactory.CreateLinearRing( hole.LinearRing.Coordinates.Select(crd => new Coordinate(crd.Longitude, crd.Latitude)).ToArray())); } var pGeom = _geometryFactory.CreatePolygon(outerRing, innerHoles.ToArray()); AddGeometryToCollection(f.GetParent <Placemark>(), pGeom); }
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)); }
private IGeometry ReadPolygon(int dim, int lrsDim, SdoGeometry sdoGeom) { ILinearRing shell = null; //ILinearRing[] holes = new LinearRing[sdoGeom.ElemArray.Length - 1]; ILinearRing[] holes = new LinearRing[0]; var info = sdoGeom.ElemArray; var infoSize = info.Length / 3; int i = 0; int idxInteriorRings = 0; while (i < infoSize) { ICoordinateSequence cs = null; int numCompounds = 0; //if (info.getElementType(i).isCompound()) //{ // numCompounds = info.getNumCompounds(i); // cs = Add(cs, GetCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); //} //else //{ cs = Add(cs, GetElementCSeq(i, sdoGeom, false)); //} //if (info.getElementType(i).isInteriorRing()) //{ // holes[idxInteriorRings] = factory // .CreateLinearRing(cs); // holes[idxInteriorRings].SRID = (int)sdoGeom.Sdo_Srid; // idxInteriorRings++; //} //else //{ shell = factory.CreateLinearRing(cs); shell.SRID = (int)sdoGeom.Sdo_Srid; //} i += 1 + numCompounds; } IPolygon polygon = factory.CreatePolygon(shell, holes); polygon.SRID = (int)sdoGeom.Sdo_Srid; return(polygon); }
/// <summary> /// Converts the face to a SFA polygon. /// </summary> /// <param name="factory">The geometry factory used to produce the polygon.</param> /// <returns>The polygon geometry representing the face.</returns> public IPolygon ToGeometry(IGeometryFactory factory = null) { if (factory == null) { factory = FactoryRegistry.GetFactory <IGeometryFactory>(); } return(factory.CreatePolygon(Vertices.Select(vertex => vertex.Position), Holes.Select(hole => hole.Vertices.Select(vertex => vertex.Position).Reverse()))); }
private static IPolygon RandomPolygonal(IGeometryFactory geometryFactory) { switch (Random.Next(0, 1)) { case 0: var center = RandomCoordinate(geometryFactory.CoordinateFactory); double a = Random.Next(2, 5); double b = Random.Next(2, 5); var shell = CreateEllipse(geometryFactory, center, a, b, false); a *= 0.5d; b *= 0.35d; var holes = new[] { CreateEllipse(geometryFactory, center, a, b, true) }; return(geometryFactory.CreatePolygon(shell, holes)); default: break; } return(geometryFactory.CreatePolygon()); }
/// <summary> /// /// </summary> /// <param name="geom"></param> /// <param name="parent"></param> /// <returns></returns> protected virtual IGeometry TransformPolygon(IPolygon geom, IGeometry parent) { bool isAllValidLinearRings = true; IGeometry shell = TransformLinearRing(geom.Shell, geom); if (shell == null || !(shell is ILinearRing) || shell.IsEmpty) { isAllValidLinearRings = false; } var holes = new List <ILineString>(); for (int i = 0; i < geom.NumInteriorRings; i++) { IGeometry hole = TransformLinearRing(geom.Holes[i], geom); if (hole == null || hole.IsEmpty) { continue; } if (!(hole is ILinearRing)) { isAllValidLinearRings = false; } holes.Add((ILineString)hole); } if (isAllValidLinearRings) { #if !PCL var holesAsLinearRing = holes.ConvertAll <ILinearRing>(ls => (ILinearRing)ls).ToArray(); #else var tmp = new List <ILinearRing>(); foreach (var lineString in holes) { tmp.Add((ILinearRing)lineString); } var holesAsLinearRing = tmp.ToArray(); #endif return(Factory.CreatePolygon((ILinearRing)shell, holesAsLinearRing)); } else { var components = new List <IGeometry>(); if (shell != null) { components.Add(shell); } foreach (IGeometry hole in holes) { components.Add(hole); } return(Factory.BuildGeometry(components)); } }
/// <summary> /// /// </summary> /// <param name="geometryFactory"></param> /// <returns></returns> public IPolygon ToPolygon(IGeometryFactory geometryFactory) { ILinearRing[] holeLR = new ILinearRing[holes.Count]; for (int i = 0; i < holes.Count; i++) { holeLR[i] = ((EdgeRing)holes[i]).LinearRing; } IPolygon poly = geometryFactory.CreatePolygon(LinearRing, holeLR); return(poly); }
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(IList <Coordinate[]> coordinatess) { var shell = _factory.CreateLinearRing(coordinatess[0]); var rings = new List <ILinearRing>(); for (int i = 1; i < coordinatess.Count; i++) { rings.Add(_factory.CreateLinearRing(coordinatess[i])); } return(_factory.CreatePolygon(shell, rings.ToArray())); }
public object ToPolygon(CoordinateInfo[][] coordinates) { if (coordinates.Length == 0) { return(Polygon.Empty); } return(_geometryFactory.CreatePolygon( _geometryFactory.CreateLinearRing(coordinates.First().Select(MakeCoordinate).ToArray()), coordinates.Skip(1).Select(x => _geometryFactory.CreateLinearRing(x.Select(MakeCoordinate).ToArray())).ToArray() )); }
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; }
internal static NTSPolygon ToNTSPolygon(Geometries.Polygon geom, IGeometryFactory factory) { NTSLinearRing shell = ToNTSLinearRing(geom.ExteriorRing, factory); NTSLinearRing[] holes = new NTSLinearRing[geom.InteriorRings.Count]; int index = 0; foreach (Geometries.LinearRing hole in geom.InteriorRings) holes[index++] = ToNTSLinearRing(hole, factory); return factory.CreatePolygon(shell, holes) as NTSPolygon; }
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)); } }
private IPolygon ReprojectPolygon(IGeometryFactory factory, IPolygon polygon, ISpatialReference @from, ISpatialReference to) { var exterior = (ILinearRing)ReprojectLineString(factory, polygon.ExteriorRing, from, to, false); var interior = new ILinearRing[polygon.NumInteriorRings]; for (var i = 0; i < polygon.NumInteriorRings; i++) { interior[i] = (ILinearRing)ReprojectLineString(factory, polygon.GetInteriorRingN(i), from, to, false); } return factory.CreatePolygon(exterior, interior); }
private static IPolygon ParseWkbPolygon(byte[] blob, ref int offset, IGeometryFactory factory, ReadCoordinatesFunction readCoordinates, GaiaImport gaiaImport) { var number = gaiaImport.GetInt32(blob, ref offset) - 1; var shell = (ILinearRing)ParseWkbLineString(blob, ref offset, factory, factory.CreateLinearRing, readCoordinates, gaiaImport); var holes = new ILinearRing[number]; for (var i = 0; i < number; i++) holes[i] = (ILinearRing)ParseWkbLineString(blob, ref offset, factory, factory.CreateLinearRing, readCoordinates, gaiaImport); return factory.CreatePolygon(shell, holes); }
/// <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; }
private static void generatePolygons(IGeometryFactory geometryFactory, ICollection<IGeometry> geometry, Random rndGen) { ICoordinateSequenceFactory coordinateSequenceFactory = geometryFactory.CoordinateSequenceFactory; ICoordinateFactory coordinateFactory = geometryFactory.CoordinateFactory; ICoordinateSequence coords = coordinateSequenceFactory.Create(CoordinateDimensions.Two); Int32 polyCount = rndGen.Next(10, 100); for (Int32 polyIndex = 0; polyIndex < polyCount; polyIndex++) { ICoordinate upperLeft = coordinateFactory.Create(rndGen.NextDouble() * 1000, rndGen.NextDouble() * 1000); Double sideLength = rndGen.NextDouble() * 50; // Make a square coords.Add(upperLeft); coords.Add(coordinateFactory.Create(upperLeft[Ordinates.X] + sideLength, upperLeft[Ordinates.Y])); coords.Add(coordinateFactory.Create(upperLeft[Ordinates.X] + sideLength, upperLeft[Ordinates.Y] - sideLength)); coords.Add(coordinateFactory.Create(upperLeft[Ordinates.X], upperLeft[Ordinates.Y] - sideLength)); IPolygon polygon = geometryFactory.CreatePolygon(coords); geometry.Add(polygon); } }
private static IPolygon RandomPolygonal(IGeometryFactory geometryFactory) { switch (Random.Next(0, 1)) { case 0: var center = RandomCoordinate(geometryFactory.CoordinateFactory); double a = Random.Next(2, 5); double b = Random.Next(2, 5); var shell = CreateEllipse(geometryFactory, center, a, b, false); a *= 0.5d; b *= 0.35d; var holes = new[] {CreateEllipse(geometryFactory, center, a, b, true)}; return geometryFactory.CreatePolygon(shell, holes); default: break; } return geometryFactory.CreatePolygon(); }
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()); }
/// <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); }
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> /// Transforms a <see cref="GeoAPI.Geometries.IPolygon"/>. /// </summary> /// <param name="p">Polygon to transform</param> /// <param name="transform">MathTransform</param> /// <param name="targetFactory">The factory to create the target geometry</param> /// <returns>Transformed Polygon</returns> public static IPolygon TransformPolygon(IPolygon p, IMathTransform transform, IGeometryFactory targetFactory) { var shell = TransformLinearRing((ILinearRing) p.ExteriorRing, transform, targetFactory); ILinearRing[] holes = null; var holesCount = p.NumInteriorRings; if (holesCount > 0) { holes = new ILinearRing[holesCount]; for (var i = 0; i < holesCount; i++) holes[i] = TransformLinearRing((ILinearRing)p.GetInteriorRingN(i), transform, targetFactory); } return targetFactory.CreatePolygon(shell, holes); }
/// <summary> /// /// </summary> /// <param name="geometryFactory"></param> /// <returns></returns> public virtual IPolygon ToPolygon(IGeometryFactory geometryFactory) { ILinearRing[] holeLr = new LinearRing[_holes.Count]; for (int i = 0; i < _holes.Count; i++) holeLr[i] = ((EdgeRing)_holes[i]).LinearRing; IPolygon poly = geometryFactory.CreatePolygon(LinearRing, holeLr); return poly; }
/// <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); }
/// <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> /// 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> /// Transforms a <see cref="Polygon" /> object. /// </summary> /// <param name="factory"></param> /// <param name="p"></param> /// <param name="transform"></param> /// <returns></returns> public static IPolygon TransformPolygon(IGeometryFactory factory, IPolygon p, IMathTransform transform) { List<ILinearRing> holes = new List<ILinearRing>(p.InteriorRings.Length); for (int i = 0; i < p.InteriorRings.Length; i++) { ILinearRing hole = TransformLinearRing(factory, (ILinearRing) p.InteriorRings[i], transform); holes.Add(hole); } ILinearRing shell = TransformLinearRing(factory, (ILinearRing) p.ExteriorRing, transform); return factory.CreatePolygon(shell, holes.ToArray()); }
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; }
private static IPolygon CreateWKBPolygon(BinaryReader reader, WkbByteOrder byteOrder, IGeometryFactory factory) { // Get the Number of rings in this Polygon. var numRings = (int) ReadUInt32(reader, byteOrder); Debug.Assert(numRings >= 1, "Number of rings in polygon must be 1 or more."); var shell = CreateWKBLinearRing(reader, byteOrder, factory); var holes = new ILinearRing[--numRings]; for (var i = 0; i < numRings; i++) holes[i] = CreateWKBLinearRing(reader, byteOrder, factory); return factory.CreatePolygon(shell, holes); }
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> /// Creates an empty result geometry of the appropriate dimension, /// based on the given overlay operation and the dimensions of the inputs. /// The created geometry is always an atomic geometry, /// not a collection. /// <para/> /// The empty result is constructed using the following rules: /// <list type="Bullet"> /// <item><see cref="SpatialFunction.Intersection"/> - result has the dimension of the lowest input dimension</item> /// <item><see cref="SpatialFunction.Union"/> - result has the dimension of the highest input dimension</item> /// <item><see cref="SpatialFunction.Difference"/> - result has the dimension of the left-hand input</item> /// <item><see cref="SpatialFunction.SymDifference"/> - result has the dimension of the highest input dimension /// (since symDifference is the union of the differences).</item> /// </list> /// </summary> /// <param name="overlayOpCode">The overlay operation being performed</param> /// <param name="a">An input geometry</param> /// <param name="b">An input geometry</param> /// <param name="geomFact">The geometry factory being used for the operation</param> /// <returns>An empty atomic geometry of the appropriate dimension</returns> public static IGeometry CreateEmptyResult(SpatialFunction overlayOpCode, IGeometry a, IGeometry b, IGeometryFactory geomFact) { IGeometry result = null; switch (ResultDimension(overlayOpCode, a, b)) { case Dimension.False: result = geomFact.CreateGeometryCollection(new IGeometry[0]); break; case Dimension.Point: result = geomFact.CreatePoint((Coordinate)null); break; case Dimension.Curve: result = geomFact.CreateLineString((Coordinate[])null); break; case Dimension.Surface: result = geomFact.CreatePolygon(null, null); break; } return result; }
/// <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> /// 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> /// /// </summary> /// <param name="geometryFactory"></param> /// <returns></returns> public IPolygon ToPolygon(IGeometryFactory geometryFactory) { ILinearRing[] holeLR = new ILinearRing[_holes.Count]; for (int i = 0; i < _holes.Count; i++) holeLR[i] = _holes[i].LinearRing; IPolygon poly = geometryFactory.CreatePolygon(LinearRing, holeLR); return poly; }
/// <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; }
/// <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; }
/// <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()); }