tags:

views:

682

answers:

1

My code does a .pantolatlong then a .showinfobox

The info box does not appear, unless I remove the pantolatlong. I guess it is stopping it. I tried adding it to the endpan event but that did not work.

What is the simplest way to pan to a pushpin and display the infobox for it?

I was using setcenter, but I discovered that sometimes setcenter pans, and this breaks it.

+1  A: 

After some insane googling, I came up with the solution, and I'll share it here so that others can hopefully not have the grief I went through.

I created and power my bing map using pure javascript, no sdk or iframe solutions. In my code, I generate the javascript to add all of the pins I want to the map, and inject it using an asp.net label.

If you call the setCenter() method on your Bing Map, it is supposed to instantly set the map, surprise surprise, to the coordinates you specify. And it does... most of the time. Occasionally though, it decides to pan between points. If you do a SetCenter, followed by a ShowInfoBox, it will work great, unless it decides to pan.

The solution? Being great programmers we are, we dive into the sdk, and it reveals there are events we can hook into to deal with these. There is an onendpan event, which is triggered after a pan is completed. There is also an onchangeview event, which triggers when the map jumps.

So we hook into these events, and try to display the infobox for our pushpin shape... but nothing happens. Why not?

You have to give it a few milliseconds to catch its breath, for unknown reasons, when the event is called. Using a setTimeout with 10 milliseconds seems to be fine. Your box will appear great after this.

The next problem is, you only want it to appear when it pans via whatever you used to make it flick between your pushpins (in my case, a table with onclick methods). I create/destroy the event handlers on the fly, although there are other options such as using a global variable to track if the user is panning, or if the system is panning in response to a click.

Finally, you have the one bug that comes from this. If you click a place in your list, and it jumps/pans to that location, the infobox will display fine. If the user dismisses it though, then clicks again on the list item, the map does not move, and therefore no events are triggered.

My solution to this is to detect if the map moved or not, by recording its long/lat, and using another setTimeout method, detecting if they changed 100ms later. If they did not, display the infobox.

There are other things you need to keep track of, as there is no way I can see to pass parameters to the eventhandlers so I use global javascript variables for this - you have to know which pushpin shape you are displaying, and also keep track of the previous mapcoordinates before checking to see if they changed.

It took me a while to piece all this together, but it seems to work. Here is my code, some sections are removed:

// An array of our pins to allow panning to them
var myPushPins = [];

// Used by the eventhandler
var eventPinIndex;
var oldMapCenter;

// Zoom in and center on a pin, then show its information box
function ShowPushPin(pinIndex) {
    eventPinIndex = pinIndex;
    oldMapCenter = map.GetCenter();
    map.AttachEvent("onendpan", EndPanHandler);
    map.AttachEvent("onchangeview", ChangeViewHandler);
    setTimeout("DetectNoMapChange();", 200);

    map.SetZoomLevel(9);
    map.SetCenter(myPushPins[pinIndex].GetPoints()[0]);

}


function EndPanHandler(e) {
    map.DetachEvent("onendpan", EndPanHandler);

    setTimeout("map.ShowInfoBox(myPushPins[eventPinIndex]);", 10);

}

function ChangeViewHandler(e) {
    map.DetachEvent("onchangeview", ChangeViewHandler);

    setTimeout("map.ShowInfoBox(myPushPins[eventPinIndex]);", 10);

}

function DetectNoMapChange(centerofmap) {

    if (map.GetCenter().Latitude == oldMapCenter.Latitude && map.GetCenter().Longitude == oldMapCenter.Longitude) {
        map.ShowInfoBox(myPushPins[eventPinIndex]);
    }
}
SLC