public void TestAreaPrecisionPerformance() { const double originX = 1000000; const double originY = 5000000; var sw = new Stopwatch(); var sw1 = new Stopwatch(); var sw2 = new Stopwatch(); var sw3 = new Stopwatch(); //-2,23057128323489E-11 sw.Start(); for (var nrVertices = 4; nrVertices <= 5000000; nrVertices *= 2) { var coordinates = new Coordinate[nrVertices + 1]; for (var i = 0; i <= nrVertices; i++) { var vertex = new Coordinate(originX + (1d + Math.Sin( i/(double) nrVertices*2*Math.PI)), originY + (1d + Math.Cos( i/(double) nrVertices*2*Math.PI))); coordinates[i] = vertex; } // close ring coordinates[nrVertices] = coordinates[0]; var g1 = new GeometryFactory().CreateLinearRing(coordinates); var holes = new ILinearRing[] {}; var polygon = (Polygon) new GeometryFactory().CreatePolygon(g1, holes); //Console.WriteLine(polygon); sw1.Start(); var area = polygon.Area; sw1.Stop(); sw2.Start(); var area2 = AccurateSignedArea(coordinates); sw2.Stop(); sw3.Start(); var areaOld = OriginalSignedArea(coordinates); sw3.Stop(); var exactArea = 0.5 * nrVertices * Math.Sin(2 * Math.PI / nrVertices); var eps1 = exactArea - area; var eps2 = exactArea - area2; var eps3 = exactArea - areaOld; //Assert.IsTrue(Math.Abs(eps2) <= Math.Abs(eps3)); Console.WriteLine(string.Format("{0,10},\tnow err: {1,23},\tacc err: {2,23},\told err: {3,23}", nrVertices ,eps1, eps2 ,eps3)); } sw.Stop(); Console.WriteLine("\n\nTime: " + sw.Elapsed); Console.WriteLine("Time Now: " + sw1.ElapsedTicks); Console.WriteLine("Time Acc: " + sw2.ElapsedTicks); Console.WriteLine("Time Old: " + sw3.ElapsedTicks); Assert.IsTrue(true); }
///<summary> /// Determines whether a point lies in a LinearRing, using the ring envelope to short-circuit if possible. ///</summary> /// <param name="p">The point to test</param> /// <param name="ring">A linear ring</param> /// <returns><c>true</c> if the point lies inside the ring</returns> private static Boolean IsPointInRing(Coordinate p, ILinearRing ring) { // short-circuit if point is not in ring envelope if (!ring.EnvelopeInternal.Intersects(p)) return false; return CGAlgorithms.IsPointInRing(p, ring.Coordinates); }
/// <summary> /// Find a point from the list of testCoords /// that is NOT a node in the edge for the list of searchCoords. /// </summary> /// <param name="testCoords"></param> /// <param name="searchRing"></param> /// <param name="graph"></param> /// <returns>The point found, or <c>null</c> if none found.</returns> public static ICoordinate FindPointNotNode(ICoordinate[] testCoords, ILinearRing searchRing, GeometryGraph graph) { // find edge corresponding to searchRing. Edge searchEdge = graph.FindEdge(searchRing); // find a point in the testCoords which is not a node of the searchRing EdgeIntersectionList eiList = searchEdge.EdgeIntersectionList; // somewhat inefficient - is there a better way? (Use a node map, for instance?) foreach(ICoordinate pt in testCoords) if(!eiList.IsIntersection(pt)) return pt; return null; }
/// <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 PolygonSamples() : base(new GeometryFactory(new PrecisionModel(PrecisionModels.Fixed))) { shell = Factory.CreateLinearRing(new ICoordinate[] { new Coordinate(100,100), new Coordinate(200,100), new Coordinate(200,200), new Coordinate(100,200), new Coordinate(100,100), }); hole = Factory.CreateLinearRing(new ICoordinate[] { new Coordinate(120,120), new Coordinate(180,120), new Coordinate(180,180), new Coordinate(120,180), new Coordinate(120,120), }); polygon = Factory.CreatePolygon(shell, new ILinearRing[] { hole, }); }
public static IPolygon Reproject(this IPolygon polygon, ProjectionInfo source, ProjectionInfo target) { var shell = Reproject(polygon.Shell, source, target); ILinearRing[] holes = null; if (polygon.NumHoles > 0) { holes = new ILinearRing[polygon.NumHoles]; var i = 0; foreach (var hole in polygon.Holes) holes[i++] = Reproject(hole, source, target); } return polygon.Factory.CreatePolygon(shell, holes); }
public void Init() { shell = Factory.CreateLinearRing(new ICoordinate[] { new Coordinate(100,100), new Coordinate(200,100), new Coordinate(200,200), new Coordinate(100,200), new Coordinate(100,100), }); // NOTE: Hole is created with not correct order for holes hole = Factory.CreateLinearRing(new ICoordinate[] { new Coordinate(120,120), new Coordinate(180,120), new Coordinate(180,180), new Coordinate(120,180), new Coordinate(120,120), }); polygon = Factory.CreatePolygon(shell, new ILinearRing[] { hole, }); }
/// <summary> /// /// </summary> /// <param name="innerRing"></param> /// <param name="searchRing"></param> /// <returns></returns> private bool IsInside(ILinearRing innerRing, ILinearRing searchRing) { ICoordinate[] innerRingPts = innerRing.Coordinates; ICoordinate[] searchRingPts = searchRing.Coordinates; if (!innerRing.EnvelopeInternal.Intersects(searchRing.EnvelopeInternal)) return false; ICoordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph); Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring"); bool isInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts); if (isInside) { nestedPt = innerRingPt; return true; } return false; }
/// <summary> /// /// </summary> public GMLTesting() { point = Factory.CreatePoint(new Coordinate(100, 100)); ICoordinate[] coordinates = new ICoordinate[] { new Coordinate(10,10), new Coordinate(20,20), new Coordinate(20,10), }; line = Factory.CreateLineString(coordinates); coordinates = new ICoordinate[] { new Coordinate(100,100), new Coordinate(200,100), new Coordinate(200,200), new Coordinate(100,200), new Coordinate(100,100), }; ICoordinate[] interior1 = new ICoordinate[] { new Coordinate(120,120), new Coordinate(180,120), new Coordinate(180,180), new Coordinate(120,180), new Coordinate(120,120), }; ILinearRing linearRing = Factory.CreateLinearRing(coordinates); ILinearRing[] holes = new ILinearRing[] { Factory.CreateLinearRing(interior1), }; polygon = Factory.CreatePolygon(linearRing, holes); coordinates = new ICoordinate[] { new Coordinate(100,100), new Coordinate(200,200), new Coordinate(300,300), new Coordinate(400,400), new Coordinate(500,500), }; multiPoint = Factory.CreateMultiPoint(coordinates); writer = new GMLWriter(); reader = new GMLReader(); }
/// <summary> /// /// </summary> /// <param name="g"></param> private void CheckValid(IGeometry g) { _validErr = null; if (g.IsEmpty) { return; } CheckValidCoordinates(g); if (g is ILineString) { CheckValidLineString(g); } ILinearRing r = g as ILinearRing; if (r != null) { CheckValidRing(r); } IPolygon p = g as IPolygon; if (p != null) { CheckValidPolygon(p); } IMultiPolygon mp = g as IMultiPolygon; if (mp != null) { CheckValidMultipolygon(mp); } else { IGeometryCollection gc = g as IGeometryCollection; if (gc != null) { CheckValidCollection(gc); } } }
/// <summary> /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any. /// The innermost enclosing ring is the <i>smallest</i> enclosing ring. /// The algorithm used depends on the fact that: /// ring A contains ring B iff envelope(ring A) contains envelope(ring B). /// This routine is only safe to use if the chosen point of the hole /// is known to be properly contained in a shell /// (which is guaranteed to be the case if the hole does not touch its shell). /// </summary> /// <param name="testEr">The EdgeRing to test.</param> /// <param name="shellList">The list of shells to test.</param> /// <returns>Containing EdgeRing, if there is one, OR /// null if no containing EdgeRing is found.</returns> public static EdgeRing FindEdgeRingContaining(EdgeRing testEr, IList shellList) { ILinearRing teString = testEr.Ring; IEnvelope testEnv = teString.EnvelopeInternal; EdgeRing minShell = null; IEnvelope minEnv = null; for (IEnumerator it = shellList.GetEnumerator(); it.MoveNext();) { EdgeRing tryShell = (EdgeRing)it.Current; ILinearRing tryRing = tryShell.Ring; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) { minEnv = minShell.Ring.EnvelopeInternal; } bool isContained = false; // the hole envelope cannot equal the shell envelope if (tryEnv.Equals(testEnv)) { continue; } Coordinate testPt = PtNotInList(teString.Coordinates, tryRing.Coordinates); if (tryEnv.Contains(testEnv) && CgAlgorithms.IsPointInRing(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 = tryShell; } } } return(minShell); }
/// <summary> /// This method will cause the ring to be computed. /// It will also check any holes, if they have been assigned. /// </summary> /// <param name="p"></param> public bool ContainsPoint(Coordinate p) { ILinearRing shell = LinearRing; Envelope env = shell.EnvelopeInternal; if (!env.Contains(p)) { return(false); } if (!PointLocation.IsInRing(p, shell.Coordinates)) { return(false); } foreach (EdgeRing hole in _holes) { if (hole.ContainsPoint(p)) { return(false); } } return(true); }
/// <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 LinearRing[] { } } ; 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; }
public void TestIsClosed() { LineString l = (LineString)reader.Read("LINESTRING EMPTY"); Assert.IsTrue(l.IsEmpty); Assert.IsTrue(!l.IsClosed); ILinearRing r = geometryFactory.CreateLinearRing((ICoordinateSequence)null); Assert.IsTrue(r.IsEmpty); Assert.IsTrue(r.IsClosed); IMultiLineString m = geometryFactory.CreateMultiLineString( new ILineString[] { l, r }); Assert.IsTrue(!m.IsClosed); IMultiLineString m2 = geometryFactory.CreateMultiLineString( new ILineString[] { r }); Assert.IsTrue(!m2.IsClosed); }
/// <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> /// <returns> /// A <c>Polygon</c> specified by the next token /// in the stream. /// </returns> private IPolygon ReadPolygonText(IList tokens) { string nextToken = GetNextEmptyOrOpener(tokens); if (nextToken.Equals("EMPTY")) { return(geometryFactory.CreatePolygon( geometryFactory.CreateLinearRing(new ICoordinate[] { }), new ILinearRing[] { })); } List <ILinearRing> holes = new List <ILinearRing>(); ILinearRing shell = ReadLinearRingText(tokens); nextToken = GetNextCloserOrComma(tokens); while (nextToken.Equals(",")) { ILinearRing hole = ReadLinearRingText(tokens); holes.Add(hole); nextToken = GetNextCloserOrComma(tokens); } return(geometryFactory.CreatePolygon(shell, holes.ToArray())); }
public new IMultiPolygon ToCommon() { List <PolygonBuilder> polygonBuilders = new List <PolygonBuilder>(); PolygonBuilder currentBuilder = null; for (int i = 0; i < RingArray.Length; ++i) { ILinearRing commonLinearRing = RingArray[i].ToCommon(); if (currentBuilder == null || !currentBuilder.ExteriorRing.Contains(commonLinearRing)) { currentBuilder = new PolygonBuilder(commonLinearRing); polygonBuilders.Add(currentBuilder); } else { currentBuilder.InteriorRings.Add(commonLinearRing); } } return(new NetTopologySuite.Geometries.MultiPolygon(polygonBuilders.Select(o => o.ToPolygon()).ToArray())); }
/// <summary> /// /// </summary> /// <returns></returns> public bool IsNonNested() { BuildQuadtree(); for (int i = 0; i < rings.Count; i++) { ILinearRing innerRing = (ILinearRing)rings[i]; ICoordinate[] innerRingPts = innerRing.Coordinates; IList results = quadtree.Query(innerRing.EnvelopeInternal); for (int j = 0; j < results.Count; j++) { ILinearRing searchRing = (ILinearRing)results[j]; ICoordinate[] searchRingPts = searchRing.Coordinates; if (innerRing == searchRing) { continue; } if (!innerRing.EnvelopeInternal.Intersects(searchRing.EnvelopeInternal)) { continue; } ICoordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph); Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring"); bool isInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts); if (isInside) { nestedPt = innerRingPt; return(false); } } } return(true); }
public SerializationSamples() : base() { filepath = Path.GetTempPath() + "\\testserialization.bin"; serializer = new BinaryFormatter(); point = Factory.CreatePoint(new Coordinate(100, 100)); coordinates = new ICoordinate[] { new Coordinate(10, 10), new Coordinate(20, 20), new Coordinate(20, 10), }; line = Factory.CreateLineString(coordinates); coordinates = new ICoordinate[] { new Coordinate(100, 100), new Coordinate(200, 100), new Coordinate(200, 200), new Coordinate(100, 200), new Coordinate(100, 100), }; ILinearRing linearRing = Factory.CreateLinearRing(coordinates); polygon = Factory.CreatePolygon(linearRing, null); coordinates = new ICoordinate[] { new Coordinate(100, 100), new Coordinate(200, 200), new Coordinate(300, 300), new Coordinate(400, 400), new Coordinate(500, 500), }; multiPoint = Factory.CreateMultiPoint(coordinates); }
/// <summary> /// This method will cause the ring to be computed. /// It will also check any holes, if they have been assigned. /// </summary> /// <param name="p"></param> public bool ContainsPoint(ICoordinate p) { ILinearRing shell = LinearRing; IEnvelope env = shell.EnvelopeInternal; if (!env.Contains(p)) { return(false); } if (!CGAlgorithms.IsPointInRing(p, shell.Coordinates)) { return(false); } for (IEnumerator i = holes.GetEnumerator(); i.MoveNext();) { EdgeRing hole = (EdgeRing)i.Current; if (hole.ContainsPoint(p)) { return(false); } } return(true); }
/// <summary> /// Constructs a <c>Polygon</c> with the given exterior boundary and /// interior boundaries. /// </summary> /// <param name="inShell"> /// 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="inHoles"> /// 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> /// <exception cref="PolygonException">Holes must not contain null elements</exception> public Polygon(ILinearRing inShell, ILinearRing[] inHoles, IGeometryFactory factory) : base(factory) { if (inShell == null) { inShell = Factory.CreateLinearRing(null); } if (inHoles == null) { inHoles = new LinearRing[] { } } ; if (HasNullElements(inHoles)) { throw new PolygonException(TopologyText.PolygonException_HoleElementNull); } if (inShell.IsEmpty && HasNonEmptyElements(inHoles)) { throw new PolygonException(TopologyText.PolygonException_ShellEmptyButHolesNot); } _shell = inShell; _holes = inHoles; }
/// <inheritdoc/> /// <remarks> /// The <see cref="IPolygon.ExteriorRing"/> is guaranteed to be orientated counter-clockwise. /// <br/>The <see cref="IPolygon.InteriorRings"/> are guaranteed to be orientated clockwise. /// </remarks> public override IPolygon CreatePolygon(ILinearRing shell, ILinearRing[] holes) { if (shell != null) { if (!shell.IsCCW) { shell = ReverseRing(shell); } } if (holes != null) { for (var i = 0; i < holes.Length; i++) { if (holes[i].IsCCW) { holes[i] = ReverseRing(holes[i]); } } } return(base.CreatePolygon(shell, holes)); }
/// <summary> /// /// </summary> /// <param name="p"></param> /// <param name="poly"></param> /// <returns></returns> public static bool ContainsPointInPolygon(ICoordinate p, IPolygon poly) { if (poly.IsEmpty) { return(false); } ILinearRing shell = (ILinearRing)poly.ExteriorRing; if (!IsPointInRing(p, shell)) { return(false); } // now test if the point lies in or on the holes for (int i = 0; i < poly.NumInteriorRings; i++) { ILinearRing hole = (ILinearRing)poly.GetInteriorRingN(i); if (IsPointInRing(p, hole)) { return(false); } } return(true); }
/// <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(); } if (holes == null) { holes = new ILinearRing[] { } } ; if (HasNullElements(CollectionUtil.Cast <ILinearRing, object>(holes))) { throw new ArgumentException("holes must not contain null elements"); } if (shell.IsEmpty && HasNonEmptyElements(CollectionUtil.Cast <ILinearRing, IGeometry>(holes))) { throw new ArgumentException("shell is empty but holes are not"); } _shell = shell; _holes = holes; }
void ExportPolygon(Polygon pol) { // Get the exterior ring ILinearRing xr = GetLinearRing(pol); // Pick up any islands LinearRingCollection irs = null; if (pol.HasAnyIslands) { irs = new LinearRingCollection(); foreach (Island i in pol.Islands) { ILinearRing ir = GetLinearRing(i); irs.Add(ir); } } IGeometry g = m_Factory.CreatePolygon(xr, irs); ExportGeometry(g); }
/// <summary> /// Removes a hole from the polygon. /// </summary> /// <param name="hole">The hole.</param> /// <returns><c>true</c> if the polygon contains the <paramref name="hole" />; otherwise, <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The hole is null.</exception> /// <exception cref="System.ArgumentException">The reference system of the hole does not match the reference system of the polygon.</exception> public virtual Boolean RemoveHole(ILinearRing hole) { if (hole == null) { throw new ArgumentNullException(nameof(hole)); } if (this.HoleCount == 0) { return(false); } for (Int32 holeIndex = 0; holeIndex < this.HoleCount; holeIndex++) { if (this.Holes[holeIndex].Equals(hole)) { this.DeleteCoordinates(holeIndex + 1); return(true); } } return(false); }
/// <summary> /// Creates a <see cref="IGeometry"/> with the same extent as the given envelope. /// </summary> /// <remarks> /// <para> /// The Geometry returned is guaranteed to be valid. /// To provide this behaviour, the following cases occur: /// </para> /// <para> /// If the <c>Envelope</c> is: /// <ul> /// <li>null returns an empty <see cref="IPoint"/></li> /// <li>a point returns a non-empty <see cref="IPoint"/></li> /// <li>a line returns a two-point <see cref="ILineString"/></li> /// <li>a rectangle returns a <see cref="IPolygon"/> whose points are (minx, maxy), (minx, maxy), (maxx, maxy), (maxx, miny).</li> /// </ul> /// </para> /// </remarks> /// <param name="envelope">The <c>Envelope</c></param> /// <returns> /// An empty <c>Point</c> (for null <c>Envelope</c>s), a <c>Point</c> (when min x = max x and min y = max y) or a <c>Polygon</c> (in all other cases) /// </returns> public virtual IGeometry ToGeometry(Envelope envelope) { // null envelope - return empty point geometry if (envelope.IsNull) { return(CreatePoint((ICoordinateSequence)null)); } // point? if (envelope.MinX == envelope.MaxX && envelope.MinY == envelope.MaxY) { return(CreatePoint(new Coordinate(envelope.MinX, envelope.MinY))); } // vertical or horizontal line? if (envelope.MinX == envelope.MaxX || envelope.MinY == envelope.MaxY) { return(CreateLineString(new[] { new Coordinate(envelope.MinX, envelope.MinY), new Coordinate(envelope.MaxX, envelope.MaxY) })); } // return CW polygon ILinearRing ring = CreateLinearRing(new[] { new Coordinate(envelope.MinX, envelope.MinY), new Coordinate(envelope.MinX, envelope.MaxY), new Coordinate(envelope.MaxX, envelope.MaxY), new Coordinate(envelope.MaxX, envelope.MinY), new Coordinate(envelope.MinX, envelope.MinY) }); return(CreatePolygon(ring, null)); }
private static IPolygon ReadPolygon(PostGis2GeometryHeader header, BinaryReader reader) { var numRings = reader.ReadInt32(); if (numRings == 0) { return(header.Factory.CreatePolygon((ILinearRing)null)); } var pointsPerRing = new int[numRings]; int i; for (i = 0; i < numRings; i++) { pointsPerRing[i] = reader.ReadInt32(); } //padding if (numRings % 2 != 0) { reader.ReadInt32(); } //read shell var shell = (ILinearRing)ReadLineString(header, reader, pointsPerRing[0], true); //read holes var holes = new ILinearRing[numRings - 1]; for (i = 1; i < numRings; i++) { holes[i - 1] = (ILinearRing)ReadLineString(header, reader, pointsPerRing[i], true); } //create polygon return(header.Factory.CreatePolygon(shell, holes)); }
public Ring(ILinearRing ring) { Points = new List <XYZ>(); foreach (var point in ring.Coordinates) { double x = point.X; double y = point.Y; if (x > Right) { Right = x; } if (x < Left) { Left = x; } if (y > Top) { Top = y; } if (y < Bottom) { Bottom = y; } Points.Add(new XYZ() { x = x, y = y }); } segments = new List <Segment>(); for (int i = 0; i < Points.Count; i++) { var p1 = Points[i]; var p2 = Points[(i + 1) % Points.Count]; segments.Add(new Segment(p1, p2)); } }
protected override IEnumerable <IFeature> CreateFeatures(MapFeature mapFeature) { var geometryList = new List <IPolygon>(); foreach (MapGeometry mapGeometry in mapFeature.MapGeometries) { IEnumerable <Point2D>[] pointCollections = mapGeometry.PointCollections.Select(CreateClosedRingIfNecessary).ToArray(); Coordinate[] outerRingCoordinates = ConvertPoint2DElementsToCoordinates(pointCollections[0]); ILinearRing outerRing = new LinearRing(outerRingCoordinates); var innerRings = new ILinearRing[pointCollections.Length - 1]; for (var i = 1; i < pointCollections.Length; i++) { Coordinate[] innerRingCoordinates = ConvertPoint2DElementsToCoordinates(pointCollections[i]); innerRings[i - 1] = new LinearRing(innerRingCoordinates); } IPolygon polygon = new Polygon(outerRing, innerRings); geometryList.Add(polygon); } yield return(new Feature(GetGeometry(geometryList))); }
/// <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(ILinearRing lr, Locations cwLeft, Locations cwRight) { ICoordinate[] coord = CoordinateArrays.RemoveRepeatedPoints(lr.Coordinates); if (coord.Length < 4) { hasTooFewPoints = true; invalidPoint = coord[0]; return; } Locations left = cwLeft; Locations right = cwRight; if (CGAlgorithms.IsCCW(coord)) { left = cwRight; right = cwLeft; } Edge e = new Edge(coord, new Label(argIndex, Locations.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], Locations.Boundary); }
/// <summary> /// /// </summary> /// <param name="geometry"></param> /// <param name="coordinateSpace">The size needed for each coordinate</param> /// <returns></returns> protected int GetByteStreamSize(ILinearRing geometry, int coordinateSpace) { return(GetByteStreamSize(geometry.CoordinateSequence, coordinateSpace)); }
private void ReadPolygonShape(Shape shape) { List <ILinearRing> shells = new List <ILinearRing>(); List <ILinearRing> holes = new List <ILinearRing>(); foreach (PartRange part in shape.Range.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 (shape.M != null && shape.M.Length > 0) { c.M = shape.M[i]; } if (shape.Z != null && shape.Z.Length > 0) { c.Z = shape.Z[i]; } i++; coords.Add(c); } LinearRing ring = new LinearRing(coords.ToArray()); if (shape.Range.Parts.Count == 1) { shells.Add(ring); } else { if (CGAlgorithms.IsCCW(ring.Coordinates)) { holes.Add(ring); } else { shells.Add(ring); } } } if (shells.Count == 0 && holes.Count > 0) { shells = holes; holes = new List <ILinearRing>(); } //// 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 for (int i = 0; i < holes.Count; i++) { ILinearRing testRing = holes[i]; ILinearRing minShell = null; Envelope minEnv = null; Envelope testEnv = testRing.EnvelopeInternal; Coordinate testPt = testRing.Coordinates[0]; for (int j = 0; j < shells.Count; j++) { ILinearRing tryRing = shells[j]; Envelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) { minEnv = minShell.EnvelopeInternal; } // Check if this new containing ring is smaller than the current minimum ring if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, tryRing.Coordinates) || (PointInList(testPt, tryRing.Coordinates)))) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } holesForShells[j].Add(holes[i]); } } } var polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) { polygons[i] = new Polygon(shells[i], holesForShells[i].ToArray()); } if (polygons.Length == 1) { _basicGeometry = polygons[0]; } else { // It's a multi part _basicGeometry = new MultiPolygon(polygons); } _featureType = FeatureType.Polygon; }
/// <summary> /// /// </summary> /// <param name="linearRing"></param> /// <param name="ordinates"></param> /// <param name="writer"></param> private void Write(ILinearRing linearRing, Ordinates ordinates, BinaryWriter writer) { Write(linearRing.CoordinateSequence, ordinates, writer, false); }
/// <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> /// <returns>A <see cref="IPolygon"/> object</returns> public virtual IPolygon CreatePolygon(ILinearRing shell, ILinearRing[] holes) { return(new Polygon(shell, holes, this)); }
/// <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 geometry is to be created.</param> /// <returns>the created Polygon</returns> /// <exception cref="ArgumentException">If the boundary ring is invalid</exception> public virtual IPolygon CreatePolygon(ILinearRing shell) { return(CreatePolygon(shell, null)); }
private static void ExtractInteriorPolygon(ILinearRing[] holes, PolygonType sur) { Collection<AbstractRingPropertyType> lin = sur.Interior as Collection<AbstractRingPropertyType>; int i = 0; foreach (AbstractRingPropertyType ringis in lin) { LinearRingType lii = ringis.Ring as LinearRingType; foreach (DirectPositionListType rings in lii.Items) { List<Coordinate> lstCoor = ExtractCoordinates(rings); holes[i]=new LinearRing(lstCoor); i++; } } }
///<summary> /// Simplifies a LinearRing. If the simplification results in a degenerate ring, remove the component. ///</summary> /// <returns>null if the simplification results in a degenerate ring</returns> protected override IGeometry TransformLinearRing(ILinearRing geom, IGeometry parent) { Boolean removeDegenerateRings = parent is IPolygon; IGeometry simpResult = base.TransformLinearRing(geom, parent); if (removeDegenerateRings && !(simpResult is ILinearRing)) return null; return simpResult; }
/// <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 Coordinate[] coord = _pts.ToArray(); /* new Coordinate[_pts.Count]; for (int i = 0; i < _pts.Count; i++) coord[i] = (Coordinate) _pts[i]; */ _ring = _geometryFactory.CreateLinearRing(coord); _isHole = CGAlgorithms.IsCCW(_ring.Coordinates); }
/// <summary> /// /// </summary> /// <param name="geometryFactory"></param> /// <returns></returns> public IPolygon ToPolygon(IGeometryFactory geometryFactory) { ILinearRing[] holeLR = new ILinearRing[_holes.Count]; for (int i = 0; i < _holes.Count; i++) holeLR[i] = _holes[i].LinearRing; IPolygon poly = geometryFactory.CreatePolygon(LinearRing, holeLR); return poly; }
/// <summary> /// /// </summary> /// <param name="ring"></param> public McPointInRing(ILinearRing ring) { _ring = ring; BuildIndex(); }
/// <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> /// /// </summary> /// <param name="linearRing"></param> /// <param name="writer"></param> protected void Write(ILinearRing linearRing, XmlTextWriter writer) { writer.WriteStartElement("LinearRing", GMLElements.gmlNS); WriteCoordinates(linearRing.Coordinates, writer); writer.WriteEndElement(); }
public void Add(ILinearRing ring) { _rings.Add(ring); _totalEnv.ExpandToInclude(ring.EnvelopeInternal); }
/// <summary> /// /// </summary> /// <param name="ring"></param> /// <param name="writer"></param> protected void Write(ILinearRing linearRing, BinaryWriter writer) { Write(linearRing.Coordinates, linearRing, writer); }
private int _crossings; // number of segment/ray crossings /// <summary> /// /// </summary> /// <param name="ring"></param> public SIRtreePointInRing(ILinearRing ring) { _ring = ring; BuildIndex(); }
private IGeometry CreatePolygonFromDataRow(DataRow dr, string ShapeColumnName) { byte[] shapeBytes = dr[ShapeColumnName] as byte[]; //紧接着前两个点是几何的包围盒,也就是16*2=32个字节 //然后是4个字节,代表有几个部分;然后是4个字节,代表有多少个点,紧接着的每四个字节代表每个部分开始点的位置 byte[] numSkipByte = new byte[4]; Array.Copy(shapeBytes, 4 + 32, numSkipByte, 0, 4); int numParts = BitConverter.ToInt32(numSkipByte, 0); byte[] numPtByte = new byte[4]; Array.Copy(shapeBytes, 4 + 32 + 4, numPtByte, 0, 4); int numPt = BitConverter.ToInt32(numPtByte, 0); //获取各个多边形的分割索引号起始点序号 int[] startIdx = new int[numParts]; byte[] temp = new byte[4]; for (int k = 0; k < numParts; k++) { Array.Copy(shapeBytes, 4 + 32 + 4 + 4 + k * 4, temp, 0, 4); startIdx[k] = BitConverter.ToInt32(temp, 0); } //去掉坐标点之前的字节 byte[] shapeIgnoreHeadByte = new byte[shapeBytes.Length - 4 - 32 - 4 - 4 - 4 * numParts]; Array.Copy(shapeBytes, 4 + 32 + 4 + 4 + 4 * numParts, shapeIgnoreHeadByte, 0, shapeIgnoreHeadByte.Length); ILinearRing[] linearRings = new ILinearRing[numParts]; for (int k = 0; k < startIdx.Length; k++) { int sIdx = startIdx[k]; //下一个部分起点序号 int endIdx = k + 1 < startIdx.Length ? startIdx[k + 1] : numPt; //4+32:几何类型和包围盒字节 //紧接着的4+4是多边形个数和总点数; //跳过4 * numPolygon个字节 Coordinate[] pCoords = new Coordinate[endIdx - sIdx]; int i = 0; Coordinate coor; byte[] geo = new byte[8]; for (int j = sIdx * 16; j < endIdx * 16; j += 16) { Array.Copy(shapeIgnoreHeadByte, j, geo, 0, geo.Length); coor = new Coordinate(); coor.X = BitConverter.ToDouble(geo, 0); Array.Copy(shapeIgnoreHeadByte, j + 8, geo, 0, geo.Length); coor.Y = BitConverter.ToDouble(geo, 0); pCoords[i++] = coor; } ILinearRing t_Ring = new LinearRing(pCoords); linearRings[k] = t_Ring; pCoords = null; } IGeometry result = null; if (linearRings.Length == 1) { result = new Polygon(linearRings[0]); } else { //通过测试初步判定,多边形孔紧跟着外壳存储 Stack <Polygon> pStack = new Stack <Polygon>(); pStack.Push(new Polygon(linearRings[0])); for (int i = 1; i < linearRings.Length; i++) { Polygon pGeo = pStack.Pop(); if (pGeo.Contains(linearRings[i])) { Polygon poly = pGeo as Polygon; ILinearRing[] holes = new LinearRing[poly.Holes.Length + 1]; Array.Copy(poly.Holes, holes, poly.Holes.Length); holes[holes.Length - 1] = linearRings[i]; pStack.Push(new Polygon(poly.Shell, holes)); } else { pStack.Push(pGeo);//还原 pStack.Push(new Polygon(linearRings[i])); } } if (pStack.Count > 1) { result = new MultiPolygon(pStack.ToArray()); } else { result = pStack.Pop(); } } shapeIgnoreHeadByte = null;//释放 shapeBytes = null; //return new Polygon(shell, holes.ToArray()); return(result); }
public void PolygonHoles() { var coords = new Coordinate[20]; var rnd = new Random(); var center = new Coordinate((rnd.NextDouble() * 360) - 180, (rnd.NextDouble() * 180) - 90); // Shell Coordinates var coordscheck = new GeoAPI.Geometries.Coordinate[20]; for (var i = 0; i < 19; i++) { var x = center.X + Math.Cos((i * 10) * Math.PI / 10); var y = center.Y + (i * 10) * Math.PI / 10; coords[i] = new Coordinate(x, y); coordscheck[i] = new GeoAPI.Geometries.Coordinate(x, y); } coordscheck[19] = new GeoAPI.Geometries.Coordinate(coords[0].X, coords[0].Y); coords[19] = new Coordinate(coords[0].X, coords[0].Y); // Shell Rings var ring = new LinearRing(coords); var gf = new NetTopologySuite.Geometries.GeometryFactory(); var ringCheck = gf.CreateLinearRing(coordscheck); // Hole Coordinates var coordsholecheck = new GeoAPI.Geometries.Coordinate[20]; var coordshole = new Coordinate[20]; for (var i = 0; i < 20; i++) { var x = center.X + Math.Cos((i * 10) * Math.PI / 20); var y = center.Y + (i * 10) * Math.PI / 20; coordshole[i] = new Coordinate(x, y); coordsholecheck[i] = new GeoAPI.Geometries.Coordinate(x, y); } coordshole[19] = new Coordinate(coordshole[0].X, coordshole[0].Y); coordsholecheck[19] = new GeoAPI.Geometries.Coordinate(coordshole[0].X, coordshole[0].Y); // Hole LinearRing Arrays var hole = new LinearRing(coordshole); var holes = new ILinearRing[1]; var holeCheck = gf.CreateLinearRing(coordsholecheck); var holescheck = new GeoAPI.Geometries.ILinearRing[1]; holes[0] = hole; holescheck[0] = holeCheck; var pg = new Polygon(ring, holes); var polygonCheck = gf.CreatePolygon(ringCheck, holescheck); var areaCheck = polygonCheck.Area; var area = pg.Area; Assert.IsTrue(Math.Abs(area - areaCheck) < 1e-6); }
public static double FindHoleArea(ObjectId parcelId) { var polylineIds = CadUtils.FindAllPolylines(Application.DocumentManager.MdiActiveDocument); var datebase = Application.DocumentManager.MdiActiveDocument.Database; var dictionary = new Dictionary <ObjectId, double>(); using (var tr = datebase.TransactionManager.StartTransaction()) { // 读入多边形数据 var reader = new DwgReader(); var polygons = new List <IPolygon>(); var quadtree = new Quadtree <IGeometry>(); foreach (ObjectId polylineId in polylineIds) { var polygon = reader.ReadEntityAsPolygon(tr, polylineId) as IPolygon; if (polygon != null) { polygons.Add(polygon); quadtree.Insert(polygon.EnvelopeInternal, polygon); } } // 遍历多边形,如果有洞,开始计算 foreach (var polygon in polygons) { // 找洞 var insidePolygons = new List <IPolygon>(); foreach (var geom in quadtree.Query(polygon.EnvelopeInternal)) { var insidePolygon = geom as IPolygon; if (insidePolygon != null && polygon.Contains(insidePolygon) && !insidePolygon.Equals(polygon) && // 不是同一个 insidePolygon.UserData != polygon.UserData) { insidePolygons.Add(insidePolygon); } } // 算面积 var polygonId = (ObjectId)polygon.UserData; var linearRings = new List <ILinearRing>(); if (insidePolygons.Any()) { foreach (var insidePolygon in insidePolygons) { ILinearRing linearRing = reader.GeometryFactory.CreateLinearRing(insidePolygon.ExteriorRing.CoordinateSequence); if (!linearRing.IsCCW) { linearRing.Reverse(); } linearRings.Add(linearRing); } } IPolygon newPolygon = reader.GeometryFactory.CreatePolygon(polygon.Shell, linearRings.ToArray()); dictionary.Add(polygonId, newPolygon.Area); } tr.Commit(); } return(dictionary[parcelId]); }
public static IPolygon CreatePolygon(ILinearRing shell, ILinearRing[] holes) { return geomFactory.CreatePolygon(shell, holes); }
/// <summary> /// /// </summary> /// <param name="ring"></param> /// <param name="writer"></param> protected virtual void Write(ILinearRing ring, BinaryWriter writer) { writer.Write(ring.NumPoints); for (int i = 0; i < ring.Coordinates.Count; i++) Write(ring.Coordinates[i], writer); }
/// <summary> /// /// </summary> /// <param name="ring"></param> /// <param name="writer"></param> protected void Write(ILinearRing ring, BinaryWriter writer) { writer.Write((int) ring.NumPoints); for (int i = 0; i < ring.Coordinates.Length; i++) Write(ring.Coordinates[i], writer); }
/// <summary> /// Reads a <see cref="IPolygon"/> 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="IPolygon"/> geometry</returns> protected IGeometry ReadPolygon(BinaryReader reader, CoordinateSystem cs, int srid) { IGeometryFactory factory = _geometryServices.CreateGeometryFactory(_precisionModel, srid, _sequenceFactory); ILinearRing exteriorRing = null; ILinearRing[] interiorRings = null; int numRings = reader.ReadInt32(); if (numRings > 0) { exteriorRing = ReadLinearRing(reader, cs, srid); interiorRings = new ILinearRing[numRings - 1]; for (int i = 0; i < numRings - 1; i++) interiorRings[i] = ReadLinearRing(reader, cs, srid); } return factory.CreatePolygon(exteriorRing, interiorRings); }
private IBasicGeometry GetPolygon(MultiSurfaceType multi) { Polygon[] p = new Polygon[multi.SurfaceMemberItems.Count]; ; int npoly = 0; foreach (SurfacePropertyType member in multi.SurfaceMemberItems) { ILinearRing shell = null; ILinearRing[] holes = null; PolygonType sur = ExtractShellPolygon(ref shell, member); if (sur.Interior.Count == 0 && shell !=null) p[npoly] = new Polygon(shell); else { holes = new ILinearRing[sur.Interior.Count]; ExtractInteriorPolygon(holes, sur); p[npoly] = new Polygon(shell, holes); } npoly++; } return new MultiPolygon(p); }
/// <summary> /// /// </summary> /// <param name="ring"></param> public void Add(ILinearRing ring) { rings.Add(ring); }
private static PolygonType ExtractShellPolygon(ref ILinearRing shell, SurfacePropertyType member) { PolygonType sur = member.Surface as PolygonType; LinearRingType li = sur.Exterior.Ring as LinearRingType; foreach (DirectPositionListType rings in li.Items) { List<Coordinate> lstCoor = ExtractCoordinates(rings); shell = new LinearRing(lstCoor); } return sur; }
/// <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; } }
/// <summary> /// /// </summary> /// <param name="geometry"></param> /// <returns></returns> protected int SetByteStream(ILinearRing geometry) { return SetByteStream(geometry.Coordinates, geometry); }
/// <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); }
/// <summary> /// Transforms a <see cref="LinearRing" /> object. /// </summary> /// <param name="r"></param> /// <param name="transform"></param> /// <returns></returns> public static ILinearRing TransformLinearRing(ILinearRing r, IMathTransform transform) { try { List<ICoordinate> coords = ExtractCoordinates(r, transform); return new LinearRing(coords.ToArray()); } catch { return null; } }
private void HolesCS(object sender, EventArgs e) { //Defines a new coordinate array Coordinate[] coords = new Coordinate[20]; //Defines a new random number generator Random rnd = new Random(); //defines a randomly generated center for teh polygon Coordinate center = new Coordinate((rnd.NextDouble() * 360) - 180, (rnd.NextDouble() * 180) - 90); for (int i = 0; i < 19; i++) { //generates random coordinates and adds those coordinates to the array coords[i] = new Coordinate(center.X + Math.Cos((i * 10) * Math.PI / 10), center.Y + (i * 10) * Math.PI / 10); } //sets the last coordinate equal to the first, this 'closes' the polygon coords[19] = new Coordinate(coords[0].X, coords[0].Y); //defines a new LingRing from the coordinates LinearRing Ring = new LinearRing(coords); //Repeates the process, but generates a LinearRing with a smaller area, this will be the hole in the polgyon Coordinate[] coordshole = new Coordinate[20]; for (int i = 0; i < 20; i++) { coordshole[i] = new Coordinate(center.X + Math.Cos((i * 10) * Math.PI / 20), center.Y + (i * 10) * Math.PI / 20); } coordshole[19] = new Coordinate(coordshole[0].X, coordshole[0].Y); LinearRing Hole = new LinearRing(coordshole); //This steps addes the hole LinerRing to a ILinearRing Array //A Polgyon can contain multiple holes, thus a Array of Hole is required ILinearRing[] Holes = new ILinearRing[1]; Holes[0] = Hole; //This passes the Ring, the polygon shell, and the Holes Array, the holes Polygon pg = new Polygon(Ring, Holes); //Feature f = new Feature(); FeatureSet fs = new FeatureSet(pg.FeatureType); //f = new Feature(pg); fs.Features.Add(pg); fs.SaveAs("C:\\Temp\\hole.shp", true); }