Hello,
I am trying to create a code that will move Annotation visibly moved like in the original Move in ArcGIS Pro.
This is how I would imagine it:
My code only does this:
enum TrackingState
{
NotTracking = 0,
CanTrack,
Tracking
}
internal class MapTool1 : MapTool
{
private string side;
private long oid;
private Geometry shape;
private Point? _workingLocation;
private static readonly object _lock = new object();
private TrackingState _tracking = TrackingState.NotTracking;
private CIMTextSymbol _symbol;
private IDisposable _graphic;
private Geometry _geometry;
private Point? _lastPosition;
private bool click = false;
private DateTime firstClick;
private int clickCount = 0;
private DateTime secondClick;
private double time;
private DateTime clickTime;
private double timeOfClick;
private DateTime clicking;
public MapTool1()
{
IsSketchTool = false;
SketchType = SketchGeometryType.Point;
SketchOutputMode = SketchOutputMode.Map;
}
private void DoubleClick()
{
if (secondClick.Ticks / TimeSpan.TicksPerMillisecond != 0 && clickCount > 0)
{
FrameworkApplication.SetCurrentToolAsync(null);
clickCount = 0;
}
}
private AnnotationLayer AlLayerAnno(string layerAnno)
{
MapView mapView = MapView.Active;
AnnotationLayer alLayerAnno = mapView.Map.FindLayers(layerAnno).FirstOrDefault() as AnnotationLayer;
if (alLayerAnno == null)
{
MessageBox.Show(@"Does not exist.");
return null;
}
return alLayerAnno;
}
private Inspector Insp()
{
var insp = new Inspector();
return insp;
}
private EditOperation Edit()
{
var edit = new EditOperation
{
Name = "Annotation move",
SelectNewFeatures = false
};
return edit;
}
private QueryFilter Filter(long oid)
{
var filter = new QueryFilter
{
WhereClause = " OBJECTID = " + oid
};
return filter;
}
protected override Task OnToolDeactivateAsync(bool mapChange)
{
lock (_lock)
{
if (_graphic != null)
{
_graphic.Dispose();
_graphic = null;
}
}
return base.OnToolDeactivateAsync(mapChange);
}
private Selection AnnoSelected(AnnotationLayer alLayerAnno, QueryFilter filter)
{
var annoSelected = alLayerAnno.Select(filter);
return annoSelected;
}
private double[] CoordinatesCenter(Envelope envelope)
{
var mapPointCenter = GeometryEngine.Instance.Centroid(envelope);
double coordinatesX = mapPointCenter.X;
double coordinatesY = mapPointCenter.Y;
double[] array = { coordinatesX, coordinatesY };
return array;
}
private AnnotationProperties AnnotationProperties()
{
const string layerAnno = "BodyAnno";
var alLayerAnno = AlLayerAnno(layerAnno);
var insp = Insp();
insp.Load(alLayerAnno, oid);
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
return annoProperties;
}
private CIMSymbolReference SymbolReference(AnnotationProperties annoProperties, Geometry moved)
{
annoProperties.Shape = moved;
var cover = annoProperties.TextGraphic.Symbol.Symbol;
var textSymbol = cover as CIMTextSymbol;
_symbol = textSymbol;
var symbolReference = _symbol.MakeSymbolReference();
return symbolReference;
}
private double[] Coordinate(MapViewMouseEventArgs e, double coordinatesX, double coordinatesY)
{
var mapPoint = ActiveMapView.ClientToMap(e.ClientPoint);
var xCoordinate = mapPoint.X;
var x = xCoordinate - coordinatesX;
var yCoordinate = mapPoint.Y;
var y = yCoordinate - coordinatesY;
double[] array = { x, y };
return array;
}
protected override void OnToolMouseDown(MapViewMouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
e.Handled = true;
clickTime = DateTime.Now;
}
protected async override void OnToolMouseUp(MapViewMouseButtonEventArgs e)
{
MapView mapView = MapView.Active;
await QueuedTask.Run(() =>
{
if (shape == null)
{
clicking = DateTime.Now;
timeOfClick = (clicking - clickTime).TotalMilliseconds;
if (click == false)
{
click = true;
firstClick = DateTime.Now;
}
else
{
click = false;
secondClick = DateTime.Now;
}
time = (firstClick - secondClick).TotalMilliseconds;
if (secondClick.Ticks / TimeSpan.TicksPerMillisecond < firstClick.Ticks / TimeSpan.TicksPerMillisecond)
{
time = (secondClick - firstClick).TotalMilliseconds;
if (time < 0 && timeOfClick < 500)
{
DoubleClick();
}
}
clickCount++;
if (time < 0 && time > -1000)
{
DoubleClick();
}
if (timeOfClick > 500)
{
MessageBox.Show("Annotation deos not selected!");
click = false;
clickCount = 0;
}
if (clickCount > 1)
{
clickCount = 0;
}
return;
}
var annoProperties = AnnotationProperties();
var insp = Insp();
const string layerAnno = "BodyAnno";
var alLayerAnno = AlLayerAnno(layerAnno);
insp.Load(alLayerAnno, oid);
var edit = Edit();
var envelope = shape.Extent;
var array = CoordinatesCenter(envelope);
var coordinatesX = array.First();
var coordinatesY = array.Last();
if (shape.GeometryType != GeometryType.GeometryBag)
{
var mapPoint = ActiveMapView.ClientToMap(e.ClientPoint);
var xCoordinate = mapPoint.X;
var x = xCoordinate - coordinatesX;
var yCoordinate = mapPoint.Y;
var y = yCoordinate - coordinatesY;
if (side == "up" || side == "down")
{
var moved = GeometryEngine.Instance.Move(shape, x, 0);
annoProperties.Shape = moved;
}
else
{
var moved = GeometryEngine.Instance.Move(shape, 0, y);
annoProperties.Shape = moved;
}
clickCount = 0;
click = false;
}
insp.SetAnnotationProperties(annoProperties);
edit.Modify(insp);
edit.Execute();
oid = 0;
shape = null;
mapView.Map.SetSelection(null);
OnToolDeactivateAsync(true);
lock (_lock)
{
_tracking = TrackingState.NotTracking;
_geometry = null;
}
});
}
protected override Task HandleMouseDownAsync(MapViewMouseButtonEventArgs e)
{
return QueuedTask.Run(() =>
{
var mapPoint = ActiveMapView.ClientToMap(e.ClientPoint);
MapView mapView = MapView.Active;
const string layerAnno = "BodyAnno";
var alLayerAnno = AlLayerAnno(layerAnno);
var features = mapView.GetFeatures(mapPoint);
if (features.ContainsKey(alLayerAnno))
{
var tag = features.FirstOrDefault(t => t.Key == alLayerAnno);
var oidList = tag.Value;
oid = oidList[0];
var filter = Filter(oid);
var annotationFind = alLayerAnno.Search(filter);
while (annotationFind.MoveNext())
{
var actualRow = annotationFind.Current;
side = actualRow["SIDE"].ToString();
}
var annoProperties = AnnotationProperties();
AnnoSelected(alLayerAnno, filter);
shape = annoProperties.Shape;
var geometry = shape;
lock (_lock)
{
_workingLocation = null;
_geometry = geometry;
if (_graphic != null)
_graphic.Dispose();
_graphic = AddOverlay(geometry, _symbol.MakeSymbolReference());
_tracking = TrackingState.CanTrack;
}
}
});
}
protected override async void OnToolMouseMove(MapViewMouseEventArgs e)
{
lock (_lock)
{
if (_tracking == TrackingState.NotTracking)
return;
if (_workingLocation.HasValue)
{
_lastPosition = e.ClientPoint;
return;
}
_lastPosition = e.ClientPoint;
_workingLocation = e.ClientPoint;
_tracking = TrackingState.Tracking;
}
await QueuedTask.Run(() =>
{
var annoProperties = AnnotationProperties();
while (true)
{
Point? point;
Geometry geometry = null;
IDisposable graphic;
lock (_lock)
{
point = _lastPosition;
_lastPosition = null;
_workingLocation = point;
if (point == null || !point.HasValue)
{
_workingLocation = null;
break;
}
if (_geometry == null || _graphic == null)
{
_tracking = TrackingState.NotTracking;
break;
}
graphic = _graphic;
}
var envelope = shape.Extent;
var array = CoordinatesCenter(envelope);
var coordinatesX = array.First();
var coordinatesY = array.Last();
if (shape.GeometryType != GeometryType.GeometryBag)
{
var arrayCoordinate = Coordinate(e, coordinatesX, coordinatesY);
var x = arrayCoordinate.First();
var y = arrayCoordinate.Last();
if (side == "up" || side == "down")
{
var moved = GeometryEngine.Instance.Move(shape, x, 0);
var symbolReference = SymbolReference(annoProperties, moved);
UpdateOverlay(graphic, moved, symbolReference);
}
else
{
var moved = GeometryEngine.Instance.Move(shape, 0, y);
var symbolReference = SymbolReference(annoProperties, moved);
UpdateOverlay(graphic, moved, symbolReference);
}
}
}
});
}
Sorry for the quality of the video, my program broke so I had to use mobile.
Thanks for the tips.
David