Map Ruler for Distance Measurement

Topics: WPF
May 20, 2013 at 11:55 AM
Hi,
  1. Is this the "right/best" way?
  2. How can the text be placed along the route line?
Thanks,
superware
public class MapRuler
{
    private GMapControl _map;
    private GMapMarker[] _anchors;
    private GMapMarker _route;
    private GMapMarker _text;
    private GMapMarker _currentAnchor;
    private PointLatLng _fixedAnchorPosition;

    public MapRuler(GMapControl map, PointLatLng p, int zindex)
    {
        _anchors = new GMapMarker[2];
        _route = new GMapMarker(p);
        for (int i = 0; i < 2; i++)
        {
            Ellipse ellipse = new Ellipse()
            {
                Width = 16,
                Height = 16,
                Fill = Brushes.Red,
                Stroke = Brushes.White,
                StrokeThickness = 3,
                Tag = i,
            };
            ellipse.MouseDown += new MouseButtonEventHandler(Anchor_MouseDown);
            ellipse.MouseUp += new MouseButtonEventHandler(Anchor_MouseUp);
            GMapMarker anchor = new GMapMarker(p)
            {
                Offset = new Point(-8, -8),
                Shape = ellipse,
                ZIndex = zindex,
            };
            _anchors[i] = anchor;
            _route.Route.Add(p);
            map.Markers.Add(anchor);
            zindex++;
        }
        _route.RegenerateRouteShape(map);
        map.Markers.Add(_route);
        _text = new GMapMarker(p);
        TextBlock textBlock = new TextBlock();
        textBlock.Text = "test";
        _text.Shape = textBlock;
        map.Markers.Add(_text);
        map.MouseMove += new MouseEventHandler(Map_MouseMove);
        _map = map;
    }

    private void Anchor_MouseDown(object sender, MouseButtonEventArgs e)
    {
        int index = (int)((Ellipse)sender).Tag;
        _currentAnchor = _anchors[index];
        _fixedAnchorPosition = _anchors[index == 0 ? 1 : 0].Position;
    }
    private void Anchor_MouseUp(object sender, MouseButtonEventArgs e)
    {
        _currentAnchor = null;
    }
    private void Map_MouseMove(object sender, MouseEventArgs e)
    {
        if (_currentAnchor != null)
        {
            Point point = e.GetPosition(_map);
            PointLatLng pointLatLng = _map.FromLocalToLatLng((int)point.X, (int)point.Y);
            _currentAnchor.Position = pointLatLng;
            _route.Position = pointLatLng;
            _route.Route[0] = pointLatLng;
            _route.Route[1] = _fixedAnchorPosition;
            _route.RegenerateRouteShape(_map);
            double distance = _map.MapProvider.Projection.GetDistance(pointLatLng, _fixedAnchorPosition);
            ((TextBlock)_text.Shape).Text = distance.ToString();
            e.Handled = true;
        }
    }

    public void Clear()
    {
        foreach (GMapMarker anchor in _anchors)
        {
            _map.Markers.Remove(anchor);
            anchor.Clear();
        }
        _map.Markers.Remove(_route);
        _route.Clear();
        _map.Markers.Remove(_text);
        _text.Clear();
    }
}
May 20, 2013 at 1:17 PM
if it works right, it's good enough ;}
May 20, 2013 at 1:45 PM
Performance is also important, but I guess you already know that :)
Any thoughts regarding the TextBlock position parallel to the route line?
It might be a good idea to include this in your WPF demo.