private static AdvancedReshapeRequest CreateReshapeRequest( [NotNull] IList <Feature> selectedFeatures, [NotNull] Polyline reshapePath, [CanBeNull] IList <Feature> adjacentFeatures, bool allowOpenJaw, bool multiReshapeAsUnion, bool useNonDefaultSide) { var request = new AdvancedReshapeRequest(); ProtobufConversionUtils.ToGdbObjectMsgList(selectedFeatures, request.Features, request.ClassDefinitions); ShapeMsg reshapePathMsg = ProtobufConversionUtils.ToShapeMsg(reshapePath); request.ReshapePaths = reshapePathMsg; request.AllowOpenJawReshape = allowOpenJaw; request.UseNonDefaultReshapeSide = useNonDefaultSide; request.MultipleSourcesTryUnion = multiReshapeAsUnion; // TODO: from options request.MoveOpenJawEndJunction = true; if (adjacentFeatures != null) { ProtobufConversionUtils.ToGdbObjectMsgList( adjacentFeatures, request.PotentiallyConnectedFeatures, request.ClassDefinitions); } return(request); }
public static ReshapeResult Reshape( [NotNull] ReshapeGrpc.ReshapeGrpcClient rpcClient, [NotNull] IList <Feature> selectedFeatures, [NotNull] Polyline reshapeLine, [CanBeNull] IList <Feature> adjacentFeatures, bool allowOpenJawReshape, bool multiReshapeAsUnion, bool tryReshapeNonDefault, CancellationToken cancellationToken) { var allInputFeatures = new Dictionary <GdbObjectReference, Feature>(); AddInputFeatures(selectedFeatures, allInputFeatures); if (adjacentFeatures != null) { AddInputFeatures(adjacentFeatures, allInputFeatures); } AdvancedReshapeRequest request = CreateReshapeRequest( selectedFeatures, reshapeLine, adjacentFeatures, allowOpenJawReshape, multiReshapeAsUnion, tryReshapeNonDefault); return(Reshape(rpcClient, request, allInputFeatures, cancellationToken)); }
public static AdvancedReshapeResponse Reshape( [NotNull] AdvancedReshapeRequest request) { var polyline = (IPolyline)ProtobufGeometryUtils.FromShapeMsg(request.ReshapePaths); List <IPath> reshapePaths = GeometryUtils.GetPaths(Assert.NotNull(polyline)).ToList(); GeometryReshaperBase reshaper = CreateReshaper(request, reshapePaths); bool useNonDefaultReshapeSide = request.UseNonDefaultReshapeSide; var notifications = new NotificationCollection(); IDictionary <IGeometry, NotificationCollection> reshapedGeometries = reshaper.Reshape(reshapePaths, useNonDefaultReshapeSide, notifications); Assert.NotNull(reshapedGeometries, "No reshaped geometries"); if (reshapedGeometries.Count == 0) { return(NoReshapeResponse(notifications)); } var response = new AdvancedReshapeResponse(); if (reshaper.ResultWithinOtherResultButNotInOriginal( reshapedGeometries.Keys, out IPolygon containedPolygon)) { response.OverlapPolygon = ProtobufGeometryUtils.ToShapeMsg(containedPolygon); } // Messages regarding some of the features that were not reshaped: if (notifications.Count > 0 && request.Features.Count > 1) { string overallMessage = notifications.Concatenate(". "); _msg.Info(overallMessage); response.WarningMessage = overallMessage; } // Junction-move, updating of adjacent lines is performed in Save: IList <IFeature> storedFeatures = reshaper.Save(reshapedGeometries); response.OpenJawReshapeHappened = reshaper.OpenJawReshapeOcurred; response.OpenJawIntersectionCount = reshaper.OpenJawIntersectionPointCount; PackReshapeResponseFeatures(response, storedFeatures, reshapedGeometries, reshaper.OpenJawReshapeOcurred, reshaper.NotificationIsWarning); return(response); }
public override async Task <AdvancedReshapeResponse> AdvancedReshape( AdvancedReshapeRequest request, ServerCallContext context) { Stopwatch watch = _msg.DebugStartTiming(); Func <ITrackCancel, AdvancedReshapeResponse> func = trackCancel => AdvancedReshapeServiceUtils.Reshape(request); AdvancedReshapeResponse response = await GrpcServerUtils.ExecuteServiceCall(func, context, _staTaskScheduler, true) ?? new AdvancedReshapeResponse(); _msg.DebugStopTiming(watch, "Reshaped for peer {0} ({1} source features)", context.Peer, request.Features.Count); return(response); }
private static ReshapeResult Reshape( [NotNull] ReshapeGrpc.ReshapeGrpcClient rpcClient, [NotNull] AdvancedReshapeRequest request, [NotNull] IReadOnlyDictionary <GdbObjectReference, Feature> allInputFeatures, CancellationToken cancellationToken) { request.AllowOpenJawReshape = true; const int deadlinePerFeature = 5000; AdvancedReshapeResponse reshapeResultMsg = RpcCallUtils.Try( o => rpcClient.AdvancedReshape(request, o), cancellationToken, deadlinePerFeature * request.Features.Count); if (reshapeResultMsg == null) { return(null); } var result = new ReshapeResult { OpenJawReshapeHappened = reshapeResultMsg.OpenJawReshapeHappened, OpenJawIntersectionCount = reshapeResultMsg.OpenJawIntersectionCount, FailureMessage = reshapeResultMsg.WarningMessage }; if (reshapeResultMsg.ResultFeatures.Count == 0) { return(result); } foreach (ResultFeatureMsg resultFeatureMsg in reshapeResultMsg.ResultFeatures) { GdbObjectReference objRef = new GdbObjectReference( resultFeatureMsg.UpdatedFeature.ClassHandle, resultFeatureMsg.UpdatedFeature.ObjectId); Feature inputFeature = allInputFeatures[objRef]; var reshapeResultFeature = new ReshapeResultFeature(inputFeature, resultFeatureMsg); result.ResultFeatures.Add(reshapeResultFeature); } return(result); }
private static IList <IFeature> GetFeaturesToReshape( [NotNull] AdvancedReshapeRequest request, out GdbTableContainer container) { container = ProtobufConversionUtils.CreateGdbTableContainer( request.ClassDefinitions, null, out _); foreach (IDataset dataset in container.GetDatasets(esriDatasetType.esriDTAny)) { if (dataset is IObjectClass objectClass) { objectClass.AddField(FieldUtils.CreateOIDField()); } } IList <IFeature> featuresToReshape = ProtobufConversionUtils.FromGdbObjectMsgList(request.Features, container); return(featuresToReshape); }
public void CanAdvancedReshapePolygon() { 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 }; IPath reshapePath = GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600500, 1200000, sr), GeometryFactory.CreatePoint(2600500, 1200500, sr), GeometryFactory.CreatePoint(2601000, 1200500, sr)); reshapePath.SpatialReference = sr; IPolyline reshapePolyline = GeometryFactory.CreatePolyline(reshapePath); var sourceFeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(sourceFeature); var reshapePaths = ProtobufGeometryUtils.ToShapeMsg(reshapePolyline); var objectClassMsg = ProtobufGdbUtils.ToObjectClassMsg(sourceFeature.Class); AdvancedReshapeRequest request = new AdvancedReshapeRequest() { ClassDefinitions = { objectClassMsg }, Features = { sourceFeatureMsg }, ReshapePaths = reshapePaths }; AdvancedReshapeResponse response = AdvancedReshapeServiceUtils.Reshape(request); Assert.AreEqual(1, response.ResultFeatures.Count); GdbObjectMsg resultFeatureMsg = response.ResultFeatures[0].UpdatedFeature; Assert.AreEqual(sourceFeature.OID, resultFeatureMsg.ObjectId); Assert.AreEqual(sourceFeature.Class.ObjectClassID, resultFeatureMsg.ClassHandle); var resultPoly = (IPolygon)ProtobufGeometryUtils.FromShapeMsg(resultFeatureMsg.Shape); Assert.NotNull(resultPoly); double oneQuarter = 1000d * 1000d / 4d; Assert.AreEqual(3 * oneQuarter, ((IArea)resultPoly).Area); // Non-default side: request.UseNonDefaultReshapeSide = true; response = AdvancedReshapeServiceUtils.Reshape(request); Assert.AreEqual(1, response.ResultFeatures.Count); resultFeatureMsg = response.ResultFeatures[0].UpdatedFeature; resultPoly = (IPolygon)ProtobufGeometryUtils.FromShapeMsg(resultFeatureMsg.Shape); Assert.NotNull(resultPoly); Assert.AreEqual(oneQuarter, ((IArea)resultPoly).Area); }
public void CanAdvancedReshapePolyline() { var fClass = new GdbFeatureClass(123, "TestFC", esriGeometryType.esriGeometryPolyline); var sr = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LN02); fClass.SpatialReference = sr; IPolyline sourcePolyline = CreatePolyline( GeometryFactory.CreatePoint(2600500, 1200000, sr), GeometryFactory.CreatePoint(2600500, 1200500, sr), GeometryFactory.CreatePoint(2601000, 1200500, sr)); GdbFeature sourceFeature = new GdbFeature(42, fClass) { Shape = sourcePolyline }; IPolyline sourceAdjacentPolyline = CreatePolyline( GeometryFactory.CreatePoint(2601000, 1200500, sr), GeometryFactory.CreatePoint(2601500, 1200500, sr), GeometryFactory.CreatePoint(2601500, 1200000, sr)); GdbFeature sourceAdjacentFeature = new GdbFeature(43, fClass) { Shape = sourceAdjacentPolyline }; IPolyline reshapePolyline = CreatePolyline( GeometryFactory.CreatePoint(2600500, 1200500, sr), GeometryFactory.CreatePoint(2600500, 1201000, sr)); var sourceFeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(sourceFeature); var reshapePaths = ProtobufGeometryUtils.ToShapeMsg(reshapePolyline); var sourceAdjacentFeatureMsg = ProtobufGdbUtils.ToGdbObjectMsg(sourceAdjacentFeature); var objectClassMsg = ProtobufGdbUtils.ToObjectClassMsg(sourceFeature.Class); AdvancedReshapeRequest request = new AdvancedReshapeRequest() { ClassDefinitions = { objectClassMsg }, Features = { sourceFeatureMsg }, ReshapePaths = reshapePaths, AllowOpenJawReshape = true, MoveOpenJawEndJunction = true, PotentiallyConnectedFeatures = { sourceAdjacentFeatureMsg } }; AdvancedReshapeResponse response = AdvancedReshapeServiceUtils.Reshape(request); Assert.AreEqual(2, response.ResultFeatures.Count); GdbObjectMsg resultFeatureMsg = response.ResultFeatures[1].UpdatedFeature; Assert.AreEqual(sourceFeature.OID, resultFeatureMsg.ObjectId); Assert.AreEqual(sourceFeature.Class.ObjectClassID, resultFeatureMsg.ClassHandle); var resultPolyline = (IPolyline)ProtobufGeometryUtils.FromShapeMsg(resultFeatureMsg.Shape); Assert.NotNull(resultPolyline); Assert.IsTrue(GeometryUtils.AreEqual(resultPolyline.ToPoint, reshapePolyline.ToPoint)); GdbObjectMsg resultAdjacentFeatureMsg = response.ResultFeatures[0].UpdatedFeature; var resultAdjacentPolyline = (IPolyline)ProtobufGeometryUtils.FromShapeMsg(resultAdjacentFeatureMsg.Shape); Assert.NotNull(resultAdjacentPolyline); Assert.IsTrue( GeometryUtils.AreEqual(resultAdjacentPolyline.FromPoint, reshapePolyline.ToPoint)); // Non-default side: request.UseNonDefaultReshapeSide = true; response = AdvancedReshapeServiceUtils.Reshape(request); Assert.AreEqual(1, response.ResultFeatures.Count); resultFeatureMsg = response.ResultFeatures[0].UpdatedFeature; resultPolyline = (IPolyline)ProtobufGeometryUtils.FromShapeMsg(resultFeatureMsg.Shape); Assert.NotNull(resultPolyline); Assert.IsTrue( GeometryUtils.AreEqual(resultPolyline.FromPoint, reshapePolyline.ToPoint)); }
private static GeometryReshaperBase CreateReshaper( AdvancedReshapeRequest request, IList <IPath> reshapePaths) { GeometryReshaperBase result; bool allowOpenJaw = request.AllowOpenJawReshape; bool moveOpenJawEndJunction = request.MoveOpenJawEndJunction; IList <IFeature> featuresToReshape = GetFeaturesToReshape(request, out GdbTableContainer container); if (featuresToReshape.Count == 1) { IFeature firstFeature = featuresToReshape[0]; var singleGeometryReshaper = new GeometryReshaper(firstFeature) { AllowOpenJawReshape = allowOpenJaw }; result = singleGeometryReshaper; } else { var stickyIntersections = new StickyIntersections(featuresToReshape); foreach (SourceTargetPointPair pair in request.StickyIntersections) { stickyIntersections.SourceTargetPairs.Add( new KeyValuePair <IPoint, IPoint>( (IPoint)ProtobufGeometryUtils.FromShapeMsg( pair.SourcePoint), (IPoint)ProtobufGeometryUtils.FromShapeMsg( pair.TargetPoint))); } result = new MultipleGeometriesReshaper(featuresToReshape) { MultipleSourcesTreatIndividually = true, MultipleSourcesTreatAsUnion = request.MultipleSourcesTryUnion, MaxProlongationLengthFactor = 4, StickyIntersectionPoints = stickyIntersections }; // Conditions for closed reshape paths being removed: // - multiple source geometries, at least two of which polygons // - multiple reshape paths (or a single closed path) // ... consider checking that the ring-path is completely inside the outermost ring of the source polygon's union // or at least that several polygons are intersected by the sketch geometry if ((reshapePaths.Count > 1) || reshapePaths.All(path => path.IsClosed)) { if (ContainsMultiplePolygonFeatures(featuresToReshape)) { result.RemoveClosedReshapePathAreas = true; } } } if (moveOpenJawEndJunction) { IList <IFeature> targetCandidates = ProtobufConversionUtils.FromGdbObjectMsgList( request.PotentiallyConnectedFeatures, container); result.NetworkFeatureFinder = new LinearNetworkGdbFeatureFinder(targetCandidates); result.NetworkFeatureUpdater = new LinearNetworkNodeUpdater(result.NetworkFeatureFinder); } result.MoveLineEndJunction = moveOpenJawEndJunction; // TODO: Add to admin-options (i.e. central defaults only, no GUI) together with the threshold // _useSimplifiedReshapeSideDeterminationVertexThreshold in ReshapeInfo result.AllowSimplifiedReshapeSideDetermination = true; return(result); }