public void CanReadWriteSingleRingPolygonXyz() { IPolygon poly = GeometryFactory.CreatePolygon(2600000, 1200000, 2601000, 1201000, 400); WkbGeometryWriter writer = new WkbGeometryWriter(); byte[] wkb = writer.WritePolygon(poly); // Wkx var ordinates = Ordinates.Xyz; LinearRing wkxLinearRing = ToWkxLinearRing(GeometryUtils.GetWKSPointZs(poly), ordinates); byte[] wkx = ToChristianSchwarzWkb(ToWkxPolygon(wkxLinearRing)); Assert.AreEqual(wkx, wkb); // Bonus test: Geom WkbGeomWriter geomWriter = new WkbGeomWriter(); RingGroup ringGroup = GeometryConversionUtils.CreateRingGroup(poly); byte[] wkbGeom = geomWriter.WritePolygon(ringGroup, ordinates); Assert.AreEqual(wkb, wkbGeom); WkbGeometryReader reader = new WkbGeometryReader(); IPolygon restored = reader.ReadPolygon(new MemoryStream(wkb)); Assert.IsTrue(GeometryUtils.AreEqual(poly, restored)); WkbGeomReader geomReader = new WkbGeomReader(); Assert.IsTrue( ringGroup.Equals(geomReader.ReadPolygon(new MemoryStream(wkbGeom)))); }
public static void AddRingGroup(IMultiPatch result, RingGroup ringGroup, bool simplify, bool setPointIds) { IRing ringTemplate = GeometryFactory.CreateEmptyRing(result); int?pointId = setPointIds ? ringGroup.Id : null; if (simplify) { IPolygon poly = CreatePolygon(result, ringTemplate, ringGroup); GeometryUtils.Simplify(poly); if (!poly.IsEmpty) { AddToMultipatch(result, poly, false, pointId); return; } } Linestring exteriorRing = ringGroup.ExteriorRing; IList <Linestring> interiorRings = ringGroup.InteriorRings.ToList(); AddToMultipatch(result, ringTemplate, exteriorRing, interiorRings, false, pointId); }
public static RingGroup CreateRingGroup([NotNull] IRing exterior, [CanBeNull] IList <IRing> interior) { Assert.ArgumentNotNull(exterior, nameof(exterior)); if (interior == null) { interior = new List <IRing>(0); } Linestring exteriorRing = CreateLinestring(Assert.NotNull(exterior)); Assert.True(exteriorRing.IsClosed, "Expected a closed outer ring"); List <Linestring> interiorRings = new List <Linestring>(interior.Count); foreach (IRing innerRing in interior) { var interiorLinestring = new Linestring(CreateLinestring(innerRing)); Assert.True(exteriorRing.IsClosed, "Expected only closed inner rings"); interiorRings.Add(interiorLinestring); } var result = new RingGroup(exteriorRing, interiorRings); return(result); }
public void CanWritePolygonWithInnerRing() { var ring1 = new List <Pnt3D> { new Pnt3D(0, 0, 9), new Pnt3D(0, 100, 8), new Pnt3D(100, 100, 5), new Pnt3D(100, 20, 9) }; RingGroup polygon = CreatePoly(ring1); polygon.AddInteriorRing(new Linestring(new[] { new Pnt3D(25, 50, 0), new Pnt3D(50, 50, 0), new Pnt3D(50, 75, 0), new Pnt3D(25, 75, 0), new Pnt3D(25, 50, 0) } )); WkbGeomWriter writer = new WkbGeomWriter(); byte[] bytes = writer.WritePolygon(polygon); WkbGeomReader reader = new WkbGeomReader(); RingGroup deserialized = reader.ReadPolygon(new MemoryStream(bytes)); Assert.IsTrue(deserialized.Equals(polygon)); }
public static RingGroup CreateRingGroup([NotNull] GeometryPart part) { RingGroup result = CreateRingGroup( Assert.NotNull(part.MainOuterRing), part.InnerRings.Cast <IRing>().ToList()); return(result); }
private static RingGroup CreatePoly(List <Pnt3D> points) { Linestring ring = CreateRing(points); RingGroup poly = new RingGroup(ring); return(poly); }
private static IList <RingGroup> CutRingGroupPlanar( [NotNull] RingGroup ringGroup, [NotNull] IPolyline cutLine, double tolerance, ChangeAlongZSource zSource, double zTolerance) { cutLine = GeometryFactory.Clone(cutLine); if (GeometryUtils.IsZAware(cutLine) && zSource != ChangeAlongZSource.Target) { ((IZAware)cutLine).DropZs(); } Plane3D plane = null; if (zSource == ChangeAlongZSource.SourcePlane) { plane = ChangeAlongZUtils.GetSourcePlane( ringGroup.ExteriorRing.GetPoints().ToList(), zTolerance); } GeometryUtils.Simplify(cutLine, true, true); MultiPolycurve cutLinestrings = new MultiPolycurve( GeometryUtils.GetPaths(cutLine).Select( cutPath => GeometryConversionUtils.CreateLinestring(cutPath))); IList <RingGroup> resultGroups = GeomTopoOpUtils.CutPlanar(ringGroup, cutLinestrings, tolerance); foreach (RingGroup resultPoly in resultGroups) { resultPoly.Id = ringGroup.Id; if (plane != null) { resultPoly.AssignUndefinedZs(plane); } else { resultPoly.InterpolateUndefinedZs(); } } Marshal.ReleaseComObject(cutLine); if (resultGroups.Count == 0) { // Return uncut original resultGroups.Add(ringGroup); } return(resultGroups); }
public void CanReadWriteSingleExteriorRingWithIslandsPolygonXyz() { ISpatialReference sr = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); IPolygon outerRing = GeometryFactory.CreatePolygon(2600000, 1200000, 2601000, 1201000, 432); outerRing.SpatialReference = sr; IPolygon innerRing = GeometryFactory.CreatePolygon(2600100, 1200100, 2600200, 1200200, 321); innerRing.SpatialReference = sr; IPolygon polyWithHole = (IPolygon)IntersectionUtils.Difference(outerRing, innerRing); WkbGeometryWriter writer = new WkbGeometryWriter(); byte[] wkb = writer.WritePolygon(polyWithHole); // Wkx var ordinates = Ordinates.Xyz; IGeometry exteriorRing = GeometryUtils.GetParts(polyWithHole).First(); IGeometry interiorRing = GeometryUtils.GetPaths(polyWithHole).Last(); LinearRing wkxOuterRing = ToWkxLinearRing(exteriorRing, ordinates); LinearRing wkxInnerRing = ToWkxLinearRing(interiorRing, ordinates); byte[] wkx = ToChristianSchwarzWkb(ToWkxPolygon(wkxOuterRing, new[] { wkxInnerRing })); Assert.AreEqual(wkx, wkb); // Bonus test: Geom WkbGeomWriter geomWriter = new WkbGeomWriter(); RingGroup ringGroup = GeometryConversionUtils.CreateRingGroup(polyWithHole); byte[] wkbGeom = geomWriter.WritePolygon(ringGroup, ordinates); Assert.AreEqual(wkb, wkbGeom); WkbGeometryReader reader = new WkbGeometryReader(); IPolygon restored = reader.ReadPolygon(new MemoryStream(wkb)); Assert.IsTrue(GeometryUtils.AreEqual(polyWithHole, restored)); // Geom: WkbGeomReader geomReader = new WkbGeomReader(); Assert.IsTrue( ringGroup.Equals(geomReader.ReadPolygon(new MemoryStream(wkbGeom)))); }
public byte[] WritePolygon([NotNull] RingGroup ringGroup, Ordinates ordinates = Ordinates.Xyz) { // TODO: Initialize with the proper size or allow providing the actual byte[] MemoryStream memoryStream = InitializeWriter(); WriteWkbType(WkbGeometryType.Polygon, ordinates); IList <IPointList> rings = ringGroup.GetLinestrings().Cast <IPointList>().ToList(); WritePolygonCore(rings, ordinates); return(memoryStream.ToArray()); }
public RingGroup ReadPolygon(Stream stream) { using (BinaryReader reader = InitializeReader(stream)) { ReadWkbType(reader, true, out WkbGeometryType geometryType, out Ordinates ordinates); if (geometryType == WkbGeometryType.Polygon) { RingGroup result = ReadPolygonCore(reader, ordinates); return(result); } throw new NotSupportedException($"Cannot read {geometryType} as Polygon."); } }
public void CanWriteAndReadMultiPolygonWithInnerRing() { var ring1 = new List <Pnt3D> { new Pnt3D(0, 0, 9), new Pnt3D(0, 100, 8), new Pnt3D(100, 100, 5), new Pnt3D(100, 20, 9) }; var disjoint = new List <Pnt3D>(); disjoint.Add(new Pnt3D(140, -10, 0)); disjoint.Add(new Pnt3D(140, 30, 23)); disjoint.Add(new Pnt3D(300, 30, 56)); disjoint.Add(new Pnt3D(300, -10, 0)); RingGroup poly1 = CreatePoly(ring1); poly1.AddInteriorRing(new Linestring(new[] { new Pnt3D(25, 50, 0), new Pnt3D(50, 50, 0), new Pnt3D(50, 75, 0), new Pnt3D(25, 75, 0), new Pnt3D(25, 50, 0) } )); Linestring disjointRing = CreateRing(disjoint); var poly2 = new RingGroup(disjointRing); var multipolygon = new List <RingGroup>(new[] { poly1, poly2 }); WkbGeomWriter writer = new WkbGeomWriter(); byte[] bytes = writer.WriteMultipolygon(multipolygon); WkbGeomReader reader = new WkbGeomReader(); IList <RingGroup> deserialized = reader.ReadMultiPolygon(new MemoryStream(bytes)); Assert.IsTrue(deserialized[0].Equals(multipolygon[0])); Assert.IsTrue(deserialized[1].Equals(multipolygon[1])); }
public static IPolygon CreatePolygon(IGeometry template, IRing ringTemplate, RingGroup ringGroup) { IPolygon poly = GeometryFactory.CreateEmptyPolygon(template); IRing mainRing = CreateRing(ringGroup.ExteriorRing, ringTemplate); ((IGeometryCollection)poly).AddGeometry(mainRing); foreach (Linestring interiorRing in ringGroup.InteriorRings) { IRing inner = CreateRing(interiorRing, ringTemplate); ((IGeometryCollection)poly).AddGeometry(inner); } ((IGeometryCollection)poly).GeometriesChanged(); return(poly); }
private RingGroup ReadPolygonCore(BinaryReader reader, Ordinates ordinates) { int ringCount = checked ((int)reader.ReadUInt32()); if (ringCount > 0) { bool reverseOrder = !AssumeWkbPolygonsClockwise; GeomBuilder geometryBuilder = new GeomBuilder(reverseOrder); List <Linestring> rings = ReadLinestringsCore(reader, ordinates, ringCount, geometryBuilder).ToList(); RingGroup result = new RingGroup(rings.First(), rings.Skip(1)); return(result); } // Allow empty? return(null); }
private static void CutAndAssignToFootprintParts( [NotNull] GeometryPart multipatchPart, [NotNull] IPolyline cutLine, [NotNull] IDictionary <RingGroup, List <RingGroup> > splitPartsByFootprintPart, ChangeAlongZSource zSource) { double tolerance = GeometryUtils.GetXyTolerance(multipatchPart.FirstGeometry); double zTolerance = GeometryUtils.GetZTolerance(multipatchPart.FirstGeometry); RingGroup ringGroup = GeometryConversionUtils.CreateRingGroup(multipatchPart); int pointId; if (GeometryUtils.HasUniqueVertexId( Assert.NotNull(multipatchPart.MainOuterRing), out pointId)) { ringGroup.Id = pointId; } bool inverted = ringGroup.ClockwiseOriented == false; if (inverted) { ringGroup.ReverseOrientation(); } IList <RingGroup> cutRingGroups = CutRingGroupPlanar(ringGroup, cutLine, tolerance, zSource, zTolerance); AssignResultsToFootprintParts(cutRingGroups, splitPartsByFootprintPart, tolerance); if (inverted) { foreach (RingGroup cutRingGroup in cutRingGroups) { cutRingGroup.ReverseOrientation(); } } }
public void CanReadClockwiseWindingPolygon() { // Some OGC 1.1 implementations do not have counter-clockwise polygon winding order: var ring1 = new List <Pnt3D> { new Pnt3D(0, 0, 9), new Pnt3D(0, 100, 8), new Pnt3D(100, 100, 5), new Pnt3D(100, 20, 9) }; RingGroup polygon = CreatePoly(ring1); polygon.AddInteriorRing(new Linestring(new[] { new Pnt3D(25, 50, 0), new Pnt3D(50, 50, 0), new Pnt3D(50, 75, 0), new Pnt3D(25, 75, 0), new Pnt3D(25, 50, 0) } )); RingGroup inverted = (RingGroup)polygon.Clone(); inverted.ReverseOrientation(); WkbGeomWriter writer = new WkbGeomWriter(); byte[] bytes = writer.WritePolygon(inverted); const bool assumeWkbPolygonsClockwise = true; WkbGeomReader reader = new WkbGeomReader(assumeWkbPolygonsClockwise); RingGroup deserialized = reader.ReadPolygon(new MemoryStream(bytes)); Assert.IsTrue(deserialized.Equals(polygon)); }
public void Run(params string[] args) { RingGroup dn = PhoneSystem.Root.GetDNByNumber(args[1]) as RingGroup; if (dn != null && dn.RingStrategy == RingGroup.StrategyType.Paging) { if (args.Length > 2) { dn.SetProperty("MULTICASTADDR", args[2], PropertyType.String, ""); dn.SetProperty("MULTICASTPORT", args[3], PropertyType.String, ""); dn.SetProperty("MULTICASTCODEC", args[4], PropertyType.String, ""); dn.SetProperty("MULTICASTPTIME", args[5], PropertyType.String, ""); } else { dn.DeleteProperty("MULTICASTADDR"); dn.DeleteProperty("MULTICASTPORT"); dn.DeleteProperty("MULTICASTCODEC"); dn.DeleteProperty("MULTICASTPTIME"); } dn.Save(); } }
private static IList <IList <RingGroup> > TryCutConnectedComponents( IPolygon inputPolygon, IPolyline cutPolyline, ChangeAlongZSource zSource) { double tolerance = GeometryUtils.GetXyTolerance(inputPolygon); double zTolerance = GeometryUtils.GetZTolerance(inputPolygon); var result = new List <IList <RingGroup> >(); foreach (IPolygon connectedComponent in GeometryUtils.GetConnectedComponents( inputPolygon)) { RingGroup ringGroup = GeometryConversionUtils.CreateRingGroup(connectedComponent); IList <RingGroup> cutRingGroups = CutRingGroupPlanar( ringGroup, cutPolyline, tolerance, zSource, zTolerance); result.Add(cutRingGroups); } return(result); }
public IList <RingGroup> ReadMultiPolygon(Stream stream) { using (BinaryReader reader = InitializeReader(stream)) { ReadWkbType(reader, true, out WkbGeometryType geometryType, out Ordinates ordinates); if (geometryType == WkbGeometryType.Polygon) { RingGroup result = ReadPolygonCore(reader, ordinates); return(new List <RingGroup> { result }); } if (geometryType == WkbGeometryType.MultiPolygon) { uint polygonCount = reader.ReadUInt32(); var result = new List <RingGroup>((int)polygonCount); for (int i = 0; i < polygonCount; i++) { ReadWkbType(reader, false, out geometryType, out ordinates); result.Add(ReadPolygonCore(reader, ordinates)); } return(result); } throw new NotSupportedException($"Cannot read {geometryType} as MultiPolygon."); } }
private static Dictionary <IPolygon, IMultiPatch> BuildResultMultipatches( [NotNull] IMultiPatch prototype, [NotNull] IDictionary <RingGroup, List <RingGroup> > splitResultsByFootprintPart, DegenerateMultipatchFootprintAction nonSimpleBoundaryAction) { var result = new Dictionary <IPolygon, IMultiPatch>(); IRing emptyRing = GeometryFactory.CreateEmptyRing(prototype); foreach (var outerRingsByFootprintPart in splitResultsByFootprintPart) { RingGroup footprintPart = outerRingsByFootprintPart.Key; List <RingGroup> resultPolys = outerRingsByFootprintPart.Value; IMultiPatch resultMultipatch = GeometryFactory.CreateEmptyMultiPatch(prototype); foreach (RingGroup poly in resultPolys) { // TODO: Support vertical ring group with inner rings bool simplify = poly.InteriorRings.Any(); GeometryConversionUtils.AddRingGroup( resultMultipatch, poly, simplify, poly.Id != null); } if (resultPolys.Any(p => p.Id != null)) { GeometryUtils.MakePointIDAware(resultMultipatch); } // Guard against multipatches with wrong footprint. They are so broken (IRelationalOps are wrong) that // it's not worth using them any further... if (IsMultipatchWithDegenerateFootprint(resultMultipatch)) { switch (nonSimpleBoundaryAction) { case DegenerateMultipatchFootprintAction.Throw: throw new DegenerateResultGeometryException( "The multipatch cut operation resulted in a multipatch with degenerate footprint."); case DegenerateMultipatchFootprintAction.Discard: _msg.DebugFormat( "Discarding result multipatch with degenerate boundary: {0}", GeometryUtils.ToString(resultMultipatch)); continue; case DegenerateMultipatchFootprintAction.Keep: _msg.DebugFormat( "Detected result multipatch with degenerate boundary (it will be kept): {0}", GeometryUtils.ToString(resultMultipatch)); break; } } IPolygon footprintPoly = GeometryConversionUtils.CreatePolygon(emptyRing, emptyRing, footprintPart); result.Add(footprintPoly, resultMultipatch); } return(result); }