public static ApplyReshapeLinesResponse ApplyReshapeLines( [NotNull] ApplyReshapeLinesRequest request, [CanBeNull] ITrackCancel trackCancel) { var subcurves = new List <CutSubcurve>(); foreach (ReshapeLineMsg reshapeLineMsg in request.ReshapeLines) { subcurves.Add(FromReshapeLineMsg(reshapeLineMsg)); } GeometryReshaperBase reshaper = CreateReshaper(request); var notifications = new NotificationCollection(); Dictionary <IGeometry, NotificationCollection> reshapedGeometries = reshaper.Reshape(subcurves, notifications, request.UseNonDefaultReshapeSide); var response = new ApplyReshapeLinesResponse(); if (reshapedGeometries.Count > 0) { // TODO: CacheGeometrySizes... IList <IFeature> updatedFeatures = reshaper.Save(reshapedGeometries); IList <ResultObjectMsg> ResultObjectMsgs = GetResultFeatureMessages( null, updatedFeatures, f => GetNotifications(reshapedGeometries, f), f => reshaper.NotificationIsWarning); response.ResultFeatures.AddRange(ResultObjectMsgs); } // Calculate new reshape lines based on current source and target states: CalculateReshapeLinesRequest calculationRequest = request.CalculationRequest; List <IFeature> newSourceFeatures = reshaper.ReshapeGeometryCloneByFeature.Keys.ToList(); IList <IFeature> newTargetFeatures = GetUpToDateTargets(reshaper, request.CalculationRequest); ReshapeAlongCurveUsability curveUsability; IList <CutSubcurve> newSubcurves = CalculateReshapeLines(newSourceFeatures, newTargetFeatures, calculationRequest, trackCancel, out curveUsability); response.ReshapeLinesUsability = (int)curveUsability; foreach (CutSubcurve resultCurve in newSubcurves) { response.NewReshapeLines.Add(ToReshapeLineMsg(resultCurve)); } return(response); }
private static GeometryReshaperBase CreateReshaper( [NotNull] ApplyReshapeLinesRequest request) { GetFeatures(request.CalculationRequest.SourceFeatures, request.CalculationRequest.TargetFeatures, request.CalculationRequest.ClassDefinitions, out IList <IFeature> sourceFeatures, out IList <IFeature> targetFeatures); GeometryReshaperBase reshaper = sourceFeatures.Count == 1 ? (GeometryReshaperBase) new GeometryReshaper(sourceFeatures[0]) : new MultipleGeometriesReshaper(sourceFeatures) { MultipleSourcesTreatIndividually = true, MultipleSourcesTreatAsUnion = false }; if (request.InsertVerticesInTarget) { reshaper.TargetFeatures = targetFeatures; } IEnvelope visibleExtent; ReshapeCurveFilterOptions filterOptions = GetLineFilterOptions(request.CalculationRequest.FilterOptions, out visibleExtent); IEnumerable <IFeature> unallowedOverlapFeatures = null; if (filterOptions.ExcludeResultingInOverlaps) { unallowedOverlapFeatures = targetFeatures; reshaper.RemoveClosedReshapePathAreas = true; } List <IEnvelope> allowedExtents = visibleExtent == null ? null : new List <IEnvelope> { visibleExtent }; bool useMinimalTolerance = MathUtils.AreEqual(0, request.CalculationRequest.Tolerance); reshaper.ResultFilter = new ReshapeResultFilter(allowedExtents, unallowedOverlapFeatures, useMinimalTolerance); reshaper.ResultFilter.UseNonDefaultReshapeSide = request.UseNonDefaultReshapeSide; reshaper.UseMinimumTolerance = useMinimalTolerance; return(reshaper); }
public override async Task <ApplyReshapeLinesResponse> ApplyReshapeLines( [NotNull] ApplyReshapeLinesRequest request, [NotNull] ServerCallContext context) { Stopwatch watch = _msg.DebugStartTiming(); Func <ITrackCancel, ApplyReshapeLinesResponse> func = trackCancel => ChangeAlongServiceUtils.ApplyReshapeLines(request, trackCancel); ApplyReshapeLinesResponse response = await GrpcServerUtils.ExecuteServiceCall(func, context, _staTaskScheduler, true) ?? new ApplyReshapeLinesResponse(); _msg.DebugStopTiming( watch, "Applied reshape lines for peer {0} ({1} source features, {2} reshape lines)", context.Peer, request.CalculationRequest.SourceFeatures.Count, request.ReshapeLines.Count); return(response); }
private static ApplyReshapeLinesRequest CreateApplyReshapeCurvesRequest( IList <Feature> selectedFeatures, IList <Feature> targetFeatures, IList <CutSubcurve> selectedSubcurves) { var result = new ApplyReshapeLinesRequest { CalculationRequest = CreateCalculateReshapeLinesRequest(selectedFeatures, targetFeatures) }; foreach (CutSubcurve subcurve in selectedSubcurves) { result.ReshapeLines.Add(ToReshapeLineMsg(subcurve)); } // TODO: Options result.InsertVerticesInTarget = true; return(result); }
public static List <ResultFeature> ApplyReshapeCurves( [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); ApplyReshapeLinesRequest request = CreateApplyReshapeCurvesRequest(sourceFeatures, targetFeatures, selectedSubcurves); ApplyReshapeLinesResponse response = rpcClient.ApplyReshapeLines(request, null, null, cancellationToken); List <ResultObjectMsg> responseResultFeatures = response.ResultFeatures.ToList(); var resultFeatures = new List <ResultFeature>(); foreach (ResultObjectMsg resultObjectMsg in responseResultFeatures) { GdbObjectMsg updateMsg = Assert.NotNull(resultObjectMsg.Update); var updateObjRef = new GdbObjectReference(updateMsg.ClassHandle, updateMsg.ObjectId); Feature originalFeature = featuresByObjRef[updateObjRef]; resultFeatures.Add(new ResultFeature(originalFeature, resultObjectMsg)); } newChangeAlongCurves = PopulateReshapeAlongCurves( sourceFeatures, targetFeatures, response.NewReshapeLines, (ReshapeAlongCurveUsability)response.ReshapeLinesUsability); return(resultFeatures); }
public void CanReshapeAlongFilteredLinesByNoTargetOverlap() { GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature); CalculateReshapeLinesRequest calculationRequest = CreateCalculateReshapeLinesRequest(sourceFeature, targetFeature); // // Filter by 'no target overlaps': // calculationRequest.FilterOptions = new ReshapeLineFilterOptionsMsg(); calculationRequest.FilterOptions.ExcludeResultingInOverlaps = true; CalculateReshapeLinesResponse calculateResponse = ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null); Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape, (ReshapeAlongCurveUsability)calculateResponse.ReshapeLinesUsability); // 1 inside-source line and 1 (reshapable, but filtered) outside-source line. AssertReshapeLineCount(calculateResponse.ReshapeLines, 2, 2, 1); int insideLineIndex = GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape); IPolyline insideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg( calculateResponse.ReshapeLines[insideLineIndex].Path); Assert.NotNull(insideLine); Assert.AreEqual(1000, insideLine.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; IGeometry updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape); Assert.IsNotNull(updatedGeometry); Assert.AreEqual(1000 * 1000 * 3 / 4, ((IArea)updatedGeometry).Area); // Check the new reshape line - there should be 1 reshapable, but filtered line AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1, 1); // Technically the curve could be used to reshape (filtered out is not evaluated for usability) Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape, (ReshapeAlongCurveUsability)applyResponse.ReshapeLinesUsability); // Reshape the non-default side. This should probably not be possible but as it is currently // just labelled a reshape line filter, it can be justified to reshape anyway... applyRequest.UseNonDefaultReshapeSide = true; applyResponse = ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null); Assert.AreEqual(1, applyResponse.ResultFeatures.Count); updatedFeatureMsg = applyResponse.ResultFeatures[0].Update; updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape); Assert.IsNotNull(updatedGeometry); Assert.AreEqual(1000 * 1000 * 1 / 4, ((IArea)updatedGeometry).Area); // Check the new reshape line - there should be 1 reshapable, but filtered line AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1, 1); // Technically the curve could be used to reshape (filtered out is not evaluated for usability) Assert.AreEqual(ReshapeAlongCurveUsability.CanReshape, (ReshapeAlongCurveUsability)applyResponse.ReshapeLinesUsability); }
public void CanReshapeAlongFilteredLinesByExtent() { GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature); CalculateReshapeLinesRequest calculationRequest = CreateCalculateReshapeLinesRequest(sourceFeature, targetFeature); IEnvelope visibleExtent = sourceFeature.Shape.Envelope; visibleExtent.Expand(10, 10, false); calculationRequest.FilterOptions = new ReshapeLineFilterOptionsMsg(); calculationRequest.FilterOptions.ClipLinesOnVisibleExtent = true; calculationRequest.FilterOptions.VisibleExtents.Add( ProtobufGeometryUtils.ToEnvelopeMsg(visibleExtent)); CalculateReshapeLinesResponse calculateResponse = ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null); Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape, calculateResponse.ReshapeLinesUsability); // 1 inside-line and 2 extent-intersecting dangles to the outside within the extent. AssertReshapeLineCount(calculateResponse.ReshapeLines, 3, 1); int insideLineIndex = GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape); IPolyline insideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg( calculateResponse.ReshapeLines[insideLineIndex].Path); Assert.NotNull(insideLine); Assert.AreEqual(1000, insideLine.Length); // // Reshape the non-default side (should be possible): // ApplyReshapeLinesRequest applyRequest = new ApplyReshapeLinesRequest(); applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]); applyRequest.CalculationRequest = calculationRequest; applyRequest.InsertVerticesInTarget = false; applyRequest.UseNonDefaultReshapeSide = true; 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 * 1 / 4, ((IArea)updatedGeometry).Area); // Check the new reshape line - there should be 2 non-reshapable dangles AssertReshapeLineCount(applyResponse.NewReshapeLines, 2, 0); Assert.AreEqual(ReshapeAlongCurveUsability.InsufficientOrAmbiguousReshapeCurves, (ReshapeAlongCurveUsability)applyResponse.ReshapeLinesUsability); }
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); }
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); }
public void CanReshapeAlongMinimalTolerance() { GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature); // Insert an extra point: IPoint targetAlmostIntersectPoint = GeometryFactory.CreatePoint( 2601000.001, 1200500.0, sourceFeature.Shape.SpatialReference); bool pointInserted = ReshapeUtils.EnsurePointsExistInTarget( targetFeature.Shape, new[] { targetAlmostIntersectPoint }, 0.001); Assert.IsTrue(pointInserted); Assert.AreEqual(6, GeometryUtils.GetPointCount(targetFeature.Shape)); CalculateReshapeLinesRequest calculationRequest = CreateCalculateReshapeLinesRequest(sourceFeature, targetFeature); CalculateReshapeLinesResponse calculateResponse = ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null); Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape, calculateResponse.ReshapeLinesUsability); AssertReshapeLineCount(calculateResponse.ReshapeLines, 2, 2); int insideLineIndex = GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape); IPolyline insideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg( calculateResponse.ReshapeLines[insideLineIndex].Path); Assert.NotNull(insideLine); Assert.AreNotEqual(1000.0, (insideLine).Length); // NOTE: If IntersectionUtils.UseCustomIntersect = true the from point is exactly on the inserted point // Otherwise it's somewhere between - so we cannot do the exact comparison Assert.AreNotEqual(insideLine.FromPoint.X, 2601000.0); Assert.AreNotEqual(insideLine.ToPoint.X, 2601000.0); // // 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; IGeometry updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape); Assert.IsNotNull(updatedGeometry); Assert.Greater(((IArea)updatedGeometry).Area, 1000.0 * 1000.0 * 3 / 4); // Check the new reshape line: AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1); Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape, applyResponse.ReshapeLinesUsability); // // // The same using the minimum tolerance: // calculationRequest.Tolerance = 0; calculateResponse = ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null); Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape, calculateResponse.ReshapeLinesUsability); AssertReshapeLineCount(calculateResponse.ReshapeLines, 2, 2); insideLineIndex = GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape); insideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg( calculateResponse.ReshapeLines[insideLineIndex].Path); Assert.NotNull(insideLine); Assert.AreEqual(1000.0, insideLine.Length, 0.000000001); // NOTE: If IntersectionUtils.UseCustomIntersect = true the from point is exactly on the inserted point // Otherwise it's somewhere between - so we cannot do the exact comparison Assert.AreEqual(2601000.0, insideLine.FromPoint.X); Assert.AreEqual(1200500.0, insideLine.FromPoint.Y); // // Apply with minimum tolerance: applyRequest = new ApplyReshapeLinesRequest(); applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]); applyRequest.CalculationRequest = calculationRequest; applyRequest.InsertVerticesInTarget = false; applyRequest.UseNonDefaultReshapeSide = false; applyResponse = ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null); Assert.AreEqual(1, applyResponse.ResultFeatures.Count); updatedFeatureMsg = applyResponse.ResultFeatures[0].Update; updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape); Assert.IsNotNull(updatedGeometry); Assert.AreEqual(1000 * 1000 * 3 / 4, ((IArea)updatedGeometry).Area); // Check the new remaining reshape line (outside) AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1); Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape, applyResponse.ReshapeLinesUsability); IPolyline outsideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg( applyResponse.NewReshapeLines[0].Path); Assert.NotNull(outsideLine); Assert.AreEqual(3000.0, outsideLine.Length, 0.000000001); // NOTE: If IntersectionUtils.UseCustomIntersect = true the from point is exactly on the inserted point // Otherwise it's somewhere between - so we cannot do the exact comparison Assert.AreEqual(2601000.0, outsideLine.ToPoint.X); Assert.AreEqual(1200500.0, outsideLine.ToPoint.Y); }
public void CanReshapeAlongInsertTargetVertices() { 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); int insideLineIndex = GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape); IPolyline insideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg( calculateResponse.ReshapeLines[insideLineIndex].Path); Assert.NotNull(insideLine); Assert.AreEqual(1000.0, insideLine.Length); // // Reshape the default side: // ApplyReshapeLinesRequest applyRequest = new ApplyReshapeLinesRequest(); applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]); applyRequest.CalculationRequest = calculationRequest; applyRequest.InsertVerticesInTarget = true; applyRequest.UseNonDefaultReshapeSide = false; ApplyReshapeLinesResponse applyResponse = ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null); Assert.AreEqual(2, applyResponse.ResultFeatures.Count); ResultObjectMsg sourceResultMsg = applyResponse.ResultFeatures.First( f => f.Update.ObjectId == sourceFeature.OID); IGeometry updatedSourceGeometry = ProtobufGeometryUtils.FromShapeMsg(sourceResultMsg.Update.Shape); Assert.IsNotNull(updatedSourceGeometry); Assert.AreEqual(1000 * 1000 * 3 / 4, ((IArea)updatedSourceGeometry).Area); ResultObjectMsg targetResultMsg = applyResponse.ResultFeatures.First( f => f.Update.ObjectId == targetFeature.OID); IGeometry updatedTargetGeometry = ProtobufGeometryUtils.FromShapeMsg(targetResultMsg.Update.Shape); Assert.AreEqual(GeometryUtils.GetPointCount(targetFeature.Shape) + 2, GeometryUtils.GetPointCount(updatedTargetGeometry)); // Check the new reshape line: AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1); Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape, applyResponse.ReshapeLinesUsability); }