private async Task <bool> UpdatePolygonResultPreviewAsync( bool nonDefaultSide, [NotNull] Polyline sketchPolyline, [NotNull] List <Feature> polygonSelection) { ReshapeResult reshapeResult = null; if (polygonSelection.Count != 0) { // Idea: ReshapeOperation class that contains the options to build the rpc, cancellation token, time out settings and logging. // TODO: Keep this source and cancel in case finish sketch happens var cancellationTokenSource = new CancellationTokenSource(3000); reshapeResult = MicroserviceClient.TryReshape( polygonSelection, sketchPolyline, null, false, true, nonDefaultSide, cancellationTokenSource.Token); } // TODO: discard result if the user has since clicked again or some other event (finish / esc) happened // TODO in 2.6 and higher try: //FrameworkApplication.QueueIdleAction( // () => _feedback?.UpdatePreview(reshapeResult.ResultFeatures)); return(await QueuedTaskUtils.Run( () => _feedback?.UpdatePreview(reshapeResult?.ResultFeatures))); }
public static async Task <MapPoint> GetOpenJawReplacementPointAsync( [NotNull] ReshapeGrpc.ReshapeGrpcClient rpcClient, [NotNull] Feature polylineFeature, [NotNull] Polyline reshapeLine, bool useNonDefaultReshapeSide) { var request = new OpenJawReshapeLineReplacementRequest() { UseNonDefaultReshapeSide = useNonDefaultReshapeSide }; SpatialReference sr = await QueuedTaskUtils.Run( () => { Geometry geometryToReshape = polylineFeature.GetShape(); request.Feature = ProtobufConversionUtils.ToGdbObjectMsg( polylineFeature, geometryToReshape, true); request.ReshapePath = ProtobufConversionUtils.ToShapeMsg(reshapeLine); return(geometryToReshape.SpatialReference); }); // Not in a queued task (but it is still called multiple times because...) ShapeMsg pointMsg = rpcClient.GetOpenJawReshapeLineReplaceEndPoint(request); return(await QueuedTaskUtils.Run( () => (MapPoint)ProtobufConversionUtils.FromShapeMsg(pointMsg, sr))); }
protected override void OnToolKeyUp(MapViewKeyEventArgs k) { _msg.VerboseDebug("OnToolKeyUp"); // TODO: Key pressed management //_shiftIsPressed = false; try { QueuedTaskUtils.Run( delegate { if ((k.Key == Key.LeftShift || k.Key == Key.RightShift) && SelectionCursor != null && IsInSelectionPhase()) { SetCursor(SelectionCursor); } OnKeyUpCore(k); return(true); }); } catch (Exception e) { HandleError($"Error in tool key up ({Caption}): {e.Message}", e, true); } }
protected override void OnToolKeyUp(MapViewKeyEventArgs k) { _msg.VerboseDebug("OnToolKeyUp"); try { QueuedTaskUtils.Run( delegate { if (IsShiftKey(k.Key)) { ShiftReleasedCore(); } OnKeyUpCore(k); return(true); }); } catch (Exception e) { HandleError($"Error in tool key up ({Caption}): {e.Message}", e, true); } finally { PressedKeys.Remove(k.Key); } }
//protected override void OnKeyUpCore(MapViewKeyEventArgs k) //{ // _msg.VerboseDebug("OnKeyUpCore"); // if (k.Key == _keyToggleNonDefaultSide) // { // _nonDefaultSideMode = ! _nonDefaultSideMode; // k.Handled = true; // } // else if (k.Key == Key.Space) // { // k.Handled = true; // } // base.OnKeyUpCore(k); //} //protected override async Task HandleKeyUpAsync(MapViewKeyEventArgs k) //{ // // At 2.5 this is never called (despite setting k.Handled = true above). // TODO: Test in 2.6/2.7 // try // { // if (k.Key == _keyToggleNonDefaultSide || // k.Key == Key.Space) // { // _updateFeedbackTask = UpdateFeedbackAsync(_nonDefaultSideMode); // await _updateFeedbackTask; // } // } // catch (Exception e) // { // _msg.Warn("Error generating preview", e); // } // finally // { // _updateFeedbackTask = null; // } //} protected override async Task <bool> OnEditSketchCompleteCoreAsync( Geometry sketchGeometry, EditingTemplate editTemplate, MapView activeView, CancelableProgressor cancelableProgressor = null) { _feedback.Clear(); // TODO: cancel all running background tasks... var polyline = (Polyline)sketchGeometry; List <Feature> selection; // Or allow selecting next feature already? SetCursor(Cursors.Wait); bool success = await QueuedTaskUtils.Run(async() => { selection = GetApplicableSelectedFeatures(activeView).ToList(); var potentiallyAffectedFeatures = GetAdjacentFeatures(selection, cancelableProgressor); // This timout should be enough even in extreme circumstances: int timeout = selection.Count * 10000; _cancellationTokenSource = new CancellationTokenSource(timeout); ReshapeResult result = MicroserviceClient.Reshape( selection, polyline, potentiallyAffectedFeatures, true, true, _nonDefaultSideMode, _cancellationTokenSource.Token); if (result == null) { return(false); } Dictionary <Feature, Geometry> resultFeatures = result.ResultFeatures.ToDictionary(r => r.Feature, r => r.UpdatedGeometry); LogReshapeResults(result, selection.Count); success = await SaveAsync(resultFeatures); // At some point, hopefully, read-only operations on the CIM model can run in parallel await ToolUtils.FlashResultPolygonsAsync(activeView, resultFeatures); return(success); }); _nonDefaultSideMode = false; //if (!_advancedReshapeOptions.RemainInSketchMode) { StartSelectionPhase(); } return(success); // taskSave.Result; }
protected override bool HandleEscape() { QueuedTaskUtils.Run( () => { SelectionUtils.ClearSelection(ActiveMapView.Map); ResetDerivedGeometries(); StartSelectionPhase(); return(true); }); return(true); }
protected override void OnToolKeyDown(MapViewKeyEventArgs k) { _msg.VerboseDebug("OnToolKeyDown"); try { PressedKeys.Add(k.Key); if (IsModifierKey(k.Key) || HandledKeys.Contains(k.Key)) { k.Handled = true; } if (k.Key == _keyShowOptionsPane) { ShowOptionsPane(); } // Cancel outside a queued task otherwise the current task that blocks the queue // cannot be cancelled. if (k.Key == Key.Escape) { HandleEscape(); } QueuedTaskUtils.Run( delegate { if (IsShiftKey(k.Key) && SelectionCursorShift != null && IsInSelectionPhase()) { SetCursor(SelectionCursorShift); } OnKeyDownCore(k); return(true); }); } catch (Exception e) { HandleError($"Error in tool key down ({Caption}): {e.Message}", e, true); } }
protected override async Task <bool> OnEditSketchCompleteCoreAsync( Geometry sketchGeometry, EditingTemplate editTemplate, MapView activeView, CancelableProgressor cancelableProgressor = null) { var polygon = (Polygon)sketchGeometry; var resultFeatures = await QueuedTaskUtils.Run( () => CalculateResultFeatures(activeView, polygon), cancelableProgressor); var taskSave = QueuedTaskUtils.Run(() => SaveAsync(resultFeatures)); var taskFlash = QueuedTaskUtils.Run(() => FlashAsync(activeView, resultFeatures)); await Task.WhenAll(taskFlash, taskSave); return(taskSave.Result); }
private async Task <bool> UpdateFeedbackAsync(bool nonDefaultSide) { var sketchPolyline = await GetCurrentSketchAsync() as Polyline; if (sketchPolyline == null || sketchPolyline.IsEmpty || sketchPolyline.PointCount < 2) { _feedback?.Clear(); return(true); } // Snapshot: MapView activeMapView = ActiveMapView; List <Feature> polylineSelection; List <Feature> polygonSelection; bool result = await QueuedTaskUtils.Run( async() => { List <Feature> selection = GetApplicableSelectedFeatures(activeMapView).ToList(); polylineSelection = GdbObjectUtils.Filter(selection, GeometryType.Polyline).ToList(); polygonSelection = GdbObjectUtils.Filter(selection, GeometryType.Polygon).ToList(); bool updated = await UpdateOpenJawReplacedEndpointAsync(nonDefaultSide, sketchPolyline, polylineSelection); updated |= await UpdatePolygonResultPreviewAsync( nonDefaultSide, sketchPolyline, polygonSelection); return(updated); }); return(result); }
private void OnMapSelectionChanged(MapSelectionChangedEventArgs args) { _msg.VerboseDebug("OnToolActivateAsync"); try { QueuedTaskUtils.Run( delegate { // Used to clear derived geometries etc. bool result = OnMapSelectionChangedCore(args); return(result); }); } catch (Exception e) { HandleError($"Error OnSelectionChanged: {e.Message}", e, true); } }
protected override bool HandleEscape() { QueuedTaskUtils.Run( delegate { if (IsInSketchMode) { // if sketch is empty, also remove selection and return to selection phase if (!RequiresSelection) { // remain in sketch mode, just reset the sketch ResetSketch(); } else { Geometry sketch = GetCurrentSketchAsync().Result; if (sketch != null && !sketch.IsEmpty) { ResetSketch(); } else { SelectionUtils.ClearSelection(ActiveMapView.Map); StartSelectionPhase(); } } } else { ClearSketchAsync(); SelectionUtils.ClearSelection(ActiveMapView.Map); } return(true); }); return(true); }
protected override void OnToolKeyDown(MapViewKeyEventArgs k) { _msg.VerboseDebug("OnToolKeyDown"); try { if (IsModifierKey(k.Key) || HandledKeys.Contains(k.Key)) { k.Handled = true; } if (k.Key == _keyShowOptionsPane) { ShowOptionsPane(); } QueuedTaskUtils.Run( delegate { if (k.Key == Key.Escape) { return(HandleEscape()); } if ((k.Key == Key.LeftShift || k.Key == Key.RightShift) && SelectionCursorShift != null && IsInSelectionPhase()) { SetCursor(SelectionCursorShift); } OnKeyDownCore(k); return(true); }); } catch (Exception e) { HandleError($"Error in tool key down ({Caption}): {e.Message}", e, true); } }
protected override Task <bool> OnSketchModifiedAsync() { return(QueuedTaskUtils.Run(OnSketchModifiedCore)); }
private async Task <bool> OnSelectionSketchComplete(Geometry sketchGeometry, CancelableProgressor progressor) { // TODO: Add Utils method to KeyboardUtils to do it in the WPF way SelectionCombinationMethod selectionMethod = KeyboardUtils.IsModifierPressed(Keys.Shift) ? SelectionCombinationMethod.XOR : SelectionCombinationMethod.New; Geometry selectionGeometry; var pickerWindowLocation = new Point(0, 0); Dictionary <BasicFeatureLayer, List <long> > candidatesOfManyLayers = await QueuedTaskUtils.Run(() => { DisposeOverlays(); selectionGeometry = GetSelectionGeometry(sketchGeometry); pickerWindowLocation = MapView.Active.MapToScreen(selectionGeometry.Extent.Center); // find all features spatially related with selectionGeometry return(FindFeaturesOfAllLayers(selectionGeometry)); }); if (!candidatesOfManyLayers.Any()) { //no candidate (user clicked into empty space): clear selection await QueuedTask.Run(() => { SelectionUtils.ClearSelection(ActiveMapView.Map); }); return(false); } if (SketchingMoveType == SketchingMoveType.Click) { //note if necessary add a virtual core method here for overriding if (GetSelectionSketchMode() == SelectionMode.Original ) //alt was pressed: select all xy { await QueuedTask.Run(() => { Selector.SelectLayersFeaturesByOids( candidatesOfManyLayers, selectionMethod); }); } // select a single feature using feature reduction and picker else { IEnumerable <KeyValuePair <BasicFeatureLayer, List <long> > > candidatesOfLayers = await QueuedTask.Run( () => GeometryReducer.GetReducedset(candidatesOfManyLayers)); // show picker if more than one candidate if (GeometryReducer.ContainsManyFeatures(candidatesOfManyLayers)) { List <IPickableItem> pickables = new List <IPickableItem>(); foreach (var layerCandidates in candidatesOfLayers) { pickables.AddRange( await QueuedTask.Run( () => PickerUI.Picker.CreatePickableFeatureItems( layerCandidates))); } var picker = new PickerUI.Picker(pickables, pickerWindowLocation); var item = await picker.PickSingle() as PickableFeatureItem; if (item != null) { var kvp = new KeyValuePair <BasicFeatureLayer, List <long> >( item.Layer, new List <long> { item.Oid }); await QueuedTask.Run(() => { Selector.SelectLayersFeaturesByOids( kvp, selectionMethod); }); } } else { await QueuedTask.Run(() => { Selector.SelectLayersFeaturesByOids( candidatesOfLayers.First(), selectionMethod); }); } } } if (SketchingMoveType == SketchingMoveType.Drag) { //CTRL was pressed: picker shows FC's to select from if (GetSelectionSketchMode() == SelectionMode.UserSelect) { List <IPickableItem> pickingCandidates = await QueuedTask.Run(() => { List <FeatureClassInfo> featureClassInfos = Selector.GetSelectableFeatureclassInfos(); return(PickableItemAdapter.Get(featureClassInfos)); }); var picker = new PickerUI.Picker(pickingCandidates, pickerWindowLocation); var item = await picker.PickSingle() as PickableFeatureClassItem; if (item != null) { await QueuedTask.Run(() => { item.BelongingFeatureLayers.ForEach(layer => { List <long> oids = candidatesOfManyLayers[layer]; QueryFilter qf = new QueryFilter { ObjectIDs = oids }; layer.Select(qf, selectionMethod); }); }); } } //no modifier pressed: select all in envelope else { await QueuedTask.Run(() => { Selector.SelectLayersFeaturesByOids( candidatesOfManyLayers, selectionMethod); }); } } MapView activeMapView = MapView.Active; await QueuedTask.Run(() => ProcessSelection( SelectionUtils.GetSelectedFeatures(activeMapView), progressor)); return(true); }