Hi Ethan,
I have tried writing the custom track layer.
However I 've run into a problem.
It seems that DrawTileCore is not called in the custom track layer.
is there another way to get the info required in FindNearestSnappingPointPixel and FindNearestSnappingPoint ?
here is my code for the layer:
> class SnapToLayerTrackInteractiveOverlay: TrackInteractiveOverlay
> {
> private List<FeatureLayer> toSnapShapeFeatureLayerList = new List<FeatureLayer>();
> private float tolerance;
> private DistanceUnit toleranceUnit;
> private GeographyUnit geographyUnit;
> private RectangleShape currentWorldExtent;
> private float mapWidth;
> private float mapHeight;
> private ToleranceCoordinates toleranceType;
> private bool enableSnapping = false;
> public SnapToLayerTrackInteractiveOverlay():base()
> {
> }
> //FeatureLayer for the layer to be snapped to.
> public List<FeatureLayer> ToSnapShapeFeatureLayerList
> {
> get { return toSnapShapeFeatureLayerList; }
> }
> public ToleranceCoordinates ToleranceType
> {
> get { return toleranceType; }
> set { toleranceType = value; }
> }
> public float Tolerance
> {
> get { return tolerance; }
> set { tolerance = value; }
> }
> public DistanceUnit ToleranceUnit
> {
> get { return toleranceUnit; }
> set { toleranceUnit = value; }
> }
> public bool EnableSnapping
> {
> get { return enableSnapping; }
> set { enableSnapping = value; }
> }
> protected override void OnVertexAdding(VertexAddingTrackInteractiveOverlayEventArgs e)
> {
> if (enableSnapping && ToSnapShapeFeatureLayerList != null && ToSnapShapeFeatureLayerList.Count > 0 && this.TrackMode == TrackMode.StraightLine)
> {
> var targetControlPoint = new PointShape(e.AddingVertex.X, e.AddingVertex.Y);
> PointShape snapPointShape = null;
> if (toleranceType == ToleranceCoordinates.Screen)
> {
> snapPointShape = FindNearestSnappingPointPixel(targetControlPoint);
> }
> else
> {
> snapPointShape = FindNearestSnappingPoint(targetControlPoint);
> }
> if (snapPointShape != null)
> {
> e.AddingVertex = new Vertex(snapPointShape);
> }
> }
> base.OnVertexAdding(e);
> }
> //Function to find if dragged control point is within the tolerance of a vertex of layer in screen (pixels) coordinates.
> private PointShape FindNearestSnappingPointPixel(PointShape targetPointShape)
> {
> PointShape toSnapPointShape = null;
> float nearestDistance = float.MaxValue;
> foreach (var toSnapShapeFeatureLayer in ToSnapShapeFeatureLayerList)
> {
> toSnapShapeFeatureLayer.Open();
> Collection<Feature> toSnapInMemoryFeatures = toSnapShapeFeatureLayer.FeatureSource.GetFeaturesNearestTo(targetPointShape, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns);
> toSnapShapeFeatureLayer.Close();
> if (toSnapInMemoryFeatures.Count == 1)
> {
> PointShape nearestPointInLayer = (PointShape)toSnapInMemoryFeatures[0].GetShape();
> float screenDistance = ExtentHelper.GetScreenDistanceBetweenTwoWorldPoints(currentWorldExtent, nearestPointInLayer, targetPointShape, mapWidth, mapHeight);
> if (screenDistance <= tolerance && screenDistance < nearestDistance)
> {
> toSnapPointShape = nearestPointInLayer;
> nearestDistance = screenDistance;
> }
> }
> }
> if (toSnapPointShape != null)
> {
> return new PointShape(toSnapPointShape.X, toSnapPointShape.Y);
> }
> return null;
> }
> //Function to find if dragged control point is within the tolerance of a vertex of layer in world coordinates.
> private PointShape FindNearestSnappingPoint(PointShape targetPointShape)
> {
> PointShape toSnapPointShape = null;
> double nearestDistance = double.MaxValue;
> foreach (var toSnapShapeFeatureLayer in ToSnapShapeFeatureLayerList)
> {
> toSnapShapeFeatureLayer.Open();
> Collection<Feature> toSnapInMemoryFeatures = toSnapShapeFeatureLayer.FeatureSource.GetFeaturesNearestTo(targetPointShape, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns);
> toSnapShapeFeatureLayer.Close();
> if (toSnapInMemoryFeatures.Count == 1)
> {
> PointShape nearestPointInLayer = (PointShape)toSnapInMemoryFeatures[0].GetShape();
> double Distance = nearestPointInLayer.GetDistanceTo(targetPointShape, geographyUnit, toleranceUnit);
> if (Distance <= tolerance && Distance < nearestDistance)
> {
> toSnapPointShape = nearestPointInLayer;
> nearestDistance = Distance;
> }
> }
> }
> if (toSnapPointShape != null)
> {
> return new PointShape(toSnapPointShape.X, toSnapPointShape.Y);
> }
> return null;
> }
> protected override void DrawTileCore(GeoCanvas geoCanvas)
> {
> //Sets the geography Unit used in FindNearestSnappingPoint function
> geographyUnit = geoCanvas.MapUnit;
> currentWorldExtent = geoCanvas.CurrentWorldExtent;
> mapWidth = geoCanvas.Width;
> mapHeight = geoCanvas.Height;
> base.DrawTileCore(geoCanvas);
> }
> }