4

In the WinRt/WP 8.1 MapControl, how do I differentiate between when the user changed the center of the screen by swiping vs a programmatic change?

The WinRt/WP 8.1 MapControl has a CenterChanged event ( http://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.maps.mapcontrol.centerchanged.aspx ), but this does not provide any info about what caused the center change.

Is there any other way of knowing whether or not the user changed the map center?


/* To give some more context, my specific scenario is as follows:
Given an app which shows a map, I want to track the gps position of a user.

  • If a gps position is found, I want to put a dot on the map and center the map to that point.
  • If a gps position change is found, I want to center the map to that point.
  • If the user changes the position of the map by touch/swipe, I no longer want to center the map when the gps position changes.

I could hack this by comparing gps position and center, but he gps position latLng is a different type & precision as the Map.Center latLng. I'd prefer a simpler, less hacky solution. */

koenmetsu
  • 1,044
  • 9
  • 31
  • 1
    I don't think there's anything you could do properly. The only things that comes to mind, is having a hack check for user input and then check how close it happened to the event. However, since you'd be changing it programmatically, can't you determine it when you do that? Maybe overwrite the handler, right before you change it and overwrite it again after you handled it. Could you show some more context on what you want to achieve? – Kenneth Nov 07 '14 at 12:35
  • @Kenneth I've updated the question with my specific scenario. – koenmetsu Nov 07 '14 at 13:10
  • @Kenneth the problem with checking it programmatically is that those events can happen completely async from each other. – koenmetsu Nov 07 '14 at 13:11

1 Answers1

1

I solved this by setting a bool ignoreNextViewportChanges to true before calling the awaitable TrySetViewAsync and reset it to false after the async action is done.

In the event handler, I immediately break the Routine then ignoreNextViewportChanges still is true.

So in the end, it looks like:

bool ignoreNextViewportChanges;

public void HandleMapCenterChanged() {
    Map.CenterChanged += (sender, args) => {
        if(ignoreNextViewportChanges)
            return;
        //if you came here, the user has changed the location
        //store this information somewhere and skip SetCenter next time
    }
}

public async void SetCenter(BasicGeoposition center) {
    ignoreNextViewportChanges = true;
    await Map.TrySetViewAsync(new Geopoint(Center));
    ignoreNextViewportChanges = false;
}

If you have the case that SetCenter might be called twice in parallel (so that the last call of SetCenter is not yet finished, but SetCenter is called again), you might need to use a counter:

int viewportChangesInProgressCounter;

public void HandleMapCenterChanged() {
    Map.CenterChanged += (sender, args) => {
        if(viewportChangesInProgressCounter > 0)
            return;
        //if you came here, the user has changed the location
        //store this information somewhere and skip SetCenter next time
    }
}

public async void SetCenter(BasicGeoposition center) {
    viewportChangesInProgressCounter++;
    await Map.TrySetViewAsync(new Geopoint(Center));
    viewportChangesInProgressCounter--;
}
sibbl
  • 3,203
  • 26
  • 38
  • I've thought about this before, but the TrySetViewAsync causes multiple MapCenterChanges since it uses a "zoom out, fly to, zoom in" kind of animation. I'm not sure how you could use the counter to take this into account. – koenmetsu Nov 11 '14 at 08:28
  • I've added an example which shows the usage of a counter. This is only necessary when you call SetCenter again while another TrySetViewAsync is still in progress and hasn't finished yet. – sibbl Nov 11 '14 at 08:33
  • I guess this is a work-around, I had to implement another one because of other issues like threading. Too bad there's not a baked-in solution for this problem. Thanks for your answer. – koenmetsu Jan 09 '15 at 08:58