예제 #1
0
        private static FeatureCutter CreateFeatureCutter([NotNull] ApplyCutLinesRequest request,
                                                         out IList <IFeature> targetFeatures)
        {
            GetFeatures(request.CalculationRequest.SourceFeatures,
                        request.CalculationRequest.TargetFeatures,
                        request.CalculationRequest.ClassDefinitions,
                        out IList <IFeature> sourceFeatures, out targetFeatures);

            ChangeAlongZSource zSource = (ChangeAlongZSource)request.ChangedVerticesZSource;

            DatasetSpecificSettingProvider <ChangeAlongZSource> zSourceProvider =
                new DatasetSpecificSettingProvider <ChangeAlongZSource>(
                    "Z values for changed vertices", zSource);

            var cutter = new FeatureCutter(sourceFeatures)
            {
                ZSourceProvider = zSourceProvider
            };

            if (request.InsertVerticesInTarget)
            {
                cutter.TargetFeatures = targetFeatures;
            }

            return(cutter);
        }
예제 #2
0
        public void CanCutAlongInsertTargetVertices()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            CalculateCutLinesRequest calculationRequest =
                CreateCalculateCutLinesRequest(sourceFeature, targetFeature);

            CalculateCutLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateCutLines(calculationRequest, null);

            Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape,
                            (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability);

            AssertReshapeLineCount(calculateResponse.CutLines, 1, 1);

            IPolyline reshapeLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(calculateResponse.CutLines[0].Path);

            Assert.NotNull(reshapeLine);
            Assert.AreEqual(1000, (reshapeLine).Length);

            //
            // Cutting
            //
            var applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = true;

            ApplyCutLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(3, applyResponse.ResultFeatures.Count);

            List <IGeometry> cutSourceGeometries =
                applyResponse.ResultFeatures
                .Where(f => GetObjectId(f) != targetFeature.OID)
                .Select(GetShape)
                .ToList();

            Assert.AreEqual(1000 * 1000, cutSourceGeometries.Sum(g => ((IArea)g).Area));

            IGeometry updatedTargetGeometry =
                applyResponse.ResultFeatures
                .Where(f => f.Update?.ObjectId == targetFeature.OID)
                .Select(GetShape)
                .Single();

            Assert.AreEqual(GeometryUtils.GetPointCount(targetFeature.Shape) + 2,
                            GeometryUtils.GetPointCount(updatedTargetGeometry));

            // Check the new reshape line:
            AssertReshapeLineCount(applyResponse.NewCutLines, 0, 0);

            Assert.AreEqual(ReshapeAlongCurveUsability.NoReshapeCurves,
                            (ReshapeAlongCurveUsability)applyResponse.CutLinesUsability);
        }
예제 #3
0
        public static ApplyCutLinesResponse ApplyCutLines(
            [NotNull] ApplyCutLinesRequest request,
            [CanBeNull] ITrackCancel trackCancel)
        {
            IList <CutSubcurve> cutCurves = request.CutLines.Select(FromReshapeLineMsg).ToList();

            FeatureCutter cutter = CreateFeatureCutter(request, out IList <IFeature> targetFeatures);

            cutter.Cut(cutCurves);

            List <IFeature> storedFeatures = new List <IFeature>();

            var response = new ApplyCutLinesResponse();

            if (cutter.ResultGeometriesByFeature.Count > 0)
            {
                cutter.StoreResultFeatures(storedFeatures);

                cutter.LogSuccessfulCut();

                ICollection <KeyValuePair <IFeature, IList <IFeature> > > insertsByOriginal =
                    cutter.InsertedFeaturesByOriginal;

                IList <ResultObjectMsg> ResultObjectMsgs =
                    GetResultFeatureMessages(insertsByOriginal, storedFeatures);

                response.ResultFeatures.AddRange(ResultObjectMsgs);

                // Calculate the new cut lines:
                List <IFeature> newSourceFeatures = new List <IFeature>(cutter.SourceFeatures);

                newSourceFeatures.AddRange(
                    insertsByOriginal.SelectMany(kvp => kvp.Value));

                var newSubcurves =
                    CalculateCutLines(newSourceFeatures, targetFeatures,
                                      request.CalculationRequest, trackCancel,
                                      out ReshapeAlongCurveUsability usability);

                response.CutLinesUsability = (int)usability;

                response.NewCutLines.AddRange(newSubcurves.Select(ToReshapeLineMsg));

                return(response);
            }

            _msg.WarnFormat("The selection was not cut. Please select the lines to cut along");

            return(response);
        }
예제 #4
0
        public static List <ResultFeature> ApplyCutCurves(
            [NotNull] ChangeAlongGrpc.ChangeAlongGrpcClient rpcClient,
            [NotNull] IList <Feature> sourceFeatures,
            [NotNull] IList <Feature> targetFeatures,
            [NotNull] IList <CutSubcurve> selectedSubcurves,
            CancellationToken cancellationToken,
            out ChangeAlongCurves newChangeAlongCurves)
        {
            Dictionary <GdbObjectReference, Feature> featuresByObjRef =
                CreateFeatureDictionary(sourceFeatures, targetFeatures);

            ApplyCutLinesRequest request =
                CreateApplyCutCurvesRequest(sourceFeatures, targetFeatures, selectedSubcurves);

            ApplyCutLinesResponse response =
                rpcClient.ApplyCutLines(request, null, null, cancellationToken);

            List <ResultObjectMsg> responseResultFeatures = response.ResultFeatures.ToList();

            var resultFeatures = new List <ResultFeature>();

            foreach (ResultObjectMsg resultObjectMsg in responseResultFeatures)
            {
                GdbObjectReference originalFeatureRef =
                    GetOriginalGdbObjectReference(resultObjectMsg);

                Feature originalFeature = featuresByObjRef[originalFeatureRef];

                ResultFeature resultFeature = new ResultFeature(
                    originalFeature, resultObjectMsg);

                resultFeatures.Add(resultFeature);
            }

            newChangeAlongCurves = PopulateReshapeAlongCurves(
                sourceFeatures, targetFeatures, response.NewCutLines,
                (ReshapeAlongCurveUsability)response.CutLinesUsability);

            return(resultFeatures);
        }
예제 #5
0
        public override async Task <ApplyCutLinesResponse> ApplyCutLines(
            [NotNull] ApplyCutLinesRequest request,
            [NotNull] ServerCallContext context)
        {
            Stopwatch watch = _msg.DebugStartTiming();

            Func <ITrackCancel, ApplyCutLinesResponse> func =
                trackCancel =>
                ChangeAlongServiceUtils.ApplyCutLines(request, trackCancel);

            ApplyCutLinesResponse response =
                await GrpcServerUtils.ExecuteServiceCall(func, context, _staTaskScheduler, true) ??
                new ApplyCutLinesResponse();

            _msg.DebugStopTiming(
                watch,
                "Applied reshape lines for peer {0} ({1} source features, {2} reshape lines)",
                context.Peer, request.CalculationRequest.SourceFeatures.Count,
                request.CutLines.Count);

            return(response);
        }
예제 #6
0
        private static ApplyCutLinesRequest CreateApplyCutCurvesRequest(
            IList <Feature> selectedFeatures,
            IList <Feature> targetFeatures,
            IList <CutSubcurve> selectedSubcurves)
        {
            var result =
                new ApplyCutLinesRequest
            {
                CalculationRequest =
                    CreateCalculateCutLinesRequest(selectedFeatures, targetFeatures)
            };

            foreach (CutSubcurve subcurve in selectedSubcurves)
            {
                result.CutLines.Add(ToReshapeLineMsg(subcurve));
            }

            // TODO: Options
            result.InsertVerticesInTarget = true;

            return(result);
        }
예제 #7
0
        public void CanCutMultipleSourcesAlong()
        {
            GetOverlappingPolygons(out GdbFeature source1Feature, out GdbFeature source2Feature);

            IFeatureClass fClass = (IFeatureClass)source1Feature.Class;

            IFeature cutFeature = fClass.CreateFeature();

            cutFeature.Shape =
                GeometryFactory.CreatePolygon(
                    GeometryFactory.CreatePoint(2600000, 1200750),
                    GeometryFactory.CreatePoint(2602000, 1202000));
            cutFeature.Store();

            var source1FeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(source1Feature);
            var source2FeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(source2Feature);

            var targetFeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(cutFeature);

            var objectClassMsg = ProtobufGdbUtils.ToObjectClassMsg(source1Feature.Class);

            var calculationRequest = new CalculateCutLinesRequest();

            calculationRequest.ClassDefinitions.Add(objectClassMsg);
            calculationRequest.SourceFeatures.Add(source1FeatureMsg);
            calculationRequest.SourceFeatures.Add(source2FeatureMsg);

            calculationRequest.TargetFeatures.Add(targetFeatureMsg);

            calculationRequest.Tolerance = -1;

            CalculateCutLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateCutLines(calculationRequest, null);

            Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape,
                            (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability);

            AssertReshapeLineCount(calculateResponse.CutLines, 2, 2);

            Assert.AreEqual(source1Feature.OID, calculateResponse.CutLines[0].Source.ObjectId);
            Assert.AreEqual(source2Feature.OID, calculateResponse.CutLines[1].Source.ObjectId);

            foreach (ReshapeLineMsg cutLineMsg in calculateResponse.CutLines)
            {
                IPolyline reshapeLine =
                    (IPolyline)ProtobufGeometryUtils.FromShapeMsg(cutLineMsg.Path);

                Assert.NotNull(reshapeLine);
                Assert.AreEqual(1000, reshapeLine.Length);
            }

            //
            // Cutting using just one of the lines:
            //
            var applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;

            ApplyCutLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            GdbObjectMsg updatedFeatureMsg =
                applyResponse.ResultFeatures.First(
                    r => r.FeatureCase == ResultObjectMsg.FeatureOneofCase.Update).Update;

            GdbObjectReference updatedObjRef =
                new GdbObjectReference(updatedFeatureMsg.ClassHandle, updatedFeatureMsg.ObjectId);

            Assert.AreEqual(new GdbObjectReference(source1Feature), updatedObjRef);

            // Check the new reshape line:
            AssertReshapeLineCount(applyResponse.NewCutLines, 1, 1);

            Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape,
                            (ReshapeAlongCurveUsability)applyResponse.CutLinesUsability);

            //
            // Cutting using both lines:
            //
            applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.AddRange(calculateResponse.CutLines);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;

            applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(4, applyResponse.ResultFeatures.Count);

            // Check the new reshape line:
            AssertReshapeLineCount(applyResponse.NewCutLines, 0, 0);

            Assert.AreEqual(ReshapeAlongCurveUsability.NoReshapeCurves,
                            (ReshapeAlongCurveUsability)applyResponse.CutLinesUsability);
        }
예제 #8
0
        public void CanCutAlongUsingZSources()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            GeometryUtils.MakeZAware(sourceFeature.Shape);
            GeometryUtils.MakeZAware(targetFeature.Shape);

            var   normal     = new Vector(new[] { 0.5, 0.5, 2 });
            Pnt3D planePoint = new Pnt3D(2600000, 1200000, 600);

            Plane3D sourcePlane = new Plane3D(normal, planePoint);

            ChangeAlongZUtils.AssignZ((IPointCollection)sourceFeature.Shape, sourcePlane);

            GeometryUtils.ApplyConstantZ(targetFeature.Shape, 500);

            CalculateCutLinesRequest calculationRequest =
                CreateCalculateCutLinesRequest(sourceFeature, targetFeature);

            CalculateCutLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateCutLines(calculationRequest, null);

            Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape,
                            (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability);

            AssertReshapeLineCount(calculateResponse.CutLines, 1, 1);

            IPolyline reshapeLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(calculateResponse.CutLines[0].Path);

            Assert.NotNull(reshapeLine);
            Assert.AreEqual(1000, (reshapeLine).Length);

            Linestring cutLinestring =
                GeometryConversionUtils.GetLinestring(GeometryUtils.GetPaths(reshapeLine).Single());

            Pnt3D midPoint = (Pnt3D)cutLinestring.GetPointAlong(0.5, true);

            List <Pnt3D> points = GeometryConversionUtils.GetPntList(reshapeLine);

            Assert.IsTrue(points.All(p => MathUtils.AreEqual(p.Z, 500.0)));

            //
            // Cutting - TargetZ
            //
            var applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;
            applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.Target;

            ApplyCutLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            List <IGeometry> cutGeometries =
                applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area));

            List <MultiPolycurve> multiPolycurves =
                cutGeometries
                .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g))
                .ToList();

            foreach (MultiPolycurve multiPolycurve in multiPolycurves)
            {
                Line3D segment = multiPolycurve.FindSegments(midPoint, 0.001).First().Value;
                Assert.AreEqual(500, segment.StartPoint.Z);
                Assert.AreEqual(500, segment.EndPoint.Z);
            }

            //
            // Cutting - Interpolate
            //
            applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;
            applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.InterpolatedSource;

            applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area));

            multiPolycurves =
                cutGeometries
                .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g))
                .ToList();

            foreach (MultiPolycurve multiPolycurve in multiPolycurves)
            {
                List <Line3D> segments
                    = multiPolycurve.FindSegments(midPoint, 0.001)
                      .Select(kvp => kvp.Value).ToList();

                Assert.AreEqual(2, segments.Count);

                // Check if they are properly ordered and same length
                Assert.AreEqual(segments[0].EndPoint, segments[1].StartPoint);
                Assert.AreEqual(segments[0].Length2D, segments[1].Length2D);

                // Check if they are interpolated
                double average = (segments[0].StartPoint.Z + segments[1].EndPoint.Z) / 2;

                Assert.AreEqual(average, segments[0].EndPoint.Z);
            }

            //
            // Cutting - Plane
            //
            applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;
            applyRequest.ChangedVerticesZSource = (int)ChangeAlongZSource.SourcePlane;

            applyResponse = ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            cutGeometries = applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, cutGeometries.Sum(g => ((IArea)g).Area));

            multiPolycurves =
                cutGeometries
                .Select(g => GeometryConversionUtils.CreateMultiPolycurve((IPolycurve)g))
                .ToList();

            foreach (MultiPolycurve multiPolycurve in multiPolycurves)
            {
                bool?coplanar = ChangeAlongZUtils.AreCoplanar(
                    multiPolycurve.GetPoints().ToList(), sourcePlane,
                    0.01, out double _, out string _);

                Assert.IsTrue(coplanar);
            }
        }
예제 #9
0
        public void CanCutAlong()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            CalculateCutLinesRequest calculationRequest =
                CreateCalculateCutLinesRequest(sourceFeature, targetFeature);

            CalculateCutLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateCutLines(calculationRequest, null);

            Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape,
                            (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability);

            AssertReshapeLineCount(calculateResponse.CutLines, 1, 1);

            IPolyline reshapeLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(calculateResponse.CutLines[0].Path);

            Assert.NotNull(reshapeLine);
            Assert.AreEqual(1000, (reshapeLine).Length);

            //
            // Cutting
            //
            var applyRequest = new ApplyCutLinesRequest();

            applyRequest.CutLines.Add(calculateResponse.CutLines[0]);
            applyRequest.CalculationRequest     = calculationRequest;
            applyRequest.InsertVerticesInTarget = false;

            ApplyCutLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyCutLines(applyRequest, null);

            Assert.AreEqual(2, applyResponse.ResultFeatures.Count);

            List <IGeometry> geometries = applyResponse.ResultFeatures.Select(GetShape).ToList();

            Assert.AreEqual(1000 * 1000, geometries.Sum(g => ((IArea)g).Area));

            ResultObjectMsg updateResultMsg =
                applyResponse.ResultFeatures.First(
                    r => r.FeatureCase == ResultObjectMsg.FeatureOneofCase.Update);

            GdbObjectReference updateObjRef =
                new GdbObjectReference(updateResultMsg.Update.ClassHandle,
                                       updateResultMsg.Update.ObjectId);

            Assert.AreEqual(new GdbObjectReference(sourceFeature), updateObjRef);

            IGeometry firstGeometry =
                ProtobufGeometryUtils.FromShapeMsg(updateResultMsg.Update.Shape);

            Assert.IsNotNull(firstGeometry);
            Assert.AreEqual(1000 * 1000 * 3 / 4, ((IArea)firstGeometry).Area);

            // Check the new reshape line:
            AssertReshapeLineCount(applyResponse.NewCutLines, 0, 0);

            Assert.AreEqual(ReshapeAlongCurveUsability.NoReshapeCurves,
                            (ReshapeAlongCurveUsability)applyResponse.CutLinesUsability);
        }