Search code examples
mapsbing-mapsbinginfobox

Bing Maps Polygon InfoBox


I have setup a map with polygons around the countries on the map, and want to add an infobox so that on hover some information will be displayed for each country.

I can get infoboxes displaying easy enough without the polygons, but when assigning them to the PolygonOptions class, nothing happens. The docs say that so long as I have the Bing Themes module loaded (Which I do), the infoboxes will show up on hover and click.

There seems to be zero documentation/examples of this, so hoping you clever folks can help out.

Here is some of the relevant code;

    var center = this.map.getCenter();

    // Create an info box 
    var infoboxOptions = {
        width: 300,
        height: 100,
        title: 'Testing', // sourceItems.data.dataset[0].data[index].key,
        description: "Visits: 20", // + sourceItems.data.dataset[0].data[index].visits,
        showPointer: true,
        titleClickHandler: this.polygonInfo,
        offset: new Microsoft.Maps.Point(-100, 0),
        typeName: Microsoft.Maps.InfoboxType.mini,
        zIndex: 1000
    };
    var polyinfobox = new Microsoft.Maps.Infobox(center, infoboxOptions);

    var polygonOptions = {
        fillColor: Microsoft.Maps.Color.fromHex(fillColour),
        strokeColor: Microsoft.Maps.Color.fromHex(fillColour),
        strokeThickness: 1,
        infobox: polyinfobox
    };

    var result = new Microsoft.Maps.Polygon(vertices, polygonOptions);

Solution

  • There is a working code sample in the interactive SDK for the Bing Maps V7 control here: http://www.bingmapsportal.com/ISDK/AjaxV7#BingThemeModule6

    Note that creating an infobox for each shape is very inefficient and will hurt performance if you have a lot of shapes. A better method is to have one infobox and dynamically populate it's data. I wrote a blog post on this here: http://rbrundritt.wordpress.com/2011/10/13/multiple-pushpins-and-infoboxes-in-bing-maps-v7/ If you want to use this approach here is a code sample:

    <!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, dataLayer, infobox;
    
            function GetMap()
            {  
                map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), {
                    credentials: "YOUR_BING_MAPS_KEY"
                });
    
                dataLayer = new Microsoft.Maps.EntityCollection();
                map.entities.push(dataLayer);
    
                var infoboxLayer = new Microsoft.Maps.EntityCollection();
                map.entities.push(infoboxLayer);
    
                infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
                infoboxLayer.push(infobox);
    
                AddData();
            }
    
            function AddData(){
                var polygon = new Microsoft.Maps.Polygon([
                    new Microsoft.Maps.Location(45, -110), 
                    new Microsoft.Maps.Location(65, -90), 
                    new Microsoft.Maps.Location(45, -70)]);     
    
                polygon.Metadata = {
                    title: 'Hello',
                    description: 'World'
                };
    
                dataLayer.push(polygon);
    
                Microsoft.Maps.Events.addHandler(polygon, 'click', displayInfobox);
                Microsoft.Maps.Events.addHandler(polygon, 'mouseover', displayInfobox);
            }
    
            function displayInfobox(e){
                if(e.target){
                    var point = new Microsoft.Maps.Point(e.getX(), e.getY());       
                    var loc = map.tryPixelToLocation(point);
    
                    infobox.setLocation(loc);
    
                    var opt = e.target.Metadata;
    
                    if(opt){
                        if(e.target.getIcon){ //is pushpin
                            opt.offset = new Microsoft.Maps.Point(0,20);
                        }else{
                            opt.offset = new Microsoft.Maps.Point(0,0);
                        }
    
                        opt.visible = true;
                        infobox.setOptions(opt);
                    }
                }
            }
          </script>
       </head>
       <body onload="GetMap();">
          <div id='mapDiv' style="position:relative; width:600px; height:600px;"></div> 
       </body>
    </html>