A LinearRing is a LineString that is both closed and simple.
Inheritance: LineString
Example #1
0
        /// <summary>
        /// Instatiates a polygon based on one extorier ring 
        /// and a collection of interior rings.
        /// </summary>
        /// <param name="exteriorRing">Exterior <see cref="LinearRing"/></param>
        /// <param name="interiorRings">Interior LinearRings</param>
        public Polygon(LinearRing exteriorRing, IEnumerable<LinearRing> interiorRings)
        {
            _exteriorRing = exteriorRing;

            if (interiorRings != null)
                _interiorRings.AddRange(interiorRings);
        }
Example #2
0
 /// <summary>
 /// Return a copy of this geometry
 /// </summary>
 /// <returns>Copy of Geometry</returns>
 public new LinearRing Clone()
 {
     LinearRing l = new LinearRing();
     for (int i = 0; i < Vertices.Count; i++)
         l.Vertices.Add(Vertices[i].Clone());
     return l;
 }
Example #3
0
        // METHOD IsCCW() IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
        /*
         *  Copyright (C) 2002 Urban Science Applications, Inc.
         *
         *  This library is free software; you can redistribute it and/or
         *  modify it under the terms of the GNU Lesser General Public
         *  License as published by the Free Software Foundation; either
         *  version 2.1 of the License, or (at your option) any later version.
         *
         *  This library is distributed in the hope that it will be useful,
         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         *  Lesser General Public License for more details.
         *
         *  You should have received a copy of the GNU Lesser General Public
         *  License along with this library; if not, write to the Free Software
         *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
         *
         */
        /// <summary>
        /// Tests whether a ring is oriented counter-clockwise.
        /// </summary>
        /// <param name="ring">Ring to test.</param>
        /// <returns>Returns true if ring is oriented counter-clockwise.</returns>
        public static bool IsCCW(LinearRing ring)
        {
            Point PrevPoint, NextPoint;
            Point p;

            // Check if the ring has enough vertices to be a ring
            if (ring.Vertices.Count < 3) throw(new ArgumentException("Invalid LinearRing"));

            // find the point with the largest Y coordinate
            Point hip = ring.Vertices[0];
            int hii = 0;
            for (int i = 1; i < ring.Vertices.Count; i++)
            {
                p = ring.Vertices[i];
                if (p.Y > hip.Y)
                {
                    hip = p;
                    hii = i;
                }
            }
            // Point left to Hip
            int iPrev = hii - 1;
            if (iPrev < 0) iPrev = ring.Vertices.Count - 2;
            // Point right to Hip
            int iNext = hii + 1;
            if (iNext >= ring.Vertices.Count) iNext = 1;
            PrevPoint = ring.Vertices[iPrev];
            NextPoint = ring.Vertices[iNext];

            // translate so that hip is at the origin.
            // This will not affect the area calculation, and will avoid
            // finite-accuracy errors (i.e very small vectors with very large coordinates)
            // This also simplifies the discriminant calculation.
            double prev2x = PrevPoint.X - hip.X;
            double prev2y = PrevPoint.Y - hip.Y;
            double next2x = NextPoint.X - hip.X;
            double next2y = NextPoint.Y - hip.Y;
            // compute cross-product of vectors hip->next and hip->prev
            // (e.g. area of parallelogram they enclose)
            double disc = next2x * prev2y - next2y * prev2x;
            // If disc is exactly 0, lines are collinear.  There are two possible cases:
            //	(1) the lines lie along the x axis in opposite directions
            //	(2) the line lie on top of one another
            //  (2) should never happen, so we're going to ignore it!
            //	(Might want to assert this)
            //  (1) is handled by checking if next is left of prev ==> CCW

            if (disc == 0.0)
            {
                // poly is CCW if prev x is right of next x
                return (PrevPoint.X > NextPoint.X);
            }
            else
            {
                // if area is positive, points are ordered CCW
                return (disc > 0.0);
            }
        }
Example #4
0
 private static LinearRing CreateWKBLinearRing(BinaryReader reader, WkbByteOrder byteOrder)
 {
     SharpMap.Geometries.LinearRing l = new SharpMap.Geometries.LinearRing();
     l.Vertices.AddRange(ReadCoordinates(reader, byteOrder));
     //if polygon isn't closed, add the first point to the end (this shouldn't occur for correct WKB data)
     if (l.Vertices[0].X != l.Vertices[l.Vertices.Count - 1].X || l.Vertices[0].Y != l.Vertices[l.Vertices.Count - 1].Y)
     {
         l.Vertices.Add(new Point(l.Vertices[0].X, l.Vertices[0].Y));
     }
     return(l);
 }
Example #5
0
		public void PolygonTest()
		{
			Polygon p = new Polygon();
			Assert.IsTrue(p.IsEmpty());
			Assert.AreEqual(0, p.NumInteriorRing);
			Assert.AreEqual(p.NumInteriorRing, p.InteriorRings.Count);
			Assert.IsFalse(p.Equals(null));
			Assert.IsTrue(p.Equals(new Polygon()));
			Assert.IsNull(p.GetBoundingBox());
			LinearRing ring = new LinearRing();
			ring.Vertices.Add(new Point(10, 10));
			ring.Vertices.Add(new Point(20, 10));
			ring.Vertices.Add(new Point(20, 20));
            Assert.IsFalse(ring.IsCCW());
			ring.Vertices.Add(new Point(10, 20));
            ring.Vertices.Add(ring.Vertices[0].Clone());
            Assert.IsTrue(ring.IsPointWithin(new Point(15, 15)));
            Assert.AreNotSame(ring.Clone(), ring);
			p.ExteriorRing = ring;
            
            

			Assert.AreEqual(100, p.Area);
			LinearRing ring2 = new LinearRing();
			ring2.Vertices.Add(new Point(11, 11));
			ring2.Vertices.Add(new Point(19, 11));
			ring2.Vertices.Add(new Point(19, 19));
			ring2.Vertices.Add(new Point(11, 19));
			ring2.Vertices.Add(ring2.Vertices[0].Clone());			
			p.InteriorRings.Add(ring2);
			Assert.AreEqual(100 + 64, p.Area);
            // Reverse() doesn't exist for Collections
			//ring2.Vertices.Reverse();
			//Assert.AreEqual(100 - 64, p.Area);
			Assert.AreEqual(1, p.NumInteriorRing);
			Assert.AreEqual(new BoundingBox(10, 10, 20, 20), p.GetBoundingBox());

			Polygon p2 = p.Clone();
			Assert.AreEqual(p, p2);
			Assert.AreNotSame(p, p2);
			p2.InteriorRings.RemoveAt(0);
			Assert.AreNotEqual(p, p2);
		}
Example #6
0
        /// <summary>
        /// Transforms a <see cref="SharpMap.Geometries.LinearRing"/>.
        /// </summary>
        /// <param name="r">LinearRing to transform</param>
        /// <param name="transform">MathTransform</param>
        /// <returns>Transformed LinearRing</returns>
        public static LinearRing TransformLinearRing(LinearRing r, IMathTransform transform)
        {
            try
            {
                List<double[]> points = new List<double[]>();

                for (int i = 0; i < r.Vertices.Count; i++)
                    points.Add(new double[2] {r.Vertices[i].X, r.Vertices[i].Y});

                return new LinearRing(transform.TransformList(points));
            }
            catch
            {
                return null;
            }
        }
        private static Geometry FromShapeFilePolygon(EsriShapeBuffer shapeBuffer, out BoundingBox box)
        {
            box = null;
            if (shapeBuffer == null)
                return null;

            var hasZ = EsriShapeBuffer.HasZs(shapeBuffer.shapeType);
            var hasM = EsriShapeBuffer.HasMs(shapeBuffer.shapeType);
            using (var reader = new BinaryReader(new MemoryStream(shapeBuffer.shapeBuffer)))
            {
                var type = reader.ReadInt32();
                if (!(type == 5 || type == 15 || type == 25))
                    throw new InvalidOperationException();

                box = new BoundingBox(reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble());

                var numParts = reader.ReadInt32();
                var numPoints = reader.ReadInt32();
                var allVertices = new List<Point>(numPoints);

                var parts = new int[numParts+1];
                for (var i = 0; i < numParts; i++)
                    parts[i] = reader.ReadInt32();
                parts[numParts] = numPoints;

                var res = new MultiPolygon();
                Polygon poly = null;
                for (var i = 0; i < numParts; i++)
                {
                    var count = parts[i + 1] - parts[i];
                    var vertices = new List<Point>(count);
                    for (var j = 0; j < count; j++)
                    {
                        var vertex = hasZ
                                         ? new Point3D(reader.ReadDouble(), reader.ReadDouble(), double.NaN)
                                         : new Point(reader.ReadDouble(), reader.ReadDouble());
                        vertices.Add(vertex);
                        allVertices.Add(vertex);
                    }

                    var ring = new LinearRing(vertices);
                    if (poly == null || !ring.IsCCW())
                    {
                        poly = new Polygon(ring);
                        res.Polygons.Add(poly);
                    }
                    else
                    {
                        poly.InteriorRings.Add(ring);
                    }
                }

                if (hasZ)
                {
                    var minZ = reader.ReadDouble();
                    var maxZ = reader.ReadDouble();
                    for (var i = 0; i < numPoints; i++)
                        ((Point3D) allVertices[i]).Z = reader.ReadDouble();
                }

                if (res.NumGeometries == 1)
                    return res.Polygons[0];

                return res;

            }
        }
        private static Geometry ToSharpMapMultiPolygon(EsriShapeBuffer shapeBuffer)
        {
            if (shapeBuffer == null)
                return null;

            var multiPartShapeBuffer = shapeBuffer as EsriMultiPartShapeBuffer;
            if (multiPartShapeBuffer == null)
            {
                BoundingBox box;
                return FromShapeFilePolygon(shapeBuffer, out box);
            }

            var hasZ = EsriShapeBuffer.HasZs(shapeBuffer.shapeType);
            var res = new MultiPolygon();
            Polygon poly = null;
            var offset = 0;
            for (var i = 0; i < multiPartShapeBuffer.NumParts; i++)
            {
                var vertices = new List<Point>(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 Point3D(point.x, point.y, multiPartShapeBuffer.Zs[index])
                        : new Point(point.x, point.y));
                }

                var ring = new LinearRing(vertices);
                if (poly == null || !ring.IsCCW())
                {
                    poly = new Polygon(ring);
                    res.Polygons.Add(poly);
                } 
                else
                {
                    poly.InteriorRings.Add(ring);
                }

                offset += multiPartShapeBuffer.Parts[i];
            }

            if (res.NumGeometries == 1)
                return res.Polygons[0];
            
            return res;
        }
Example #9
0
 public Polygon GetFootprint()
 {
     LinearRing myRing = new LinearRing(GetFourCorners());
     return new Polygon(myRing);
 }
Example #10
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, List <LinearRing> interiorRings)
 {
     _ExteriorRing  = exteriorRing;
     _InteriorRings = interiorRings;
 }
 private static LinearRing CreateWKBLinearRing(BinaryReader reader, WkbByteOrder byteOrder)
 {
     SharpMap.Geometries.LinearRing l = new SharpMap.Geometries.LinearRing();
     l.Vertices.AddRange(ReadCoordinates(reader, byteOrder));
     //if polygon isn't closed, add the first point to the end (this shouldn't occur for correct WKB data)
     if (l.Vertices[0].X != l.Vertices[l.Vertices.Count - 1].X || l.Vertices[0].Y != l.Vertices[l.Vertices.Count - 1].Y)
         l.Vertices.Add(new Point(l.Vertices[0].X, l.Vertices[0].Y));
     return l;
 }
Example #12
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, IList <LinearRing> interiorRings)
 {
     this.exteriorRing  = exteriorRing;
     this.interiorRings = interiorRings;
 }
Example #13
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, IList <LinearRing> interiorRings)
 {
     _ExteriorRing  = exteriorRing;
     _InteriorRings = interiorRings ?? new Collection <LinearRing>();
 }
Example #14
0
 /// <summary>
 /// Instatiates a polygon based on one exterior ring.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 public Polygon(LinearRing exteriorRing)
     : this(exteriorRing, null)
 {
 }
Example #15
0
		/// <summary>
		/// Instatiates a polygon based on one extorier ring.
		/// </summary>
		/// <param name="exteriorRing">Exterior ring</param>
		public Polygon(LinearRing exteriorRing) : this(exteriorRing, new Collection<LinearRing>()) { }
Example #16
0
		/// <summary>
		/// Instatiates a polygon based on one extorier ring and a collection of interior rings.
		/// </summary>
		/// <param name="exteriorRing">Exterior ring</param>
		/// <param name="interiorRings">Interior rings</param>
		public Polygon(LinearRing exteriorRing, Collection<LinearRing> interiorRings)
		{
			_ExteriorRing = exteriorRing;
			_InteriorRings = interiorRings;
		}
Example #17
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, IList<LinearRing> interiorRings)
 {
     _ExteriorRing = exteriorRing;
     _InteriorRings = interiorRings;
 }
Example #18
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 public Polygon(LinearRing exteriorRing) : this(exteriorRing, new List <LinearRing>())
 {
 }
		/// <summary>
		/// Transforms a <see cref="SharpMap.Geometries.LinearRing"/>.
		/// </summary>
		/// <param name="r">LinearRing to transform</param>
		/// <param name="transform">MathTransform</param>
		/// <returns>Transformed LinearRing</returns>
		public static LinearRing TransformLinearRing(LinearRing r, IMathTransform transform)
		{
			try { return new LinearRing(transform.TransformList(r.Vertices)); }
			catch { return null; }
		}
Example #20
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, IList<LinearRing> interiorRings)
 {
     _ExteriorRing = exteriorRing;
     _InteriorRings = interiorRings ?? new Collection<LinearRing>();
 }
Example #21
0
 /// <summary>   
 /// Returns the box filter string needed in SQL query   
 /// </summary>   
 /// <param name="bbox"></param>   
 /// <returns></returns>   
 private string GetBoxFilterStr(BoundingBox bbox) {   
     //geography::STGeomFromText('LINESTRING(47.656 -122.360, 47.656 -122.343)', 4326);   
     LinearRing lr = new LinearRing();   
     lr.Vertices.Add(new Point(bbox.Left, bbox.Bottom));   
     lr.Vertices.Add(new Point(bbox.Right, bbox.Bottom));   
     lr.Vertices.Add(new Point(bbox.Right, bbox.Top));   
     lr.Vertices.Add(new Point(bbox.Left, bbox.Top));   
     lr.Vertices.Add(new Point(bbox.Left, bbox.Bottom));   
     Polygon p = new Polygon(lr);   
     string bboxText = Converters.WellKnownText.GeometryToWKT.Write(p); // "";   
     //string whereClause = GeometryColumn + ".STIntersects(geometry::STGeomFromText('" + bboxText + "', " + SRID + ")" + MakeValidString + ") = 1";   
     string whereClause = String.Format("{0}{1}.STIntersects({4}::STGeomFromText('{2}', {3})) = 1", 
         GeometryColumn, MakeValidString, bboxText, SRID, _spatialObject);
     return whereClause; // strBbox;   
 }   
Example #22
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 public Polygon(LinearRing exteriorRing)
     : this(exteriorRing, new List<LinearRing>())
 {
 }
Example #23
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 public Polygon(LinearRing exteriorRing) : this(exteriorRing, new Collection <LinearRing>())
 {
 }
        /// <summary>
        /// Transforms a <see cref="SharpMap.Geometries.LinearRing"/>.
        /// </summary>
        /// <param name="r">LinearRing to transform</param>
        /// <param name="from">Source Projection</param>
        /// <param name="to">Target Projection</param>
        /// <returns>Transformed LinearRing</returns>
        public static LinearRing TransformLinearRing(LinearRing r, ProjectionInfo from, ProjectionInfo to)
        {
            try
            {
                List<double[]> points = new List<double[]>();

                for (int i = 0; i < r.Vertices.Count; i++)
                    points.Add(new double[] {r.Vertices[i].X, r.Vertices[i].Y});

                return new LinearRing(TransformList(points, from, to));
            }
            catch
            {
                return null;
            }
        }
Example #25
0
 /// <summary>
 /// Creates a deep copy of the LinearRing.
 /// </summary>
 /// <returns>A copy of the LinearRing instance.</returns>
 public override Geometry Clone()
 {
     LinearRing ring = new LinearRing(Vertices);
     return ring;
 }
Example #26
0
        /// <summary>
        /// Reads and parses the geometry with ID 'oid' from the ShapeFile
        /// </summary>
        /// <remarks><see cref="FilterDelegate">Filtering</see> is not applied to this method</remarks>
        /// <param name="oid">Object ID</param>
        /// <returns>geometry</returns>
        private Geometry ReadGeometry(uint oid)
        {
            brShapeFile.BaseStream.Seek(GetShapeIndex(oid) + 8, 0); //Skip record number and content length
            ShapeType type = (ShapeType) brShapeFile.ReadInt32(); //Shape type
            if (type == ShapeType.Null)
                return null;
            if (_ShapeType == ShapeType.Point || _ShapeType == ShapeType.PointM || _ShapeType == ShapeType.PointZ)
            {
                Point tempFeature = new Point();
                return new Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble());
            }
            else if (_ShapeType == ShapeType.Multipoint || _ShapeType == ShapeType.MultiPointM ||
                     _ShapeType == ShapeType.MultiPointZ)
            {
                brShapeFile.BaseStream.Seek(32 + brShapeFile.BaseStream.Position, 0); //skip min/max box
                MultiPoint feature = new MultiPoint();
                int nPoints = brShapeFile.ReadInt32(); // get the number of points
                if (nPoints == 0)
                    return null;
                for (int i = 0; i < nPoints; i++)
                    feature.Points.Add(new Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));

                return feature;
            }
            else if (_ShapeType == ShapeType.PolyLine || _ShapeType == ShapeType.Polygon ||
                     _ShapeType == ShapeType.PolyLineM || _ShapeType == ShapeType.PolygonM ||
                     _ShapeType == ShapeType.PolyLineZ || _ShapeType == ShapeType.PolygonZ)
            {
                brShapeFile.BaseStream.Seek(32 + brShapeFile.BaseStream.Position, 0); //skip min/max box

                int nParts = brShapeFile.ReadInt32(); // get number of parts (segments)
                if (nParts == 0)
                    return null;
                int nPoints = brShapeFile.ReadInt32(); // get number of points

                int[] segments = new int[nParts + 1];
                //Read in the segment indexes
                for (int b = 0; b < nParts; b++)
                    segments[b] = brShapeFile.ReadInt32();
                //add end point
                segments[nParts] = nPoints;

                if ((int) _ShapeType%10 == 3)
                {
                    MultiLineString mline = new MultiLineString();
                    for (int LineID = 0; LineID < nParts; LineID++)
                    {
                        LineString line = new LineString();
                        for (int i = segments[LineID]; i < segments[LineID + 1]; i++)
                            line.Vertices.Add(new Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
                        mline.LineStrings.Add(line);
                    }
                    if (mline.LineStrings.Count == 1)
                        return mline[0];
                    return mline;
                }
                else //(_ShapeType == ShapeType.Polygon etc...)
                {
                    //First read all the rings
                    List<LinearRing> rings = new List<LinearRing>();
                    for (int RingID = 0; RingID < nParts; RingID++)
                    {
                        LinearRing ring = new LinearRing();
                        for (int i = segments[RingID]; i < segments[RingID + 1]; i++)
                            ring.Vertices.Add(new Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
                        rings.Add(ring);
                    }
                    bool[] IsCounterClockWise = new bool[rings.Count];
                    int PolygonCount = 0;
                    for (int i = 0; i < rings.Count; i++)
                    {
                        IsCounterClockWise[i] = rings[i].IsCCW();
                        if (!IsCounterClockWise[i])
                            PolygonCount++;
                    }
                    if (PolygonCount == 1) //We only have one polygon
                    {
                        Polygon poly = new Polygon();
                        poly.ExteriorRing = rings[0];
                        if (rings.Count > 1)
                            for (int i = 1; i < rings.Count; i++)
                                poly.InteriorRings.Add(rings[i]);
                        return poly;
                    }
                    else
                    {
                        MultiPolygon mpoly = new MultiPolygon();
                        Polygon poly = new Polygon();
                        poly.ExteriorRing = rings[0];
                        for (int i = 1; i < rings.Count; i++)
                        {
                            if (!IsCounterClockWise[i])
                            {
                                mpoly.Polygons.Add(poly);
                                poly = new Polygon(rings[i]);
                            }
                            else
                                poly.InteriorRings.Add(rings[i]);
                        }
                        mpoly.Polygons.Add(poly);
                        return mpoly;
                    }
                }
            }
            else
                throw (new ApplicationException("Shapefile type " + _ShapeType.ToString() + " not supported"));
        }
Example #27
0
        private static LinearRing CreateWKBLinearRing(BinaryReader reader, WkbByteOrder byteOrder)
        {
            LinearRing l = new LinearRing();
            //l.Vertices.AddRange(ReadCoordinates(reader, byteOrder));
            Point[] arrPoint = ReadCoordinates(reader, byteOrder);
            for (int i = 0; i < arrPoint.Length; i++)
                l.Vertices.Add(arrPoint[i]);

            //if polygon isn't closed, add the first point to the end (this shouldn't occur for correct WKB data)
            if (l.Vertices[0].X != l.Vertices[l.Vertices.Count - 1].X ||
                l.Vertices[0].Y != l.Vertices[l.Vertices.Count - 1].Y)
                l.Vertices.Add(new Point(l.Vertices[0].X, l.Vertices[0].Y));
            return l;
        }
Example #28
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, Collection <LinearRing> interiorRings)
 {
     _ExteriorRing  = exteriorRing;
     _InteriorRings = interiorRings;
 }