A LinearRing is a LineString that is both closed and simple.
Inheritance: LineString
Ejemplo n.º 1
0
 /// <summary>
 /// Return a copy of this geometry
 /// </summary>
 /// <returns>Copy of Geometry</returns>
 public new LinearRing Clone()
 {
     var l = new LinearRing();
     for (int i = 0; i < Vertices.Count; i++)
         l.Vertices.Add(Vertices[i].Clone());
     return l;
 }
Ejemplo n.º 2
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)
        {
            // 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++)
            {
                Point 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;
            Point prevPoint = ring.Vertices[iPrev];
            Point 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);
            }
            // if area is positive, points are ordered CCW
            return (disc > 0.0);
        }
Ejemplo n.º 3
0
 private static Polygon CreatePolygon()
 {
     var polygon = new Polygon();
     polygon.ExteriorRing.Vertices.Add(new Point(0, 0));
     polygon.ExteriorRing.Vertices.Add(new Point(0, 10000000));
     polygon.ExteriorRing.Vertices.Add(new Point(10000000, 10000000));
     polygon.ExteriorRing.Vertices.Add(new Point(10000000, 0));
     polygon.ExteriorRing.Vertices.Add(new Point(0, 0));
     var linearRing = new LinearRing();
     linearRing.Vertices.Add(new Point(1000000, 1000000));
     linearRing.Vertices.Add(new Point(9000000, 1000000));
     linearRing.Vertices.Add(new Point(9000000, 9000000));
     linearRing.Vertices.Add(new Point(1000000, 9000000));
     linearRing.Vertices.Add(new Point(1000000, 1000000));
     polygon.InteriorRings.Add(linearRing);
     return polygon;
 }
Ejemplo n.º 4
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>())
 {
 }
Ejemplo n.º 5
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;
 }
Ejemplo n.º 6
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>())
 {
 }
Ejemplo n.º 7
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;
 }
Ejemplo n.º 8
0
 /// <summary>
 ///     Return a copy of this geometry
 /// </summary>
 /// <returns>Copy of Geometry</returns>
 public new LinearRing Clone()
 {
     var linearRing = new LinearRing();
     for (var i = 0; i < Vertices.Count; i++)
     {
         linearRing.Vertices.Add(Vertices[i].Clone());
     }
     return linearRing;
 }
Ejemplo n.º 9
0
        private static LinearRing CreateWKBLinearRing(BinaryReader reader, WkbByteOrder byteOrder)
        {
            var l = new LinearRing();
            //l.Vertices.AddRange(ReadCoordinates(reader, byteOrder));
            IEnumerable<Point> arrPoint = ReadCoordinates(reader, byteOrder);
            foreach (Point t in arrPoint)
            {
                l.Vertices.Add(t);
            }

            //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;
        }
Ejemplo n.º 10
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"));
        }
Ejemplo n.º 11
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;
 }
Ejemplo n.º 12
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>
        // ReSharper disable once CyclomaticComplexity // Fix when changes need to be made here
        private Geometry ReadGeometry(uint oid)
        {
            _brShapeFile.BaseStream.Seek(GetShapeIndex(oid) + 8, 0); //Skip record number and content length
            var type = (ShapeType)_brShapeFile.ReadInt32(); //Shape type
            if (type == ShapeType.Null)
                return null;
            if (_shapeType == ShapeType.Point || _shapeType == ShapeType.PointM || _shapeType == ShapeType.PointZ)
            {
                return new Point(_brShapeFile.ReadDouble(), _brShapeFile.ReadDouble());
            }
            if (_shapeType == ShapeType.Multipoint || _shapeType == ShapeType.MultiPointM ||
                _shapeType == ShapeType.MultiPointZ)
            {
                _brShapeFile.BaseStream.Seek(32 + _brShapeFile.BaseStream.Position, 0); //skip min/max box
                var 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;
            }
            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

                var 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)
                {
                    var mline = new MultiLineString();
                    for (int lineId = 0; lineId < nParts; lineId++)
                    {
                        var 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
                    var rings = new List<LinearRing>();
                    for (int ringId = 0; ringId < nParts; ringId++)
                    {
                        var 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);
                    }
                    var 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
                    {
                        var poly = new Polygon { ExteriorRing = rings[0] };
                        if (rings.Count > 1)
                            for (int i = 1; i < rings.Count; i++)
                                poly.InteriorRings.Add(rings[i]);
                        return poly;
                    }
                    else
                    {
                        var mpoly = new MultiPolygon();
                        var poly = new Polygon { ExteriorRing = rings[0] };
                        for (var 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;
                    }
                }
            }

            throw (new ApplicationException("Shapefile type " + _shapeType.ToString() + " not supported"));
        }
Ejemplo n.º 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)
 {
     this.exteriorRing = exteriorRing;
     this.interiorRings = interiorRings;
 }
Ejemplo n.º 14
0
        public static Polygon ConvertScreenToWorld(Polygon sharpmapPolygon)
        {
            // Log4netLogger.Debug("Start converting screen polygon to map polygon");

            var linearRing = new LinearRing();
            foreach (var vertex in sharpmapPolygon.ExteriorRing.Vertices)
            {
                linearRing.Vertices.Add(ConvertScreenToWorld(vertex));
            }

            // Log4netLogger.Debug("Screen polygon to map polygon conversion ended");
            return new Polygon(linearRing);
        }