Exemple #1
0
        ///<summary>
        /// Converts a linearring to be sure it is clockwise.
        ///</summary>
        ///<remarks>Normal form is a unique representation
        /// for Geometry's. It can be used to test whether two Geometrys are equal in a way that is
        /// independent of the ordering of the coordinates within them. Normal form equality is a stronger
        /// condition than topological equality, but weaker than pointwise equality. The definitions for
        /// normal form use the standard lexicographical ordering for coordinates. Sorted in order of
        /// coordinates means the obvious extension of this ordering to sequences of coordinates.
        ///</remarks>
        private void Normalize(LinearRing ring, bool clockwise)
        {
            if (ring.IsEmpty())
            {
                return;
            }
            Coordinates uniqueCoordinates = new Coordinates();

            for (int i = 0; i < ring.GetNumPoints() - 1; i++)
            {
                uniqueCoordinates.Add(ring.GetCoordinateN(i));                                  // copy all but last one into uniquecoordinates
            }
            Coordinate minCoordinate = MinCoordinate(ring.GetCoordinates());

            Scroll(uniqueCoordinates, minCoordinate);
            Coordinates ringCoordinates = ring.GetCoordinates();

            ringCoordinates.Clear();
            ringCoordinates.AddRange(uniqueCoordinates);
            ringCoordinates.Add(uniqueCoordinates[0].Clone());                          // add back in the closing point.
            if (_cgAlgorithms.IsCCW(ringCoordinates) == clockwise)
            {
                ReversePointOrder(ringCoordinates);
            }
        }
Exemple #2
0
        ///<summary>
        ///  Returns this Geometry's vertices. Do not modify  the array, as it may be the actual array stored
        ///  by this Geometry.  The Geometries contained by composite Geometries must be Geometry's;
        ///  that is, they must implement get Coordinates.
        ///</summary>
        ///<returns>Returns the vertices of this Geometry.</returns>
        public override Coordinates GetCoordinates()
        {
            Coordinates coords = new Coordinates();

            if (IsEmpty())
            {
                return(coords);
            }
            coords.AddRange(_shell.GetCoordinates());

            if (_holes != null)
            {
                for (int i = 0; i < _holes.Length; i++)
                {
                    coords.AddRange(_holes[i].GetCoordinates());
                }
            }
            return(coords);
        }
		private bool IsInside(LinearRing innerRing, LinearRing searchRing)
		{
			
			Coordinates innerRingPts = innerRing.GetCoordinates();
			Coordinates searchRingPts = searchRing.GetCoordinates();

			if (! innerRing.GetEnvelopeInternal().Intersects(searchRing.GetEnvelopeInternal()))
				return false;

			Coordinate innerRingPt = IsValidOp.FindPtNotNode(innerRingPts, searchRing, _graph);
			//Assert.isTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring");

			bool isInside = _cga.IsPointInRing(innerRingPt, searchRingPts);
			if (isInside) 
			{
				_nestedPt = innerRingPt;
				return true;
			}
			return false;
		}
		/// <summary>
		/// Initializes a new instance of the SimplePointInRing class.
		/// </summary>
		public SimplePointInRing(LinearRing ring)
		{		
			_pts = ring.GetCoordinates();
		}
		} // private int Locate( Coordinate p, LineString l )

		/// <summary>
		/// 
		/// </summary>
		/// <param name="p"></param>
		/// <param name="ring"></param>
		/// <returns></returns>
		private int Locate( Coordinate p, LinearRing ring )
		{
			if ( _cga.IsOnLine( p, ring.GetCoordinates() ) ) 
			{
				return Location.Boundary;
			}
			if ( _cga.IsPointInRing( p, ring.GetCoordinates() ) )
			{
				return Location.Interior;
			}
			return Location.Exterior;
		} // private int Locate( Coordinate p, LinearRing ring )
Exemple #6
0
 /// <summary>
 /// Compute a LinearRing from the point list previously collected.
 /// Test if the ring is a hole (i.e. if it is CCW) and set the hole flag 
 /// accordingly.
 /// </summary>
 public void ComputeRing()
 {
     if ( _ring != null ) return;   // don't compute more than once
     // create ring using geometry factory.
     _ring = _geometryFactory.CreateLinearRing( _pts );
     _isHole = _cga.IsCCW( _ring.GetCoordinates() );
 }
Exemple #7
0
        /// <summary>
        ///  The left and right topological location arguments assume that the ring is oriented CW.
        ///  If the ring is in the opposite orientation, the left and right locations must be interchanged.
        /// </summary>
        /// <param name="lr"></param>
        /// <param name="cwLeft"></param>
        /// <param name="cwRight"></param>
        private void AddPolygonRing( LinearRing lr, int cwLeft, int cwRight )
        {
            Coordinates coord = Coordinates.RemoveRepeatedPoints(lr.GetCoordinates());
            if (coord.Count<4)
            {
                _hasTooFewPoints=true;
                _invalidPoint=coord[0];
            }
            int left  = cwLeft;
            int right = cwRight;
            if ( _cga.IsCCW( coord ) )
            {
                left = cwRight;
                right = cwLeft;
            }
            Edge e = new Edge(coord,
                new Label(_argIndex, Location.Boundary, left, right));
            _lineEdgeMap[ lr]= e;

            InsertEdge( e );
            // insert the endpoint as a node, to mark that it is on the boundary
            InsertPoint( _argIndex, coord[0], Location.Boundary );
        }
Exemple #8
0
		///<summary>
		/// Converts a linearring to be sure it is clockwise.
		///</summary>
		///<remarks>Normal form is a unique representation
		/// for Geometry's. It can be used to test whether two Geometrys are equal in a way that is 
		/// independent of the ordering of the coordinates within them. Normal form equality is a stronger 
		/// condition than topological equality, but weaker than pointwise equality. The definitions for 
		/// normal form use the standard lexicographical ordering for coordinates. Sorted in order of 
		/// coordinates means the obvious extension of this ordering to sequences of coordinates.
		///</remarks>
		private void Normalize( LinearRing ring, bool clockwise ) 
		{
			if ( ring.IsEmpty() ) 
			{
				return;
			}
			Coordinates uniqueCoordinates = new Coordinates();
			for ( int i=0; i < ring.GetNumPoints()-1; i++ )
			{
				uniqueCoordinates.Add( ring.GetCoordinateN( i ) );		// copy all but last one into uniquecoordinates
			}
			Coordinate minCoordinate = MinCoordinate( ring.GetCoordinates() );
			Scroll( uniqueCoordinates, minCoordinate );
			Coordinates ringCoordinates = ring.GetCoordinates();
			ringCoordinates.Clear();
			ringCoordinates.AddRange( uniqueCoordinates );
			ringCoordinates.Add( uniqueCoordinates[0].Clone() );		// add back in the closing point.
			if ( _cgAlgorithms.IsCCW( ringCoordinates ) == clockwise )
			{
				ReversePointOrder( ringCoordinates );
			}
		}
		/// <summary>
		/// The side and left and right topological location arguments assume that the ring is oriented CW.
		/// If the ring is in the opposite orientation, the left and right locations must be interchanged
		/// and the side flipped.
		/// </summary>
		/// <param name="lr">lr the LinearRing around which to create the buffer</param>
		/// <param name="distance">distance the distance at which to create the buffer</param>
		/// <param name="side">side the side of the ring on which to construct the buffer line</param>
		/// <param name="cwLeftLoc">cwLeftLoc the location on the L side of the ring (if it is CW)</param>
		/// <param name="cwRightLoc">cwRightLoc the location on the R side of the ring (if it is CW)</param>
		private void AddPolygonRing(LinearRing lr, double distance, int side, int cwLeftLoc, int cwRightLoc)
		{
			
			Coordinates coord = Coordinates.RemoveRepeatedPoints(lr.GetCoordinates());
			
			int leftLoc  = cwLeftLoc;
			int rightLoc = cwRightLoc;
			if (_cga.IsCCW(coord)) 
			{
				leftLoc = cwRightLoc;
				rightLoc = cwLeftLoc;
				side = Position.Opposite(side);
			}
			ArrayList lineList = _lineBuilder.GetRingBuffer(coord, side, distance);
			AddEdges(lineList, leftLoc, rightLoc);
			

			/*  This section was already commented out in the java code.  Leave it commented out...
			Edge e = new Edge(coord,
								new Label(0, Location.BOUNDARY, left, right));

			insertEdge(e);
			// insert the endpoint as a node, to mark that it is on the boundary
			insertPoint(argIndex, coord[0], Location.BOUNDARY);
			*/
		}
Exemple #10
0
		/// <summary>
		/// This routine Checks to see if a shell is properly contained in a hole.
		/// </summary>
		/// <param name="shell"></param>
		/// <param name="hole"></param>
		/// <param name="graph"></param>
		private void CheckShellInsideHole(LinearRing shell, LinearRing hole, GeometryGraph graph)
		{
			
			Coordinates shellPts = shell.GetCoordinates();
			Coordinates holePts = hole.GetCoordinates();
			// TODO: improve performance of this - by sorting pointlists for instance?
			Coordinate shellPt = FindPtNotNode(shellPts, hole, graph);
			// if point is on shell but not hole, Check that the shell is inside the hole
			if (shellPt != null) 
			{
				bool insideHole = _cga.IsPointInRing(shellPt, holePts);
				if (! insideHole)
					_validErr = new TopologyValidationError(
						TopologyValidationError.NestedShells,
						shellPt);
				return;
			}
			Coordinate holePt = FindPtNotNode(holePts, shell, graph);
			// if point is on hole but not shell, Check that the hole is outside the shell
			if (holePt != null) 
			{
				bool insideShell = _cga.IsPointInRing(holePt, shellPts);
				if (insideShell) 
				{
					_validErr = new TopologyValidationError(
						TopologyValidationError.NestedShells,
						holePt);
				}
				return;
			}
			throw new InvalidOperationException("Points in shell and hole appear to be equal.");
		}
Exemple #11
0
		/// <summary>
		/// Check if a shell is incorrectly nested within a polygon.  This is the case
		/// if the shell is inside the polygon shell, but not inside a polygon hole.
		/// If the shell is inside a polygon hole, the nesting is valid.)
		/// 
		/// The algorithm used relies on the fact that the rings must be properly contained.
		/// E.g. they cannot partially overlap (this has been previously Checked by
		/// CheckRelateConsistency
		/// </summary>
		/// <param name="shell"></param>
		/// <param name="p"></param>
		/// <param name="graph"></param>
		private void CheckShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
		{
			
			Coordinates shellPts = shell.GetCoordinates();
			// test if shell is inside polygon shell
			LinearRing polyShell =  (LinearRing) p.GetExteriorRing();
			Coordinates polyPts = polyShell.GetCoordinates();
			Coordinate shellPt = FindPtNotNode(shellPts, polyShell, graph);
			// if no point could be found, we can assume that the shell is outside the polygon
			if (shellPt == null)
				return;
			bool insidePolyShell = _cga.IsPointInRing(shellPt, polyPts);
			if (! insidePolyShell) return;

			// if no holes, this is an error!
			if (p.GetNumInteriorRing() <= 0) 
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.NestedShells,
					shellPt);
				return;
			}

			for (int i = 0; i < p.GetNumInteriorRing(); i++) 
			{
				LinearRing hole = p.GetInteriorRingN( i );
				CheckShellInsideHole(shell, hole, graph);
				if (_validErr != null) return;
			}
			
		}