private void Check(
            [NotNull] IGeometry g1, [NotNull] IGeometry g2,
            int count,
            [CanBeNull] Func <ZDifferenceStrategyIntersectionPoints.IIntersectionPoint, int, bool>
            predicate = null)
        {
            g1.SpatialReference = _spatialReference;
            g2.SpatialReference = _spatialReference;
            double xyTolerance = GeometryUtils.GetXyTolerance(g1);

            Assert.True(GeometryUtils.IsZAware(g1));
            Assert.True(GeometryUtils.IsZAware(g2));

            var points = ZDifferenceStrategyIntersectionPoints
                         .GetIntersections(g1, g2, _spatialReference, xyTolerance)
                         .ToList();

            points.ForEach(p => Console.WriteLine(GeometryUtils.ToString(p.Point)));

            Assert.AreEqual(count, points.Count, "intersection count");

            Assert.True(
                points.TrueForAll(g => g.Point.SpatialReference == _spatialReference),
                "unexpected spatial reference");
            Assert.True(points.TrueForAll(ip => GeometryUtils.IsZAware(ip.Point)),
                        "points must be Z aware");

            if (predicate != null)
            {
                var errors = points.Select((ip, i) => predicate(ip, i)
                                                                              ? string.Empty
                                                                              : $"- point {i}: {ip.Point.X}, {ip.Point.Y}, {ip.Point.Z}, other Z: {ip.OtherZ}")
                             .Where(e => !string.IsNullOrEmpty(e))
                             .ToList();

                Assert.True(errors.Count == 0,
                            $"Predicate not fulfilled:{Environment.NewLine}" +
                            $"{StringUtils.Concatenate(errors, Environment.NewLine)}");
            }
        }
        public void CantGetDistanceToNonPlanarPolygon()
        {
            const double z1      = 10;
            var          g1      = GeometryFactory.CreatePoint(100, 0, z1);
            var          polygon =
                CurveConstruction.StartPoly(0, 0, 10)
                .LineTo(10, 0, 10)
                .LineTo(10, 10, 11)
                .LineTo(0, 10, 10)
                .ClosePolygon();

            var polygonClass = new FeatureClassMock(
                1, "polygon", esriGeometryType.esriGeometryPolygon,
                esriFeatureType.esriFTSimple,
                SpatialReferenceUtils.CreateSpatialReference(WellKnownHorizontalCS.LV95));

            var feature = polygonClass.CreateFeature(polygon);

            var intersectionPoints =
                ZDifferenceStrategyIntersectionPoints.GetDistanceToPlane(
                    g1, feature, 0.01);

            foreach (var either in intersectionPoints)
            {
                either.Match(e =>
                {
                    Console.WriteLine(
                        $@"expected nonplanar error: {e.Message} ({e.MaximumOffset})");
                    Assert.AreEqual(0.3324801391253977, e.MaximumOffset);
                    return(0);
                },
                             pts =>
                {
                    Assert.Fail("Unexpected intersection point");
                    return(-1);
                });
            }
        }
        public void CanGetDistanceToPlanarPolygon()
        {
            const double z1 = 10;
            const double z2 = 20;
            var          g1 = GeometryFactory.CreatePoint(100, 0, z1);
            var          g2 = GeometryFactory.CreatePolygon(0, 0, 100, 200);

            GeometryUtils.MakeZAware(g2);
            g2 = GeometryUtils.ConstantZ(g2, z2);

            var polygonClass = new FeatureClassMock(
                1, "polygon", esriGeometryType.esriGeometryPolygon,
                esriFeatureType.esriFTSimple,
                SpatialReferenceUtils.CreateSpatialReference(WellKnownHorizontalCS.LV95));

            var feature = polygonClass.CreateFeature(g2);

            var intersectionPoints =
                ZDifferenceStrategyIntersectionPoints.GetDistanceToPlane(
                    g1, feature, 0.01);

            foreach (var either in intersectionPoints)
            {
                either.Match(e =>
                {
                    Assert.Fail($"unexpected nonplanar error: {e.Message}");
                    return(-1);
                },
                             pts =>
                {
                    var points = pts.ToList();
                    Assert.AreEqual(1, points.Count);
                    Assert.AreEqual(z2 - z1, points[0].Distance);
                    return(0);
                });
            }
        }