I am trying to display multiple bing maps on the same page, with each map having a specified location displayed based on a geocode.
The issue I am having is this...
I built a single page html example based on the msdn example provided. The whole markup is below, copied and saved as an html file it should work as mentioned above. I just whipped this up for ease of understanding and better communication with my question.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null;
var mapId = '';
var geocode = ''
function InistionaliseMaps()
{
//alert('1');
InistialiseMap('mapDiv1', 'London');
//alert('2');
InistialiseMap('mapDiv2', 'Barcelona');
//alert('3');
InistialiseMap('mapDiv3', 'Auckland');
//alert('4');
InistialiseMap('mapDiv4', 'New York');
//alert('5');
InistialiseMap('mapDiv5', 'Amsterdam');
}
function InistialiseMap(mId, gc)
{
mapId = mId;
geocode = gc;
GetMap();
ClickGeocode();
}
function GetMap()
{
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById(mapId),{credentials:"Auy_rZ68nbxt5cE4EYg7o1pFD3IpEg6sgNNWC8RyP04f12t9GSf0YQzlnBmgyJV3", mapTypeId:Microsoft.Maps.MapTypeId.road});
}
function ClickGeocode(credentials)
{
map.getCredentials(MakeGeocodeRequest);
}
function MakeGeocodeRequest(credentials)
{
var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations?query=" + encodeURI(geocode) + "&output=json&jsonp=GeocodeCallback&key=" + credentials;
CallRestService(geocodeRequest);
}
function GeocodeCallback(result)
{
alert("Found location: " + result.resourceSets[0].resources[0].name);
if (result &&
result.resourceSets &&
result.resourceSets.length > 0 &&
result.resourceSets[0].resources &&
result.resourceSets[0].resources.length > 0)
{
// Set the map view using the returned bounding box
var bbox = result.resourceSets[0].resources[0].bbox;
var viewBoundaries = Microsoft.Maps.LocationRect.fromLocations(new Microsoft.Maps.Location(bbox[0], bbox[1]), new Microsoft.Maps.Location(bbox[2], bbox[3]));
map.setView({ bounds: viewBoundaries});
// Add a pushpin at the found location
var location = new Microsoft.Maps.Location(result.resourceSets[0].resources[0].point.coordinates[0], result.resourceSets[0].resources[0].point.coordinates[1]);
var pushpin = new Microsoft.Maps.Pushpin(location);
map.entities.push(pushpin);
}
}
function CallRestService(request)
{
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", request);
document.body.appendChild(script);
}
</script>
</head>
<body onload="InistionaliseMaps();">
<div id='mapDiv1' style="position:relative; width:400px; height:400px;"></div>
<div id='mapDiv2' style="position:relative; width:400px; height:400px;"></div>
<div id='mapDiv3' style="position:relative; width:400px; height:400px;"></div>
<div id='mapDiv4' style="position:relative; width:400px; height:400px;"></div>
<div id='mapDiv5' style="position:relative; width:400px; height:400px;"></div>
</body>
</html>
I believe this is probably occurring as the page is loading to fast and the consecutive calls to the REST service are overlapping, or an object used in the REST service is not being destroyed before the next call or something like that. I really am a tad confused to be honest.
If anyone knows what might be going on here, a way around the problem or a better way to do this via Bing maps - it would be much appreciated and I shall be forever in your stack-debt. Thanks.
I have not tried out your code, via inspection I think I spotted some problems that would cause the behavior you are seeing. The problem has to do with you using a global variable to reference your map in GeocodeCallback()
. GeocodeCallback()
is a callback function that is run after the geocoding is complete, there is no guaratee that if you issue multiple CallRestService()s
, GeocodeCallback()
for each request will be called in the same sequence. You set the map
variable to your current map in GetMap()
, and then proceed to call CallRestService()
, and then subsequently call InistialiseMap()
again, which will override the map
variable with a new map. If GeocodeCallback()
is called before InistialiseMap()
, you will have no problems.(As illlustrated by the use of alerts which most likely forces this to happen). However, chances are multiple InistialiseMap()
are run before the GeocodeCallback()s
are called, so there is no determining which map gets updated with the geocoding results returned by GeocodeCallback()
.
Here is an easy solution to your problem. Not very elegant and I haven't tested the code, but the idea is to have a separate geocode callback for each map, as well is storing each map in its own varable.
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var mapOne = null;
var mapTwo = null;
var geocode = ''
function InistionaliseMaps()
{
InistialiseMap('mapDiv1', mapOne, 'London');
InistialiseMap('mapDiv2', mapTwo,'Barcelona');
}
function InistialiseMap(mId, mapVar, gc)
{
geocode = gc;
GetMap(mId, mapVar);
ClickGeocode(mapVar);
}
function GetMap(mapIdName, mapVar )
{
// Initialize the map
mapVar = new Microsoft.Maps.Map(document.getElementById(mapId),{credentials:"Auy_rZ68nbxt5cE4EYg7o1pFD3IpEg6sgNNWC8RyP04f12t9GSf0YQzlnBmgyJV3", mapTypeId:Microsoft.Maps.MapTypeId.road});
mapVar.MapIdName = mapIdName ;
}
function ClickGeocode(mapVar )
{
mapVar.getCredentials(MakeGeocodeRequest)
}
function MakeGeocodeRequest(credentials)
{
// Figure out how to get the map that called this...
var mapThatCalledThis = ...
var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations?query=" + encodeURI(geocode) + "&output=json&jsonp=GeocodeCallback"+mapThatCalledThis .MapIdName+"&key=" + credentials;
CallRestService(geocodeRequest);
}
function GeocodeCallbackmapDiv1(result)
{
// common stuff
mapOne.entities.push(pushpin);
}
}
function GeocodeCallbackmapDiv2(result)
{
// common stuff
mapTwo.entities.push(pushpin);
}
}
function CallRestService(request)
{
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", request);
document.body.appendChild(script);
}
</script>
Good luck.