none
Bing Map V8 Cluster replace TestDataGenerator data with real time data RRS feed

  • Question

  • I am just starting with Bing map. Gone through few examples in official documentation. 

    Example from [Bing map V8 official documentation][1]

    <!DOCTYPE html>
    <html>
    <head>
    <title></title>
    <meta charset="utf-8" />
    <script type='text/javascript'
    src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    <script type="text/javascript">
    var map, clusterLayer;

    function GetMap() {
    map = new Microsoft.Maps.Map('#myMap',{
    credentials: 'Your Bing Maps Key',
    zoom: 3
    });

    Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
    //Generate 3000 random pushpins in the map view.
    var pins = Microsoft.Maps.TestDataGenerator.getPushpins(3000, map.getBounds());

    //Create a ClusterLayer with options and add it to the map.
    clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
    clusteredPinCallback: customizeClusteredPin
    });
    map.layers.insert(clusterLayer);
    });
    }

    function customizeClusteredPin(cluster) {
      //Add click event to clustered pushpin
    Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
    }

    function clusterClicked(e) {
    if (e.target.containedPushpins) {
    var locs = [];
    for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
    //Get the location of each pushpin.
    locs.push(e.target.containedPushpins[i].getLocation());
    }

    //Create a bounding box for the pushpins.
    var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);

    //Zoom into the bounding box of the cluster. 
    //Add a padding to compensate for the pixel area of the pushpins.
    map.setView({ bounds: bounds, padding: 100 });
    }
    }
    </script>
    </head>
    <body>
    <div id="myMap" style="width:600px;height:400px;"></div>
    </body>
    </html>

    In above bing map cluster example how to replace the TestDataGenerator data with realtime data JSON like below

        mapData = [{"Name":"Point: 0","Latitude":22.0827,"Longitude":80.2707},
                   {"Name":"Point: 1","Latitude":24.0827,"Longitude":80.2707},
                   {"Name":"Point: 2","Latitude":26.0827,"Longitude":80.2707},
                   {"Name":"Point: 3","Latitude":28.0827,"Longitude":80.2707},
                   {"Name":"Point: 4","Latitude":20.0827,"Longitude":80.2707},
                   {"Name":"Point: 5","Latitude":22.0827,"Longitude":82.2707},
                   {"Name":"Point: 6","Latitude":30.0827,"Longitude":80.2707},
                   {"Name":"Point: 7","Latitude":22.0827,"Longitude":84.2707},
                   {"Name":"Point: 8","Latitude":32.0827,"Longitude":84.2707},
                   {"Name":"Point: 9","Latitude":18.0827,"Longitude":80.2707}];
    

    When I pass above object in ClusterLayer I am getting following error

    Uncaught TypeError: i[t].getLocation is not a function(…)

    • Edited by shamoh19 Thursday, December 1, 2016 1:42 PM Edited
    Thursday, December 1, 2016 1:03 PM

Answers

  • You have to loop through your data and turn it into pushpins. Here's a code sample:

    var pins = [];
    
    for(var i = 0;i < mapData.length;i++){
        var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
    
        //Store the original data object in the pushpins metadata so that you can access other properties like Name.
        pin.metedata = mapData[i];
    
        pins.push(pin);
    }
    
    //Now "pins" is an array of pushpins. Add them to the map or to the clustering layer.


    [Blog] [twitter] [LinkedIn]

    Friday, December 2, 2016 11:07 AM
  • Here is a modified version of your code with the code I provided simply copy/pasted in place of the test data generator code:

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    	<meta charset="utf-8" />
    	<script type="text/javascript">
    		var mapData = [{"Name":"Point: 0","Latitude":22.0827,"Longitude":80.2707},
    				   {"Name":"Point: 1","Latitude":24.0827,"Longitude":80.2707},
    				   {"Name":"Point: 2","Latitude":26.0827,"Longitude":80.2707},
    				   {"Name":"Point: 3","Latitude":28.0827,"Longitude":80.2707},
    				   {"Name":"Point: 4","Latitude":20.0827,"Longitude":80.2707},
    				   {"Name":"Point: 5","Latitude":22.0827,"Longitude":82.2707},
    				   {"Name":"Point: 6","Latitude":30.0827,"Longitude":80.2707},
    				   {"Name":"Point: 7","Latitude":22.0827,"Longitude":84.2707},
    				   {"Name":"Point: 8","Latitude":32.0827,"Longitude":84.2707},
    				   {"Name":"Point: 9","Latitude":18.0827,"Longitude":80.2707}];
    
    		var map, clusterLayer;
    
    		function GetMap() {
    			map = new Microsoft.Maps.Map('#myMap',{
    				credentials: 'Your Bing Maps Key',
    				zoom: 3
    			});
    
    			Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
    				var pins = [];
    
    				for(var i = 0;i < mapData.length;i++){
    					var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
    
    					//Store the original data object in the pushpins metadata so that you can access other properties like Name.
    					pin.metadata = mapData[i];
    
    					pins.push(pin);
    				}
    
    				//Create a ClusterLayer with options and add it to the map.
    				clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
    					clusteredPinCallback: customizeClusteredPin
    				});
    				map.layers.insert(clusterLayer);
    			});
    		}
    
    		function customizeClusteredPin(cluster) {
    			//Add click event to clustered pushpin
    			Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
    		}
    
    		function clusterClicked(e) {
    			if (e.target.containedPushpins) {
    			var locs = [];
    			for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
    				//Get the location of each pushpin.
    				locs.push(e.target.containedPushpins[i].getLocation());
    			}
    
    				//Create a bounding box for the pushpins.
    				var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);
    
    				//Zoom into the bounding box of the cluster. 
    				//Add a padding to compensate for the pixel area of the pushpins.
    				map.setView({ bounds: bounds, padding: 100 });
    			}
    		}
    	</script>
    	<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
    	<div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>

    Note, if you don't see anything on the map, be sure to pan over Asia as that is where you data is. If you are expecting it in the US, your longitude values should be negative.


    [Blog] [twitter] [LinkedIn]


    Friday, July 7, 2017 1:02 AM
  • I've modified your code to simplify it. The following code show an infobox when you click on a single pushpin and zooms the map in when you click on clusters:

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    	<meta charset="utf-8" />
    	<script type="text/javascript">
    		var mapData = [{ "Title": "Place1", "Description":"Person1", "Latitude": 38.2231, "Longitude": -85.666604 },
                           { "Title": "Place2", "Description":"Person2", "Latitude": 38.22345, "Longitude": -85.66625 },
                           { "Title": "Place3", "Description":"Person3", "Latitude": 38.244, "Longitude": -85.726 },
                           { "Title": "Place4", "Description":"Person4", "Latitude": 38.26, "Longitude": -85.747 },
                           { "Title": "Place5", "Description":"Person5", "Latitude": 38.2179, "Longitude": -85.7612 }];
    
    		var map, infobox, clusterLayer;
    
    		function GetMap() {
    			map = new Microsoft.Maps.Map('#myMap',{
    				credentials: 'Your Bing Maps Key',
    				zoom: 3
    			});
    			
    			//Add an infobox to the map.
    			infobox = new Microsoft.Maps.Infobox(map.getCenter(), { visible: false });
    			infobox.setMap(map);
    
    			Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
    				var pins = [];
    
    				for(var i = 0;i < mapData.length;i++){
    					var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
    
    					//Store the original data object in the pushpins metadata so that you can access other properties like Name.
    					pin.metadata = mapData[i];
    
    					pins.push(pin);
    				}
    
    				//Create a ClusterLayer with options and add it to the map.
    				clusterLayer = new Microsoft.Maps.ClusterLayer(pins);
    				
    				//Add a click event to the cluster layer to open an infobox.
    				Microsoft.Maps.Events.addHandler(clusterLayer, 'click', showInfobox);
    				
    				map.layers.insert(clusterLayer);
    			});
    		}
    
    		function customizeClusteredPin(cluster) {
    			//Add click event to clustered pushpin
    			Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
    		}
    			
    		function showInfobox(e) {
    			var pin = e.target;
    			
    			//Check to see if the pushpin is a cluster.
       			if (pin.containedPushpins) {
    				//Cluster clicked, zoom the map in.
    				var locs = [];
    				for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
    					//Get the location of each pushpin.
    					locs.push(e.target.containedPushpins[i].getLocation());
    				}
    
    				//Create a bounding box for the pushpins.
    				var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);
    
    				//Zoom into the bounding box of the cluster. 
    				//Add a padding to compensate for the pixel area of the pushpins.
    				map.setView({ bounds: bounds, padding: 100 });
    			} else {
    				//Pushpin clicked, show infobox.
    				infobox.setOptions({ 
    					location: pin.getLocation(), 
    					title: pin.metadata.Title,
    					description: pin.metadata.Description,
    					visible: true
    				});	 
    			}		  
    		}
    	</script>
    	<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
    	<div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    Friday, July 7, 2017 4:37 PM
  • To style the infobox you have to create an HTML string and set it as the htmlContent of the infobox. Here is an example: https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk#addCustomInfobox+JS

    [Blog] [twitter] [LinkedIn]

    Monday, July 10, 2017 11:58 PM
  • You need to use that custom HTML infobox template every time you set the content of the infobox. Don't use title/description of the infobox if you are going to use htmlContent. For example:

    infobox.setOptions({
        location: pin.getLocation(),
        htmlContent: infoboxTemplate.replace('{title}', pin.metadata.Title).replace('{description}', pin.metadata.Description),
        showCloseButton: true,
        visible: true
    });


    [Blog] [twitter] [LinkedIn]

    Tuesday, July 11, 2017 5:47 PM
  • The pushpin text property option is part of the API. Most of the V7 pushpin options are supported in V8. 

    [Blog] [twitter] [LinkedIn]

    Wednesday, July 12, 2017 1:01 AM
  • Yes, you have to create function that has your logic to close the infobox. Something as simple as:

    function closeInfoBox(){
        infobox.setOptions({ visible: false });
    }


    [Blog] [twitter] [LinkedIn]

    Wednesday, July 12, 2017 1:03 AM

All replies

  • You have to loop through your data and turn it into pushpins. Here's a code sample:

    var pins = [];
    
    for(var i = 0;i < mapData.length;i++){
        var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
    
        //Store the original data object in the pushpins metadata so that you can access other properties like Name.
        pin.metedata = mapData[i];
    
        pins.push(pin);
    }
    
    //Now "pins" is an array of pushpins. Add them to the map or to the clustering layer.


    [Blog] [twitter] [LinkedIn]

    Friday, December 2, 2016 11:07 AM
  • hello--even with your help, I still cannot figure out how to make the individual pushpins show up at their respective locations. Could you be more explicit for dummy?

    AnneY

    Thursday, July 6, 2017 4:54 PM
  • Here is a modified version of your code with the code I provided simply copy/pasted in place of the test data generator code:

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    	<meta charset="utf-8" />
    	<script type="text/javascript">
    		var mapData = [{"Name":"Point: 0","Latitude":22.0827,"Longitude":80.2707},
    				   {"Name":"Point: 1","Latitude":24.0827,"Longitude":80.2707},
    				   {"Name":"Point: 2","Latitude":26.0827,"Longitude":80.2707},
    				   {"Name":"Point: 3","Latitude":28.0827,"Longitude":80.2707},
    				   {"Name":"Point: 4","Latitude":20.0827,"Longitude":80.2707},
    				   {"Name":"Point: 5","Latitude":22.0827,"Longitude":82.2707},
    				   {"Name":"Point: 6","Latitude":30.0827,"Longitude":80.2707},
    				   {"Name":"Point: 7","Latitude":22.0827,"Longitude":84.2707},
    				   {"Name":"Point: 8","Latitude":32.0827,"Longitude":84.2707},
    				   {"Name":"Point: 9","Latitude":18.0827,"Longitude":80.2707}];
    
    		var map, clusterLayer;
    
    		function GetMap() {
    			map = new Microsoft.Maps.Map('#myMap',{
    				credentials: 'Your Bing Maps Key',
    				zoom: 3
    			});
    
    			Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
    				var pins = [];
    
    				for(var i = 0;i < mapData.length;i++){
    					var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
    
    					//Store the original data object in the pushpins metadata so that you can access other properties like Name.
    					pin.metadata = mapData[i];
    
    					pins.push(pin);
    				}
    
    				//Create a ClusterLayer with options and add it to the map.
    				clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
    					clusteredPinCallback: customizeClusteredPin
    				});
    				map.layers.insert(clusterLayer);
    			});
    		}
    
    		function customizeClusteredPin(cluster) {
    			//Add click event to clustered pushpin
    			Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
    		}
    
    		function clusterClicked(e) {
    			if (e.target.containedPushpins) {
    			var locs = [];
    			for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
    				//Get the location of each pushpin.
    				locs.push(e.target.containedPushpins[i].getLocation());
    			}
    
    				//Create a bounding box for the pushpins.
    				var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);
    
    				//Zoom into the bounding box of the cluster. 
    				//Add a padding to compensate for the pixel area of the pushpins.
    				map.setView({ bounds: bounds, padding: 100 });
    			}
    		}
    	</script>
    	<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
    	<div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>

    Note, if you don't see anything on the map, be sure to pan over Asia as that is where you data is. If you are expecting it in the US, your longitude values should be negative.


    [Blog] [twitter] [LinkedIn]


    Friday, July 7, 2017 1:02 AM
  • Your code works great and thank you so much.

    In trying to add an infobox, I have no success and am scrambled, so if you can show me my errors, having enough time, many thanks again.

     <script type="text/javascript">
           
            var mapData = [{ "Title": "Place1", "Description":"Person1", "Latitude": 38.2231, "Longitude": -85.666604 },
                           { "Title": "Place2", "Description":"Person2", "Latitude": 38.22345, "Longitude": -85.66625 },
                           { "Title": "Place3", "Description":"Person3", "Latitude": 38.244, "Longitude": -85.726 },
                           { "Title": "Place4", "Description":"Person4", "Latitude": 38.26, "Longitude": -85.747 },
                           { "Title": "Place5", "Description":"Person5", "Latitude": 38.2179, "Longitude": -85.7612 }];

            var map, clusterLayer, infobox;
            var infoboxTemplate = '<div class="customInfobox"><div class="title">{title}</div>{description}</div>';
            function GetMap() {
                var navigationBarMode = Microsoft.Maps.NavigationBarMode;
                map = new Microsoft.Maps.Map('#myMap', {
                    credentials: '',
                    navigationBarMode: navigationBarMode.compact,
                    center: new Microsoft.Maps.Location(38.2231, -85.666604),
                    mapTypeId: Microsoft.Maps.MapTypeId.road,
                    zoom: 10
                });
            
                Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
                    var pins = [];

                    for(var i = 0;i < mapData.length;i++){
                        var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));

                        //Store the original data object in the pushpins metadata so that you can access other properties like Name.
                        pin.metadata = mapData[i];

                        pins.push(pin);
                    }

                    //Create a ClusterLayer with options and add it to the map.
                    clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
                        clusteredPinCallback: customizeClusteredPin
                    });
                    map.layers.insert(clusterLayer);
                });
            }

    function customizeClusteredPin(cluster) {
       //Add click event to clustered pushpin
       Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
    }

    function clusterClicked(e) {
       if (e.target.containedPushpins) {
           var locs = [];
           for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
               //Get the location of each pushpin.
               locs.push(e.target.containedPushpins[i].getLocation());
           }

           //Create a bounding box for the pushpins.
           var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);

           //Zoom into the bounding box of the cluster. 
           //Add a padding to compensate for the pixel area of the pushpins.
           map.setView({ bounds: bounds, padding: 100 });
       }
    }
    //Add an infobox to the map.
    infobox = new Microsoft.Maps.Infobox(map.setMap(map), { visible: false });

    //Display an infobox for the pushpin.
    infobox.setOptions({
       title: pin.getTitle(),
       description: description.join(''),
       visible: true
    });
    function pushpinClicked(e) {
           //Show an infobox when a pushpin is clicked.
      showInfobox(e.target);
    }
    function createPushpinList() {
       //Create a list of displayed pushpins each time clustering layer updates.
       if (clusterLayer != null) {
           infobox.setOptions({ visible: false });
                //Get all pushpins that are currently displayed.
           var data = clusterLayer.getDisplayedPushpins();
           var output = [];
                //Create a list of links for each pushpin that opens up the infobox for it.
           for (var i = 0; i < data.length; i++) {
               output.push("<a href='javascript:void(0);' onclick='showInfoboxByGridKey(", data[i].gridKey, ");'>");
               output.push(data[i].getTitle(), "</a><br/>");
           }
           document.getElementById('listOfPins').innerHTML = output.join('');
       }
            }

    function showInfoboxByGridKey(gridKey) {
            //Look up the cluster or pushpin by gridKey.
            var clusterPin = clusterLayer.getClusterPushpinByGridKey(gridKey);
            //Show an infobox for the cluster or pushpin.
       showInfobox(clusterPin);
    }
    function showInfobox(pin) {
       var description = [];
            //Check to see if the pushpin is a cluster.
       if (pin.containedPushpins) {
           //Create a list of all pushpins that are in the cluster.
           description.push('<div style="max-height:75px;overflow-y:auto;"><ul>');
           for (var i = 0; i < pin.containedPushpins.length; i++) {
               description.push('<li>', pin.containedPushpins[i].getTitle(), '</li>');
           }
           description.push('</ul></div>');
       }
            
    }
        </script>


    AnneY

    Friday, July 7, 2017 2:19 PM
  • I've modified your code to simplify it. The following code show an infobox when you click on a single pushpin and zooms the map in when you click on clusters:

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    	<meta charset="utf-8" />
    	<script type="text/javascript">
    		var mapData = [{ "Title": "Place1", "Description":"Person1", "Latitude": 38.2231, "Longitude": -85.666604 },
                           { "Title": "Place2", "Description":"Person2", "Latitude": 38.22345, "Longitude": -85.66625 },
                           { "Title": "Place3", "Description":"Person3", "Latitude": 38.244, "Longitude": -85.726 },
                           { "Title": "Place4", "Description":"Person4", "Latitude": 38.26, "Longitude": -85.747 },
                           { "Title": "Place5", "Description":"Person5", "Latitude": 38.2179, "Longitude": -85.7612 }];
    
    		var map, infobox, clusterLayer;
    
    		function GetMap() {
    			map = new Microsoft.Maps.Map('#myMap',{
    				credentials: 'Your Bing Maps Key',
    				zoom: 3
    			});
    			
    			//Add an infobox to the map.
    			infobox = new Microsoft.Maps.Infobox(map.getCenter(), { visible: false });
    			infobox.setMap(map);
    
    			Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
    				var pins = [];
    
    				for(var i = 0;i < mapData.length;i++){
    					var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));
    
    					//Store the original data object in the pushpins metadata so that you can access other properties like Name.
    					pin.metadata = mapData[i];
    
    					pins.push(pin);
    				}
    
    				//Create a ClusterLayer with options and add it to the map.
    				clusterLayer = new Microsoft.Maps.ClusterLayer(pins);
    				
    				//Add a click event to the cluster layer to open an infobox.
    				Microsoft.Maps.Events.addHandler(clusterLayer, 'click', showInfobox);
    				
    				map.layers.insert(clusterLayer);
    			});
    		}
    
    		function customizeClusteredPin(cluster) {
    			//Add click event to clustered pushpin
    			Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
    		}
    			
    		function showInfobox(e) {
    			var pin = e.target;
    			
    			//Check to see if the pushpin is a cluster.
       			if (pin.containedPushpins) {
    				//Cluster clicked, zoom the map in.
    				var locs = [];
    				for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
    					//Get the location of each pushpin.
    					locs.push(e.target.containedPushpins[i].getLocation());
    				}
    
    				//Create a bounding box for the pushpins.
    				var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);
    
    				//Zoom into the bounding box of the cluster. 
    				//Add a padding to compensate for the pixel area of the pushpins.
    				map.setView({ bounds: bounds, padding: 100 });
    			} else {
    				//Pushpin clicked, show infobox.
    				infobox.setOptions({ 
    					location: pin.getLocation(), 
    					title: pin.metadata.Title,
    					description: pin.metadata.Description,
    					visible: true
    				});	 
    			}		  
    		}
    	</script>
    	<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
    	<div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    Friday, July 7, 2017 4:37 PM
  • Thank you so much. Emphasis on Thank, You, So and Much!

    AnneY

    Saturday, July 8, 2017 12:31 PM
  • Mr Brunditt, no matter what I can't style the infobox. If you can help me again, thanks. (It disappears, or just looks normal.)

    AnneY

    Monday, July 10, 2017 8:58 PM
  • To style the infobox you have to create an HTML string and set it as the htmlContent of the infobox. Here is an example: https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk#addCustomInfobox+JS

    [Blog] [twitter] [LinkedIn]

    Monday, July 10, 2017 11:58 PM
  • Yes, I had done that, but at what stage is that applied to the individual inboxes? I can affect the style just through css (#myMap .MicrosoftMap .Infobox .infobox-body {} etc), except for the close-button--and if I style it in css, no close button shows up. Where is the infobox given its functions? I also tried adding functions to it before asking for your help. In the single or random example, it seems not to need special help. ?

    ==

           

    var map, infobox, clusterLayer;

    //Define an HTML template for a custom infobox.
    var infoboxTemplate = '<div id="infoboxText" style="background-color:White; border-style:solid; border-width:medium; border-color:DarkOrange; min-height:100px; width: 140px; "><b id="infoboxTitle" style="; top: 10px; left: 10px; width: 220px; ">{title}</b><a id="infoboxDescription" style="; top: 30px; left: 10px; width: 140px; ">{description}</a></div>';

    function loadMapScenario() {
                var navigationBarMode = Microsoft.Maps.NavigationBarMode;
                map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
                    credentials: '',
                    navigationBarMode: navigationBarMode.compact,
                    center: new Microsoft.Maps.Location(38.2231, -85.666604),
                    mapTypeId: Microsoft.Maps.MapTypeId.road,
                    zoom: 10
                });
                var center = map.getCenter();
                //Add an infobox to the map.
                infobox = new Microsoft.Maps.Infobox(map.getCenter(), { visible: false });
                //infobox = new Microsoft.Maps.Infobox(center, {
                //    htmlContent: infoboxTemplate.replace('{title}', '').replace('{description}', ''), visible:false
                //});

                infobox.setMap(map);

                Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
                    var pins = [];

                    for (var i = 0; i < mapData.length; i++) {
                        var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude), { color: 'orange' });

                        //Store the original data object in the pushpins metadata so that you can access other properties like Name.
                        pin.metadata = mapData[i];

                        pins.push(pin);
                    }

                    //Create a ClusterLayer with options and add it to the map.
                    clusterLayer = new Microsoft.Maps.ClusterLayer(pins);

                    //Add a click event to the cluster layer to open an infobox.
                    Microsoft.Maps.Events.addHandler(clusterLayer, 'click', showInfobox);

                    map.layers.insert(clusterLayer);
                });
            }

            function customizeClusteredPin(cluster) {
                //Add click event to clustered pushpin
                Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
            }

            function showInfobox(e) {
                var pin = e.target;

                //Check to see if the pushpin is a cluster.
                if (pin.containedPushpins) {
                    //Cluster clicked, zoom the map in.
                    var locs = [];
                    for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
                        //Get the location of each pushpin.
                        locs.push(e.target.containedPushpins[i].getLocation());
                    }

                    //Create a bounding box for the pushpins.
                    var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);

                    //Zoom into the bounding box of the cluster. 
                    //Add a padding to compensate for the pixel area of the pushpins.
                    map.setView({ bounds: bounds, padding: 100 });
                } else {
                    //Pushpin clicked, show infobox.
                    infobox.setOptions({
                        location: pin.getLocation(),
                        title: pin.metadata.Title,
                        description: pin.metadata.Description,
                        showCloseButton: true,
                        visible: true
                    });
                }
            }
            </script>


    AnneY

    Tuesday, July 11, 2017 11:49 AM
  • You need to use that custom HTML infobox template every time you set the content of the infobox. Don't use title/description of the infobox if you are going to use htmlContent. For example:

    infobox.setOptions({
        location: pin.getLocation(),
        htmlContent: infoboxTemplate.replace('{title}', pin.metadata.Title).replace('{description}', pin.metadata.Description),
        showCloseButton: true,
        visible: true
    });


    [Blog] [twitter] [LinkedIn]

    Tuesday, July 11, 2017 5:47 PM
  • Thank you very much! If you could provide the correct reference for how to have each pin show a number, it would be great. In v7 I had a separate variable for each pin-- var pushpinOptions = { text: '1', visible: true, textOffset: offset }; 

    Now everything is different. I have looked for a text property for pins--

    thanks very much.


    AnneY

    Tuesday, July 11, 2017 7:41 PM
  • Since I have spent so long, I will be a pest again-- 

    It is possible to add the closebox in the template---

    var infoboxTemplate = '<div id="infoboxText" style="background-color:White; border-style:solid; border-width:medium; border-color:DarkOrange; min-height:60px; width: 200px; "><div class="pull-right"><a href="javascript:void(0)" id="ibox-close" class="infobox-close" onclick="closeInfoBox()">x</a></div><b id="infoboxTitle" style="; top: 10px; left: 10px; width: 190px; ">{title}</b><a id="infoboxDescription" style="; top: 30px; left: 10px; width: 200px; ">{description}</a></div>';

    However, the click function does not work.

    There is also your code below (but again, I am not sure where it goes-- or if there is a portion that is in the infobox.setOptions code--??

    infobox = new Microsoft.Maps.Infobox(center, { htmlContent: '<div id="infoboxText" style="background: #FFFFFF; color: #000000; padding: 5px;"><div class="pull-right"><a id="ibox-close" class="infobox-close" onclick="closeInfoBox()">x</a></div><p><strong>{{ coords["site"] }}</strong></p><p>{{ coords["address"] }}<br/>{{ coords["city"] }}, {{ coords["st"] }}</p></div>', visible: false }); infobox.setMap(map); Microsoft.Maps.Events.addHandler(pushpin, "click", function () { infobox.setOptions({ visible: true }); }); map.entities.push(pushpin);


    AnneY

    Tuesday, July 11, 2017 8:06 PM
  • The pushpin text property option is part of the API. Most of the V7 pushpin options are supported in V8. 

    [Blog] [twitter] [LinkedIn]

    Wednesday, July 12, 2017 1:01 AM
  • Yes, you have to create function that has your logic to close the infobox. Something as simple as:

    function closeInfoBox(){
        infobox.setOptions({ visible: false });
    }


    [Blog] [twitter] [LinkedIn]

    Wednesday, July 12, 2017 1:03 AM
  • Thank you for all your help.

    AnneY

    Wednesday, July 12, 2017 11:19 AM
  • A follow up-- I found through experimenting that it is possible to style the infobox AND RETAIN THE CLOSE button, by adding to a style element that is on the page with the map. (Probably could put on site stylesheet too) USE ONLY:

    #myMap .MicrosoftMap .Infobox {
                ;
                border-style: solid;
                border-width: medium;
                border-color: orange;
                border-radius: 3px;
                left: 0;
                top: 0;
                background-color: #fff;
                z-index: 0;
            }

    But if you use:

    #myMap .MicrosoftMap .Infobox .infobox-body { etc }

    then the close box does not show up. It works fine with the first css rule.

    Also, by using the below, you can style the title:

    #myMap .MicrosoftMap .Infobox .infobox-body .infobox-title {
    color:#4286f4;
    }

    Also, if you click on the infobox close button in the area too near to the NavigationBar, the click function will not work. It is below that div.

    thanks again.

    "Share all good things with your teacher"


    AnneY

    Wednesday, July 12, 2017 11:06 PM
  • Ricky

    I have worked with your code below and tried some mods but I cannot get the map to zoom in to the center of the full extent of the original data set on initial load.  What am I doing wrong?

    Thanks so much.

    Bill

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script type="text/javascript">
            var mapData = [{ "Title": "Place1", "Description":"Person1", "Latitude": 41.2231, "Longitude": -75.666604 },
                           { "Title": "Place2", "Description":"Person2", "Latitude": 41.22345, "Longitude": -75.66625 },
                           { "Title": "Place3", "Description":"Person3", "Latitude": 41.244, "Longitude": -75.726 },
                           { "Title": "Place4", "Description":"Person4", "Latitude": 41.26, "Longitude": -75.747 },
                           { "Title": "Place5", "Description":"Person5", "Latitude": 41.2179, "Longitude": -75.7612 }];

            var map, infobox, clusterLayer;

            function GetMap() {
                map = new Microsoft.Maps.Map('#myMap',{
                    credentials: 'AjQ80lWVznEPLE4g1ZSoTWxYeDJGcdkA6lpkNCFxveEleQ97TkL5jyUp82mJmZCX',
                    mapTypeId: Microsoft.Maps.MapTypeId.aerial,
                    //mapTypeId: Microsoft.Maps.MapTypeId.birdseye,
                    //mapTypeId: Microsoft.Maps.MapTypeId.road,
                    //mapTypeId: Microsoft.Maps.MapTypeId.streetside,
                    zoom: 5
                });
                
                //Add an infobox to the map.
                infobox = new Microsoft.Maps.Infobox(map.getCenter(), { visible: false });
                infobox.setMap(map);

                Microsoft.Maps.loadModule("Microsoft.Maps.Clustering", function () {
                    var pins = [];

                    for(var i = 0;i < mapData.length;i++){
                        var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(mapData[i].Latitude, mapData[i].Longitude));

                        //Store the original data object in the pushpins metadata so that you can access other properties like Name.
                        pin.metadata = mapData[i];

                        pins.push(pin);
                    }

                    //Create a ClusterLayer with options and add it to the map.
                    clusterLayer = new Microsoft.Maps.ClusterLayer(pins);
                    
                    //Add a click event to the cluster layer to open an infobox.
                    Microsoft.Maps.Events.addHandler(clusterLayer, 'click', showInfobox);
                    
                    map.layers.insert(clusterLayer);
                });
            }
            //---------------
            //Create a bounding box for the pushpins.
                    var bounds = Microsoft.Maps.LocationRect.fromLocations(pins);

                    //Zoom into the bounding box of the cluster.
                    //Add a padding to compensate for the pixel area of the pushpins.
                    map.setView({ bounds: bounds, padding: 100 });
            //---------------

            function customizeClusteredPin(cluster) {
                //Add click event to clustered pushpin
                Microsoft.Maps.Events.addHandler(cluster, 'click', clusterClicked);
            }
                
            function showInfobox(e) {
                var pin = e.target;
                
                //Check to see if the pushpin is a cluster.
                   if (pin.containedPushpins) {
                    //Cluster clicked, zoom the map in.
                    var locs = [];
                    for (var i = 0, len = e.target.containedPushpins.length; i < len; i++) {
                        //Get the location of each pushpin.
                        locs.push(e.target.containedPushpins[i].getLocation());
                    }

                    //Create a bounding box for the pushpins.
                    var bounds = Microsoft.Maps.LocationRect.fromLocations(locs);

                    //Zoom into the bounding box of the cluster.
                    //Add a padding to compensate for the pixel area of the pushpins.
                    map.setView({ bounds: bounds, padding: 100 });
                } else {
                    //Pushpin clicked, show infobox.
                    infobox.setOptions({
                        location: pin.getLocation(),
                        title: pin.metadata.Title,
                        description: pin.metadata.Description,
                        visible: true
                    });    
                }          
            }
        </script>
        <script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div>
    </body>
    </html>

     

    Sunday, January 14, 2018 7:26 PM
  • This is likely due to zoom levels being integers. Rarely will the map ever zoom tightly around your data. The aspect ratio of the map versus your data positions need to be the same for this to happen which doesn't occur that often. You can also try using a smaller padding value. The padding helps to ensure your pushpin icons are visible when using a bounding box based on pushpin locations. Try a value of 40 or 50 and see if that works better for you.

    [Blog] [twitter] [LinkedIn]

    Tuesday, January 16, 2018 6:29 PM