Beispiel #1
0
        private static int GetInsideReshapeLineIndex(RepeatedField <ReshapeLineMsg> reshapeLines,
                                                     IGeometry intersectingGeometry)
        {
            List <ShapeMsg> reshapePathMsgs = reshapeLines.Select(l => l.Path).ToList();

            List <IPolyline> resultLines =
                ProtobufGeometryUtils.FromShapeMsgList <IPolyline>(reshapePathMsgs);

            int insideLineIndex = resultLines
                                  .Select((reshapePath, index) => (reshapePath, index))
                                  .First(rl => GeometryUtils.InteriorIntersects(
                                             rl.reshapePath, intersectingGeometry)).index;

            return(insideLineIndex);
        }
Beispiel #2
0
        public void CanCalculateOverlaps()
        {
            var fClass =
                new GdbFeatureClass(123, "TestFC", esriGeometryType.esriGeometryPolygon);

            var sr = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95,
                WellKnownVerticalCS.LN02);

            fClass.SpatialReference = sr;

            IPolygon polygon1 = GeometryFactory.CreatePolygon(
                GeometryFactory.CreatePoint(2600000, 1200000, sr),
                GeometryFactory.CreatePoint(2601000, 1201000, sr));

            polygon1.SpatialReference = sr;

            GdbFeature sourceFeature = new GdbFeature(42, fClass)
            {
                Shape = polygon1
            };

            IPolygon polygon2 = GeometryFactory.CreatePolygon(
                GeometryFactory.CreatePoint(2600500, 1200500, sr),
                GeometryFactory.CreatePoint(2601500, 1201500, sr));

            polygon2.SpatialReference = sr;

            GdbFeature targetFeature = new GdbFeature(43, fClass)
            {
                Shape = polygon2
            };

            var sourceFeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(sourceFeature);
            var targetFeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(targetFeature);

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

            CalculateOverlapsRequest calculationRequest = new CalculateOverlapsRequest()
            {
                ClassDefinitions =
                {
                    objectClassMsg
                },
                SourceFeatures =
                {
                    sourceFeatureMsg
                },
                TargetFeatures =
                {
                    targetFeatureMsg
                }
            };

            CalculateOverlapsResponse response =
                RemoveOverlapsServiceUtils.CalculateOverlaps(calculationRequest, null);

            Assert.AreEqual(1, response.Overlaps.Count);

            List <ShapeMsg> shapeBufferList =
                response.Overlaps.SelectMany(kvp => kvp.Overlaps).ToList();

            List <IPolygon> resultPolys =
                ProtobufGeometryUtils.FromShapeMsgList <IPolygon>(shapeBufferList);

            Assert.AreEqual(1, resultPolys.Count);

            Assert.AreEqual(1000 * 1000 / 4, ((IArea)resultPolys[0]).Area);

            // Now the removal:
            RemoveOverlapsRequest removeRequest = new RemoveOverlapsRequest();

            removeRequest.ClassDefinitions.AddRange(calculationRequest.ClassDefinitions);
            removeRequest.SourceFeatures.AddRange(calculationRequest.SourceFeatures);
            removeRequest.Overlaps.Add(response.Overlaps);

            RemoveOverlapsResponse removeResponse =
                RemoveOverlapsServiceUtils.RemoveOverlaps(removeRequest);

            Assert.AreEqual(1, removeResponse.ResultsByFeature.Count);
            ResultGeometriesByFeature resultByFeature = removeResponse.ResultsByFeature[0];

            GdbObjectReference originalObjRef = new GdbObjectReference(
                resultByFeature.OriginalFeatureRef.ClassHandle,
                resultByFeature.OriginalFeatureRef.ObjectId);

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

            var updatedGeometry =
                ProtobufGeometryUtils.FromShapeMsg(resultByFeature.UpdatedGeometry);

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

            Assert.AreEqual(0, resultByFeature.NewGeometries.Count);
        }
Beispiel #3
0
        public void CanReshapeAlongBufferedTarget()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            CalculateReshapeLinesRequest calculationRequest =
                CreateCalculateReshapeLinesRequest(sourceFeature, targetFeature);

            double minSegmentLength = 2;

            calculationRequest.TargetBufferOptions = new TargetBufferOptionsMsg();
            calculationRequest.TargetBufferOptions.BufferDistance             = 10;
            calculationRequest.TargetBufferOptions.BufferMinimumSegmentLength = minSegmentLength;

            CalculateReshapeLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null);

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

            AssertReshapeLineCount(calculateResponse.ReshapeLines, 4, 4);

            List <ShapeMsg> reshapePathMsgs =
                calculateResponse.ReshapeLines.Select(l => l.Path).ToList();

            List <IPolyline> resultLines =
                ProtobufGeometryUtils.FromShapeMsgList <IPolyline>(reshapePathMsgs);

            int insideLineIndex = resultLines
                                  .Select((reshapePath, index) => (reshapePath, index))
                                  .OrderBy(rl => rl.reshapePath.Length)
                                  .First(rl => GeometryUtils.InteriorIntersects(
                                             rl.reshapePath, sourceFeature.Shape)).index;

            var insideLines =
                resultLines.Where(rl => GeometryUtils.InteriorIntersects(rl, sourceFeature.Shape))
                .ToList();

            Assert.AreEqual(2, insideLines.Count);

            foreach (IPolyline resultLine in resultLines)
            {
                Assert.AreNotEqual(1000, resultLine.Length);
                Assert.AreEqual(
                    0, GeometryUtils.GetShortSegments(resultLine, minSegmentLength).Count);
            }

            //
            // Reshape the default side:
            //
            ApplyReshapeLinesRequest applyRequest = new ApplyReshapeLinesRequest();

            applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]);
            applyRequest.CalculationRequest       = calculationRequest;
            applyRequest.InsertVerticesInTarget   = false;
            applyRequest.UseNonDefaultReshapeSide = false;

            ApplyReshapeLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null);

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

            GdbObjectMsg updatedFeatureMsg = applyResponse.ResultFeatures[0].Update;

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

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

            IGeometry updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape);

            // The shortest reshape line results in a greater remaining area:
            Assert.IsNotNull(updatedGeometry);
            Assert.Greater(((IArea)updatedGeometry).Area, 1000 * 1000 * 3 / (double)4);

            // Check the new reshape line:
            AssertReshapeLineCount(applyResponse.NewReshapeLines, 3, 3);
            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            applyResponse.ReshapeLinesUsability);
        }
Beispiel #4
0
        public void CanReshapeAlongNonDefaultSide()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            CalculateReshapeLinesRequest calculationRequest =
                CreateCalculateReshapeLinesRequest(sourceFeature, targetFeature);

            CalculateReshapeLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null);

            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            calculateResponse.ReshapeLinesUsability);
            AssertReshapeLineCount(calculateResponse.ReshapeLines, 2, 2);

            List <ShapeMsg> reshapePathMsgs =
                calculateResponse.ReshapeLines.Select(l => l.Path).ToList();

            List <IPolyline> resultLines =
                ProtobufGeometryUtils.FromShapeMsgList <IPolyline>(reshapePathMsgs);

            int insideLineIndex = resultLines
                                  .Select((reshapePath, index) => (reshapePath, index))
                                  .First(rl => GeometryUtils.InteriorIntersects(
                                             rl.reshapePath, sourceFeature.Shape)).index;

            var insideLines =
                resultLines.Where(rl => GeometryUtils.InteriorIntersects(rl, sourceFeature.Shape))
                .ToList();

            Assert.AreEqual(1, insideLines.Count);

            Assert.AreEqual(1000, (insideLines[0]).Length);

            //
            // Reshape the default side:
            //
            ApplyReshapeLinesRequest applyRequest = new ApplyReshapeLinesRequest();

            applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]);
            applyRequest.CalculationRequest       = calculationRequest;
            applyRequest.InsertVerticesInTarget   = false;
            applyRequest.UseNonDefaultReshapeSide = false;

            ApplyReshapeLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null);

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

            GdbObjectMsg updatedFeatureMsg = applyResponse.ResultFeatures[0].Update;

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

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

            IGeometry updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape);

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

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

            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            applyResponse.ReshapeLinesUsability);

            //
            // Reshape the non-default side:
            //
            applyRequest.UseNonDefaultReshapeSide = true;
            applyResponse =
                ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null);

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

            updatedFeatureMsg = applyResponse.ResultFeatures[0].Update;

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

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

            updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape);

            Assert.IsNotNull(updatedGeometry);
            Assert.AreEqual((double)1000 * 1000 * 1 / 4, ((IArea)updatedGeometry).Area);
        }
Beispiel #5
0
        public static RemoveOverlapsResponse RemoveOverlaps(
            [NotNull] RemoveOverlapsRequest request,
            [CanBeNull] ITrackCancel trackCancel = null)
        {
            // Unpack request
            bool explodeMultiparts          = request.ExplodeMultipartResults;
            bool storeOverlapsAsNewFeatures = request.StoreOverlapsAsNewFeatures;

            GdbTableContainer container = ProtobufConversionUtils.CreateGdbTableContainer(
                request.ClassDefinitions, null, out _);

            IList <IFeature> selectedFeatureList =
                ProtobufConversionUtils.FromGdbObjectMsgList(
                    request.SourceFeatures, container);

            IList <IFeature> targetFeaturesForVertexInsertion =
                ProtobufConversionUtils.FromGdbObjectMsgList(
                    request.UpdatableTargetFeatures, container);

            Overlaps overlaps = new Overlaps();

            foreach (OverlapMsg overlapMsg in request.Overlaps)
            {
                GdbObjectReference gdbRef = new GdbObjectReference(
                    overlapMsg.OriginalFeatureRef.ClassHandle,
                    overlapMsg.OriginalFeatureRef.ObjectId);

                IFeatureClass fClass = (IFeatureClass)container.GetByClassId(gdbRef.ClassId);

                List <IGeometry> overlapGeometries =
                    ProtobufGeometryUtils.FromShapeMsgList <IGeometry>(
                        overlapMsg.Overlaps,
                        DatasetUtils.GetSpatialReference(fClass));

                overlaps.AddGeometries(gdbRef, overlapGeometries);
            }

            // Remove overlaps
            OverlapsRemover overlapsRemover = RemoveOverlaps(
                selectedFeatureList, overlaps, targetFeaturesForVertexInsertion, explodeMultiparts,
                storeOverlapsAsNewFeatures, trackCancel);

            // Pack response
            var result = overlapsRemover.Result;

            var response = new RemoveOverlapsResponse();

            PackResultGeometries(result.ResultsByFeature,
                                 response.ResultsByFeature);

            response.NonStorableMessages.AddRange(result.NonStorableMessages);

            if (result.TargetFeaturesToUpdate != null)
            {
                foreach (var keyValuePair in result.TargetFeaturesToUpdate)
                {
                    IFeature  feature     = keyValuePair.Key;
                    IGeometry newGeometry = keyValuePair.Value;

                    GdbObjectMsg targetFeatureMsg =
                        ProtobufGdbUtils.ToGdbObjectMsg(
                            feature, newGeometry, feature.Class.ObjectClassID);

                    response.TargetFeaturesToUpdate.Add(targetFeatureMsg);
                }
            }

            response.ResultHasMultiparts = result.ResultHasMultiparts;

            return(response);
        }