コード例 #1
0
        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))));
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        public static RingGroup CreateRingGroup([NotNull] GeometryPart part)
        {
            RingGroup result = CreateRingGroup(
                Assert.NotNull(part.MainOuterRing),
                part.InnerRings.Cast <IRing>().ToList());

            return(result);
        }
コード例 #6
0
ファイル: WkbReadWriteTest.cs プロジェクト: ProSuite/ProSuite
        private static RingGroup CreatePoly(List <Pnt3D> points)
        {
            Linestring ring = CreateRing(points);

            RingGroup poly = new RingGroup(ring);

            return(poly);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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))));
        }
コード例 #9
0
ファイル: WkbGeomWriter.cs プロジェクト: ProSuite/ProSuite
        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());
        }
コード例 #10
0
        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.");
            }
        }
コード例 #11
0
ファイル: WkbReadWriteTest.cs プロジェクト: ProSuite/ProSuite
        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]));
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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();
                }
            }
        }
コード例 #15
0
ファイル: WkbReadWriteTest.cs プロジェクト: ProSuite/ProSuite
        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));
        }
コード例 #16
0
        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();
            }
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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.");
            }
        }
コード例 #19
0
        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);
        }