Polygon.cs :  » GIS » DeepEarth » GisSharpBlog » NetTopologySuite » Geometries » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » GIS » DeepEarth 
DeepEarth » GisSharpBlog » NetTopologySuite » Geometries » Polygon.cs
using System;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.Algorithm;

namespace GisSharpBlog.NetTopologySuite.Geometries{
    /// <summary> 
    /// Represents a linear polygon, which may include holes.
    /// The shell and holes of the polygon are represented by {LinearRing}s.
    /// In a valid polygon, holes may touch the shell or other holes at a single point.
    /// However, no sequence of touching holes may split the polygon into two pieces.
    /// The orientation of the rings in the polygon does not matter.
    /// The shell and holes must conform to the assertions specified in the
    /// <see href="http://www.opengis.org/techno/specs.htm"/> OpenGIS Simple Features Specification for SQL.     
    /// </summary>
#if !SILVERLIGHT
  [Serializable]
#endif
    public class Polygon : Geometry, IPolygon
    {
        /// <summary>
        /// Represents an empty <c>Polygon</c>.
        /// </summary>
        public static readonly IPolygon Empty = new GeometryFactory().CreatePolygon(null, null);

        /// <summary>
        /// The exterior boundary, or <c>null</c> if this <c>Polygon</c>
        /// is the empty point.
        /// </summary>
        protected ILinearRing shell = null;

        /// <summary>
        /// The interior boundaries, if any.
        /// </summary>
        protected ILinearRing[] holes; 
        
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Polygon"/> class.
        /// </summary>
        /// <param name="shell">
        /// The outer boundary of the new <c>Polygon</c>,
        /// or <c>null</c> or an empty <c>LinearRing</c> if the empty
        /// point is to be created.
        /// </param>
        /// <param name="holes">
        /// The inner boundaries of the new <c>Polygon</c>
        /// , or <c>null</c> or empty <c>LinearRing</c>s if the empty
        /// point is to be created.
        /// </param>
        /// <remarks>
        /// For create this <see cref="Geometry"/> is used a standard <see cref="GeometryFactory"/> 
        /// with <see cref="PrecisionModel" /> <c> == </c> <see cref="PrecisionModels.Floating"/>.
        /// </remarks>
        public Polygon(ILinearRing shell, ILinearRing[] holes) : this(shell, holes, DefaultFactory) { }

        /// <summary>
        /// Constructs a <c>Polygon</c> with the given exterior boundary and
        /// interior boundaries.
        /// </summary>       
        /// <param name="shell">
        /// The outer boundary of the new <c>Polygon</c>,
        /// or <c>null</c> or an empty <c>LinearRing</c> if the empty
        /// point is to be created.
        /// </param>
        /// <param name="holes">
        /// The inner boundaries of the new <c>Polygon</c>
        /// , or <c>null</c> or empty <c>LinearRing</c>s if the empty
        /// point is to be created.
        /// </param>
        /// <param name="factory"></param>
        public Polygon(ILinearRing shell, ILinearRing[] holes, IGeometryFactory factory) : base(factory)
        {        
            if (shell == null) 
                shell = Factory.CreateLinearRing((ICoordinateSequence) null);            
            if (holes == null) 
                holes = new ILinearRing[] { };
            if (HasNullElements(holes)) 
                throw new ArgumentException("holes must not contain null elements");
            if (shell.IsEmpty && HasNonEmptyElements(holes)) 
                throw new ArgumentException("shell is empty but holes are not");
            this.shell = shell;
            this.holes = holes;
        }

        /// <summary>
        /// 
        /// </summary>
        public override ICoordinate Coordinate
        {
            get
            {
                return shell.Coordinate;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override ICoordinate[] Coordinates
        {
            get
            {
                if (IsEmpty)
                    return new ICoordinate[] { };
                ICoordinate[] coordinates = new ICoordinate[NumPoints];
                int k = -1;
                ICoordinate[] shellCoordinates = shell.Coordinates;
                for (int x = 0; x < shellCoordinates.Length; x++)
                {
                    k++;
                    coordinates[k] = shellCoordinates[x];
                }
                for (int i = 0; i < holes.Length; i++)
                {
                    ICoordinate[] childCoordinates = holes[i].Coordinates;
                    for (int j = 0; j < childCoordinates.Length; j++)
                    {
                        k++;
                        coordinates[k] = childCoordinates[j];
                    }
                }
                return coordinates;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override int NumPoints
        {
            get
            {
                int numPoints = shell.NumPoints;
                for (int i = 0; i < holes.Length; i++)
                    numPoints += holes[i].NumPoints;
                return numPoints;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override Dimensions Dimension
        {
            get
            {
                return Dimensions.Surface;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override Dimensions BoundaryDimension
        {
            get
            {
                return Dimensions.Curve;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override bool IsEmpty
        {
            get
            {
                return shell.IsEmpty;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override bool IsSimple
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public ILineString ExteriorRing
        {
            get
            {
                return shell;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public int NumInteriorRings
        {
            get
            {
                return holes.Length;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public ILineString[] InteriorRings
        {
            get
            {
                return holes;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public ILineString GetInteriorRingN(int n) 
        {
            return holes[n];
        }

        /// <summary>
        /// 
        /// </summary>
        public override string GeometryType
        {
            get
            {
                return "Polygon";
            }
        }

        /// <summary> 
        /// Returns the area of this <c>Polygon</c>
    /// </summary>
    /// <returns></returns>
        public override double Area
        {
            get
            {
                double area = 0.0;
                area += Math.Abs(CGAlgorithms.SignedArea(shell.Coordinates));
                for (int i = 0; i < holes.Length; i++)
                    area -= Math.Abs(CGAlgorithms.SignedArea(holes[i].Coordinates));                
                return area;
            }
        }

        /// <summary>
        /// Returns the perimeter of this <c>Polygon</c>.
    /// </summary>
    /// <returns></returns>
        public override double Length
        {
            get
            {
                double len = 0.0;
                len += shell.Length;
                for (int i = 0; i < holes.Length; i++)
                    len += holes[i].Length;
                return len;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override IGeometry Boundary
        {
            get
            {
                if (IsEmpty)
                    return Factory.CreateGeometryCollection(null);
                ILinearRing[] rings = new ILinearRing[holes.Length + 1];
                rings[0] = shell;
                for (int i = 0; i < holes.Length; i++)
                    rings[i + 1] = holes[i];
                if (rings.Length <= 1)
                    return Factory.CreateLinearRing(rings[0].CoordinateSequence);
                return Factory.CreateMultiLineString(rings);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected override IEnvelope ComputeEnvelopeInternal() 
        {
            return shell.EnvelopeInternal;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public override bool EqualsExact(IGeometry other, double tolerance) 
        {
            if (!IsEquivalentClass(other)) 
                return false;

            IPolygon otherPolygon = (IPolygon) other;
            IGeometry thisShell = shell;
            IGeometry otherPolygonShell = otherPolygon.Shell;
            if (!thisShell.EqualsExact(otherPolygonShell, tolerance)) 
                return false;
            if (holes.Length != otherPolygon.Holes.Length) 
                return false;
            if (holes.Length != otherPolygon.Holes.Length) 
                return false;
            for (int i = 0; i < holes.Length; i++) 
                if (!(holes[i]).EqualsExact(otherPolygon.Holes[i], tolerance)) 
                    return false;
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        public override void Apply(ICoordinateFilter filter)
        {
            shell.Apply(filter);
            for (int i = 0; i < holes.Length; i++) 
                holes[i].Apply(filter);            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        public override void Apply(IGeometryFilter filter) 
        {
            filter.Filter(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filter"></param>
        public override void Apply(IGeometryComponentFilter filter) 
        {
            filter.Filter(this);
            shell.Apply(filter);
            for (int i = 0; i < holes.Length; i++) 
                holes[i].Apply(filter);            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override object Clone() 
        {
            Polygon poly = (Polygon) base.Clone();
            poly.shell = (LinearRing) shell.Clone();
            poly.holes = new ILinearRing[holes.Length];
            for (int i = 0; i < holes.Length; i++) 
                poly.holes[i] = (LinearRing) holes[i].Clone();            
            return poly; 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override IGeometry ConvexHull()
        {            
            return ExteriorRing.ConvexHull();         
        }

        /// <summary>
        /// 
        /// </summary>
        public override void Normalize() 
        {
            Normalize(shell, true);
            foreach(ILinearRing hole in Holes)
                Normalize(hole, false);
            Array.Sort(holes);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        protected internal override int CompareToSameClass(object o) 
        {   
            LinearRing thisShell = (LinearRing) shell;
            ILinearRing otherShell = ((IPolygon) o).Shell;
            return thisShell.CompareToSameClass(otherShell);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ring"></param>
        /// <param name="clockwise"></param>        
        private void Normalize(ILinearRing ring, bool clockwise) 
        {
            if (ring.IsEmpty) 
                return;            
            ICoordinate[] uniqueCoordinates = new ICoordinate[ring.Coordinates.Length - 1];
            Array.Copy(ring.Coordinates, 0, uniqueCoordinates, 0, uniqueCoordinates.Length);
            ICoordinate minCoordinate = CoordinateArrays.MinCoordinate(ring.Coordinates);
            CoordinateArrays.Scroll(uniqueCoordinates, minCoordinate);
            Array.Copy(uniqueCoordinates, 0, ring.Coordinates, 0, uniqueCoordinates.Length);
            ring.Coordinates[uniqueCoordinates.Length] = uniqueCoordinates[0];
            if (CGAlgorithms.IsCCW(ring.Coordinates) == clockwise) 
                CoordinateArrays.Reverse(ring.Coordinates);            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override bool IsRectangle
        {
            get
            {
                if (NumInteriorRings != 0) return false;
                if (Shell == null) return false;
                if (Shell.NumPoints != 5) return false;

                // check vertices have correct values
                ICoordinateSequence seq = Shell.CoordinateSequence;                
                Envelope env = (Envelope) EnvelopeInternal;
                for (int i = 0; i < 5; i++)
                {
                    double x = seq.GetX(i);
                    if (!(x == env.MinX || x == env.MaxX)) 
                        return false;
                    
                    double y = seq.GetY(i);
                    if (!(y == env.MinY || y == env.MaxY))
                        return false;
                }

                // check vertices are in right order
                double prevX = seq.GetX(0);
                double prevY = seq.GetY(0);
                for (int i = 1; i <= 4; i++)
                {
                    double x = seq.GetX(i);
                    double y = seq.GetY(i);

                    bool xChanged = x != prevX;
                    bool yChanged = y != prevY;
                    
                    if (xChanged == yChanged)
                        return false;
                    
                    prevX = x;
                    prevY = y;
                }
                return true;
            }
        }

        /* BEGIN ADDED BY MPAUL42: monoGIS team */

        /// <summary>
        /// Constructs a <c>Polygon</c> with the given exterior boundary.
        /// </summary>
        /// <param name="shell">
        /// The outer boundary of the new <c>Polygon</c>,
        /// or <c>null</c> or an empty <c>LinearRing</c> if the empty
        /// polygon is to be created.
        /// </param>
        /// <param name="factory"></param>
        public Polygon(LinearRing shell, GeometryFactory factory) : this(shell, null, factory) { }

        /// <summary>
        /// Constructs a <c>Polygon</c> with the given exterior boundary.
        /// </summary>
        /// <param name="shell">
        /// The outer boundary of the new <c>Polygon</c>,
        /// or <c>null</c> or an empty <c>LinearRing</c> if the empty
        /// polygon is to be created.
        /// </param>
        public Polygon(LinearRing shell) : this(shell, null, DefaultFactory) { }

        /// <summary>
        /// 
        /// </summary>
        public ILinearRing Shell
        {
            get
            {
                return shell;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public ILinearRing[] Holes
        {
            get
            {
                return holes;
            }
        }

        /*END ADDED BY MPAUL42 */

    }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.