How to create draggable pin in windows 10 to give

2020-07-27 16:11发布

问题:

I am working on MapControl in Windows 10 and I want to allow the user to drag the pin and when the user drops the pin want to get latitude and longitude of that position and get the location address by using API.I added Map Icon using following code

MapControl map = frameworkElement as MapControl;
map.MapServiceToken= "my service token";
BasicGeoposition councilPosition = new BasicGeoposition()
{
     Latitude = Convert.ToDouble(Info.GetType().GetRuntimeProperty("LATITUDE").GetValue(councilInfo, null)),
     Longitude = Convert.ToDouble(Info.GetType().GetRuntimeProperty("LONGITUDE").GetValue(councilInfo, null))
};

Geopoint pinPoint = new Geopoint(councilPosition);

MapIcon locationPin = new MapIcon();
locationPin.Image= RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Images/pushpin.png"));
locationPin.Title = councilInfo.COUNCIL_NAME;
locationPin.CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible;
locationPin.Location = councilPoint;
locationPin.NormalizedAnchorPoint = new Point(0.5, 1.0);
locationPin.ZIndex = 0;

map.MapElements.Add(locationPin);
await map.TrySetViewAsync(locationPin.Location, 15D, 0, 0, MapAnimationKind.Bow);

Can someone suggest which events are required to be used to achieve pick location functionality?

回答1:

Refer this link. They have specified display points using XAML. Instead of border you can have Grid with background pushpin image,listen to manipulation events for that grid.

here is the code to achieve what i told above.

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            BasicGeoposition snPosition = new BasicGeoposition() { Latitude = 47.7356039173901, Longitude = -122.310697222129

            };
            Geopoint snPoint = new Geopoint(snPosition);

            // Create a XAML border.
            Grid grid = new Grid
            {
                Width=100,
                Height=100,
                Background = new ImageBrush() {ImageSource= new BitmapImage(new Uri("ms-appx:///Assets/icon.png", UriKind.RelativeOrAbsolute)), Stretch = Stretch.UniformToFill}
            };
              grid.ManipulationMode = ManipulationModes.TranslateX|ManipulationModes.TranslateY;
 grid.ManipulationCompleted += Grid_ManipulationCompleted;
            grid.ManipulationDelta +=Grid_ManipulationDelta;
            // Center the map over the POI.
            MapControl1.Center = snPoint;
            MapControl1.ZoomLevel = 14;
            CompositeTransform tran = new CompositeTransform();
            grid.RenderTransform = tran;
            // Add XAML to the map.
            MapControl1.Children.Add(grid);
            MapControl.SetLocation(grid, snPoint);
            MapControl.SetNormalizedAnchorPoint(grid, new Point(0.5, 0.5));
        }  

        private void Grid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            CompositeTransform xform = grid.RenderTransform as CompositeTransform;


            xform.TranslateX += e.Delta.Translation.X;
            xform.TranslateY += e.Delta.Translation.Y;
         //   Rect point = grid.TransformToVisual(MapControl1).TransformBounds(new Rect(0,0, grid.Width, grid.Height));

            e.Handled = true;
          //  Geopoint gPoint;
           // MapControl1.GetLocationFromOffset(new Point(point.X, point.Y), out gPoint);
           // Debug.WriteLine(gPoint.Position.Latitude);
           // Debug.WriteLine(gPoint.Position.Longitude);
        }

  private void Grid_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            Rect point = grid.TransformToVisual(MapControl1).TransformBounds(new Rect(0, 0, grid.Width, grid.Height);
            Geopoint gPoint;
            MapControl1.GetLocationFromOffset(new Point(point.X, point.Y), out gPoint);
            Debug.WriteLine(gPoint.Position.Latitude);
            Debug.WriteLine(gPoint.Position.Longitude);
        }

Location fetched after drag is not that accurate. You can do bit R&D on how to fetch accuarate point wrt to MapControl



回答2:

I was unable to get the accepted answer to work. After a lot of research and help from this answer, I finally got it working. Here's a working sample:

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            InitializeComponent();

            var position = new Geopoint(new BasicGeoposition
            {
                Latitude = 30.3618,
                Longitude = -91.1067
            });
            var grid = new Grid
            {
                Width = 32,
                Height = 50
            };
            var pushpin = new Image()
            {
                Source = new BitmapImage(new Uri("ms-appx:///Assets/Pushpin.png")),
                Stretch = Stretch.Uniform,
                ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY,
                RenderTransform = new TranslateTransform()
            };
            pushpin.ManipulationStarted += Pushpin_ManipulationStarted;
            pushpin.ManipulationDelta += Pushpin_ManipulationDelta;
            pushpin.ManipulationCompleted += Pushpin_ManipulationCompleted;
            grid.Children.Add(pushpin);

            Map.Center = position;
            Map.Children.Add(grid);
            MapControl.SetLocation(grid, position);
            MapControl.SetNormalizedAnchorPoint(grid, new Point(0.5, 1));
        }

        private Geopoint GetPosition(Image pushpin)
        {
            var grid = pushpin.Parent as Grid;
            var anchor = MapControl.GetNormalizedAnchorPoint(grid);
            var offset = pushpin.TransformToVisual(Map).TransformPoint(new Point(grid.Width * anchor.X, grid.Height * anchor.Y));
            Map.GetLocationFromOffset(offset, out Geopoint position);
            return position;
        }

        private void Pushpin_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
            Map.PanInteractionMode = MapPanInteractionMode.Auto;

            var pushpin = sender as Image;
            var grid = pushpin.Parent as Grid;
            var position = GetPosition(pushpin);
            MapControl.SetLocation(grid, position);
            var transform = pushpin.RenderTransform as TranslateTransform;
            transform.X = 0;
            transform.Y = 0;
        }

        private void Pushpin_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
        {
            var pushpin = sender as Image;
            var transform = pushpin.RenderTransform as TranslateTransform;
            transform.X += e.Delta.Translation.X;
            transform.Y += e.Delta.Translation.Y;
        }

        private void Pushpin_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
        {
            Map.PanInteractionMode = MapPanInteractionMode.Disabled;
        }
    }