Пример #1
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))));
        }
Пример #2
0
        private static IPolyline GetOutermostBoundary(IPolygon fullUnionPolygon,
                                                      out List <IRing> innerRings)
        {
            var resultRings = new List <IPath>();

            innerRings = new List <IRing>();
            foreach (IRing ring in GeometryUtils.GetRings(fullUnionPolygon))
            {
                if (ring.IsExterior)
                {
                    resultRings.Add(ring);
                }
                else
                {
                    innerRings.Add(ring);
                }
            }

            IPolyline fullUnionOuterRings = GeometryFactory.CreatePolyline(resultRings);

            // TOP-4915: Must also handle boundary loops between source and target
            foreach (IPolygon boundaryLoop in BoundaryLoopUtils.GetBoundaryLoops(
                         fullUnionPolygon, GeometryUtils.GetXyTolerance(fullUnionPolygon)))
            {
                // remove from result, add to rings
                IPolyline boundaryLoopLine = GeometryFactory.CreatePolyline(boundaryLoop);

                fullUnionOuterRings =
                    (IPolyline)IntersectionUtils.Difference(
                        fullUnionOuterRings, boundaryLoopLine);

                innerRings.AddRange(GeometryUtils.GetRings(boundaryLoop));
            }

            return(fullUnionOuterRings);
        }
Пример #3
0
        private static IPolyline GetCutLine(IMultiPatch sourceMultipatch,
                                            IPolygon overlappingPolygon)
        {
            IPolygon sourceFootprint = GeometryFactory.CreatePolygon(sourceMultipatch);

            IPolyline sourceFootprintBoundary =
                GeometryFactory.CreatePolyline(sourceFootprint);

            IPolyline overlappingPolygonBoundary =
                GeometryFactory.CreatePolyline(overlappingPolygon);

            const bool assumeIntersecting = true;
            const bool allowRandomStartPointsForClosedIntersections = true;

            IPolyline intersectionLines = IntersectionUtils.GetIntersectionLines(
                sourceFootprint, overlappingPolygonBoundary, assumeIntersecting,
                allowRandomStartPointsForClosedIntersections);

            // the intersectionLines also run along the boundary, but we only want the interior intersections
            var interiorIntersection = (IPolyline)IntersectionUtils.Difference(
                intersectionLines, sourceFootprintBoundary);

            return(interiorIntersection);
        }
Пример #4
0
        public static IPolyline GetDifference([NotNull] IPolyline polyline,
                                              [NotNull] IPolyline otherLine,
                                              double?xyTolerance = null)
        {
            // The lines are often very short and close to each other --> xy cluster tolerance workaround is used far too often
            // --> test for IRelationalOperator.Equals at least if lines are very short?
            // --> if equal, return empty geometry? or null?

            if (xyTolerance != null)
            {
                double maxLengthWorkaround = xyTolerance.Value * 6;

                if (polyline.Length <= maxLengthWorkaround &&
                    otherLine.Length < maxLengthWorkaround)
                {
                    if (((IRelationalOperator)polyline).Equals(otherLine))
                    {
                        return(GeometryFactory.CreateEmptyPolyline(polyline));
                    }
                }
            }

            return((IPolyline)IntersectionUtils.Difference(polyline, otherLine));
        }
Пример #5
0
        public void CanReadWriteMultipartPolygonXyz()
        {
            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, 421);

            innerRing.SpatialReference = sr;

            IPolygon polyWithHole = (IPolygon)IntersectionUtils.Difference(outerRing, innerRing);

            IPolygon poly2 = GeometryFactory.CreatePolygon(2610000, 1200000, 2611000, 1201000, 543);

            poly2.SpatialReference = sr;

            IPolygon multiPolygon = (IPolygon)GeometryUtils.Union(polyWithHole, poly2);

            Assert.IsTrue(GeometryUtils.IsZAware(multiPolygon));

            GeometryUtils.Simplify(multiPolygon);

            WkbGeometryWriter writer = new WkbGeometryWriter();

            byte[] wkb = writer.WritePolygon(multiPolygon);

            // Wkx
            var ordinates                        = Ordinates.Xyz;
            IList <IGeometry> parts              = GeometryUtils.GetParts(multiPolygon).ToList();
            IGeometry         exteriorRing       = parts[0];
            IGeometry         interiorRing       = parts[1];
            IGeometry         secondExteriorRing = parts[2];

            LinearRing wkxOuterRing = ToWkxLinearRing(exteriorRing, ordinates);
            LinearRing wkxInnerRing = ToWkxLinearRing(interiorRing, ordinates);

            Polygon wkxPolygon1 = ToWkxPolygon(wkxOuterRing, new[] { wkxInnerRing });
            Polygon wkxPolygon2 = ToWkxPolygon(ToWkxLinearRing(secondExteriorRing, ordinates));

            MultiPolygon wkxMultiPolygon = new MultiPolygon(new[] { wkxPolygon1, wkxPolygon2 });

            byte[] wkx = ToChristianSchwarzWkb(wkxMultiPolygon);
            Assert.AreEqual(wkx, wkb);

            // Bonus test: Geom
            WkbGeomWriter  geomWriter = new WkbGeomWriter();
            MultiPolycurve multiPly   = GeometryConversionUtils.CreateMultiPolycurve(multiPolygon);

            byte[] wkbGeom = geomWriter.WriteMultipolygon(multiPly, ordinates);
            Assert.AreEqual(wkb, wkbGeom);

            WkbGeometryReader reader = new WkbGeometryReader();

            IPolygon restored = reader.ReadPolygon(new MemoryStream(wkb));

            Assert.IsTrue(GeometryUtils.AreEqual(multiPolygon, restored));

            // Geom:
            WkbGeomReader     geomReader       = new WkbGeomReader();
            IList <RingGroup> readMultiPolygon =
                geomReader.ReadMultiPolygon(new MemoryStream(wkbGeom));
            var readMultiPolycurve = new MultiPolycurve(
                readMultiPolygon.SelectMany(g => g.GetLinestrings()));

            Assert.IsTrue(multiPly.Equals(readMultiPolycurve));

            // As multipatch
            IMultiPatch multipatch = GeometryFactory.CreateMultiPatch(multiPolygon);

            wkb = writer.WriteMultipatch(multipatch);

            IMultiPatch readMultipatch = (IMultiPatch)reader.ReadGeometry(new MemoryStream(wkb));

            // TODO: Implement AreEqual for multipatch that is more permissive regarding First/Outer ring type
            AssertEqual(multipatch, readMultipatch);
        }