Search code examples
c#wpfsilverlightwindows-phone-8dictionary

Windows Phone make pushpin icon move on map between start and end location


I am creating an app in which I am trying to move bike icon as user travel on his path. I am getting new location of the user by subscribing to position changed event of Geolocator class. I am setting the pushpin to this new location every time. But the problem is that pushpin doesn't move on that path like with animation but suddenly goes that new location. Is there any way to animate the pushpin to move along a path using start and end point. This should also include scenario like turning on curved path.

Current code:

XAML:

<maps:Map x:Name="myMap" ZoomLevel="16">
    <toolkit:MapExtensions.Children>
        <toolkit:UserLocationMarker x:Name="UserLocationMarker" />
        <!--<toolkit:Pushpin x:Name="MyPushpin" Content="My Position"></toolkit:Pushpin>-->
    </toolkit:MapExtensions.Children>
</maps:Map>

C#:

Geolocator geolocator = new Geolocator();
this.geolocator.MovementThreshold = 0;
 RouteQuery MyQuery = null;
        GeocodeQuery Mygeocodequery = null;

    async void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
    geolocator.PositionChanged += geolocator_PositionChanged;
    Geoposition geoposition = await geolocator.GetGeopositionAsync();
    myMap.Center = geoposition.Coordinate.ToGeoCoordinate();
}

void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
    Dispatcher.BeginInvoke(() =>
    {
        UserLocationMarker marker = (UserLocationMarker)this.FindName("UserLocationMarker");
        marker.GeoCoordinate = new GeoCoordinate(args.Position.Coordinate.Latitude, args.Position.Coordinate.Longitude);
    });

}



 private void MovePinOnPath(bool isGeodesic)
        {
            ClearMap();
            Pushpin marker = (Pushpin)this.FindName("MyPushpin");
            marker.GeoCoordinate = path[0]; 

            currentAnimation = new Animations.PathAnimation(path, (coord, pathIdx, frameIdx) =>
            {
                marker.GeoCoordinate = coord;
            }, isGeodesic, 10000);

            currentAnimation.Play();
        }

        private void ClearMap()
        {
            if (currentAnimation != null)
            {
                currentAnimation.Stop();
                currentAnimation = null;
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MovePinOnPath(true);
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            if(!string.IsNullOrWhiteSpace(txtSearchPlace.Text))
            {
                Mygeocodequery = new GeocodeQuery();
                Mygeocodequery.SearchTerm = txtSearchPlace.Text;
                Mygeocodequery.GeoCoordinate = new GeoCoordinate(myMap.Center.Latitude, myMap.Center.Longitude);

                Mygeocodequery.QueryCompleted += Mygeocodequery_QueryCompleted;
                Mygeocodequery.QueryAsync();
            }

        }

        private void Mygeocodequery_QueryCompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
        {
            if (e.Error == null
                && e.Result.Count > 0)
            {
                MyQuery = new RouteQuery();
                path.Add(e.Result[0].GeoCoordinate);
                MyQuery.Waypoints = path;
                MyQuery.QueryCompleted += MyQuery_QueryCompleted;
                MyQuery.QueryAsync();
                Mygeocodequery.Dispose();
            }
        }

        private void MyQuery_QueryCompleted(object sender, QueryCompletedEventArgs<Route> e)
        {
            if (e.Error == null)
            {
                Route MyRoute = e.Result;
                MapRoute MyMapRoute = new MapRoute(MyRoute);
                myMap.AddRoute(MyMapRoute);
                MyQuery.Dispose();

               path = e.Result.Geometry.ToList();
               btnPlay.IsEnabled = true;
            }
        }

Solution

  • You have a couple of challenges here. The updated location will not be able to tell you the path that the user took travelling from A to B, so animating curves etc will be difficult.

    Initially I would suggest you change your MovementThreshold to 0 so that you get as many updates as possible to give you the highest granularity, this should minimise any error you will see for travelling on a curved path, especially at higher zoom levels.

    Regarding animating between the 'old' and 'new' locations, there is an excellent blog article here:

    Bring your maps to life: Creating animations with Bing Maps

    This covers all sorts of pushpin animations which you should be able to utilise in your project.