/// <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));
        }
示例#2
0
        ///<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));
        }
示例#3
0
        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));
        }
示例#4
0
        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));
        }
示例#7
0
        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()));
        }
示例#9
0
        /// <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));
        }
示例#11
0
        /// <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));
        }
示例#13
0
            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);
            }
示例#14
0
 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));
        }
示例#16
0
            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()));
        }
示例#18
0
        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);
        }
示例#20
0
        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));
        }
示例#21
0
        /// <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 &lt;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)));
        }
示例#22
0
            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));
            }
示例#23
0
        /// <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));
        }
示例#24
0
        /// <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));
        }
示例#25
0
 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;
 }
示例#27
0
            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;
            }
示例#28
0
 /// <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 &lt;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));
 }
示例#29
0
        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;
     }
 }
示例#34
0
        /// <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());
        }
示例#36
0
 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());
 }
示例#37
0
 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;
 }
示例#38
0
		/// <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; }
		}
示例#39
0
        /// <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());
        }
示例#40
0
 /// <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 &lt;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;
        }
示例#42
0
        /// <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);
        }
示例#46
0
        /// <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 &lt;Polygon Text&gt;.</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);
        }
示例#48
0
        /// <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);
        }
示例#50
0
            /// <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;
            }
示例#51
0
            /// <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;
            }
示例#52
0
 /// <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;
     }
 }
示例#53
0
        /// <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;
        }
示例#54
0
 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));
 }