Bing Maps Concepts
(formerly Virtual Earth)
Mike Garza   
VEMaps@garzilla.net   

   
Concept: Layers via the Entity Collection - Bing Maps v7

In the Bing Maps AJAX control v6.x there is a class called VEShapeLayer. As defined in the documentation: “Shape layers are a mechanism to create and manage arbitrary groups of shapes (pushpines, polylines, and polygons)”. Shape Layers were/are a good mechanism for organizing your shapes and are one of the main components in importing a GeoRSS Feed.

With the Bing Maps AJAX control v7, the VEShapeLayer class is no longer available. Fret not; there is a replacement being the Entity Collection Class. The Entity Collection class essentially serves the same purpose as the VEShapeLayer class as it is a means to manage groups of other objects. These objects include Polygon, Polyline, Pushpin, TileLayer as well as other Entity Collections.

In the included example, a map has been created and 20 random push pins have been added. The push pins have been grouped into two layers (via the Entity Collection) and color coded accordingly. At the bottom of the map there are two buttons that will toggle the visibility of a given Entity Collection. Give it a try.

Walk Through:

To begin with, a couple of global variable are declared that contain the layers that will be used on the map. The implementation is as follows:

    var layer1 = new Microsoft.Maps.EntityCollection();
    var layer2 = new Microsoft.Maps.EntityCollection();
    

Two new instances of an Entity Collection are created and assigned to the variables “layer1” and “layer2”. These two layers will contain all of the push pin instances for this example. These variable are globally scoped as they are used in several places throughout the code.

Next, the map is created and the push pins are added to the map. The implementation is as follows:

    function load() {
        // Initialize the map
        map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
                        {
                            credentials: 'Your Map Key Here',
                            center: new Microsoft.Maps.Location(41.8756, -87.9956),
                            mapTypeId: Microsoft.Maps.MapTypeId.road,
                            zoom: 7
                        });
         
        getRandomPins(10, layer1, "images/BluePin.gif");
        getRandomPins(10, layer2, "images/GreenPin.gif");
         
        map.entities.push(layer1);
        map.entities.push(layer2);
    }
    

The “load” function is called when the page has completely loaded on the client side. The map is then created in the typical fashion (lines 3-9) and the credential, center, map type and zoom level properties are set. On lines 11 & 12, the push pins are added to the respective Entity Collection via the “getRandomPins” function. The details of this function will be discussed later in the article, but the thing to note here are the parameters that are being passed to this function.

The getRandomPins function accepts three parameters. The first is the number of push pins to generate. The second is the Entity Collection in which to add the pins. Lastly is the source image path for the icon of the push pin. This function is called twice (once for each layer) and the appropriate push pins are added to each Entity Collection.

Once the push pins have been added to the Entity Collections, the Entity Collections are then added to the map (lines 14 & 15). By default, the map class contains an Entity Collection. As noted previous, one of the objects that can be added to an Entity Collection is an Entity Collection, which is exactly what is being done here. The Entity Collections layer1 and layer2 are added to the maps default Entity Collection via the Push() method. The Push() method simply adds the included entity to the last position in the collection. In doing this, all of the push pins will now be included on the map, but will still be associated with their respective Entity Collection.

As mentioned, the push pins are added to each respective Entity Collection via the “getRandomPin” function. The implementation of that function is as follows:

    function getRandomPins(pinCount, layer, pinIcon) {
        var view = map.getBounds();
        var topLeft = view.getNorthwest();
        var bottomRight = view.getSoutheast();
        var latSpan = bottomRight.latitude - topLeft.latitude;
        var longSpan = bottomRight.longitude - topLeft.longitude;
     
        for (i = 1; i <= pinCount; i++) {
            var pinLatLong = new Microsoft.Maps.Location(topLeft.latitude + latSpan * Math.random(), topLeft.longitude + longSpan * Math.random());
            var randomPin = new Microsoft.Maps.Pushpin(pinLatLong, { text: i.toString(), icon: pinIcon });
            layer.push(randomPin);
        }
    }
    

The main purpose of the getRandomPin function is to add a specific number of randomly placed pins in a given Entity Collection. This function accepts three parameters which are pinCount, layer and pinIcon. “pinCount” is an integer that represent the number of randomly placed pins to add to the Entity Collecton, “layer” is a reference to the Entity Collection class in which the push pins will be placed and “picIcon” is the relative path to the image file that should be used for the push pin icon (the src attribute). Most of the code in this function supports deriving the location of the randomly placed pins. We are not going to touch on that in the article and you can dig into that at your leisure.

The lines of code to note are lines 10 & 11. Line 10 creates the instance of the push pin and uses the randomly generated Location object, pinLatLong, for the location of the push pin. Additionally, the value passed in via the “pinIcon” parameter is used to set “icon” property of the PushpinOptions Object, which customizes the display icon for the push pin. Once that has been completed, the randomPin object is added to the referenced Entity Collection via its Push() method. The Push method of the Entity Collection works exact the same as previously noted. This process is repeated for as many iterations as defined by the pinCount parameter value.

The end result of all of that is you now have a series of push that have been added to the map and group via Entity Collections. Because of that, you now have the option of work directly with the Entity Collections and the functionally they provide. There are a whole series of method and events that can be utilized, but the one we are going to touch on here is toggling the visibility.

There are two buttons below the map that toggle visibility. Each of the buttons will execute a corresponding JavaScript function. The implementation of these functions is as follows:

    function toggleLayer1() {
        layer1.setOptions({ visible: !layer1.getVisible() });
    }
     
    function toggleLayer2() {
        layer2.setOptions({ visible: !layer2.getVisible() });
    }
    

The logic for both of these functions are the same. When the function is executed, the setOptions method of the corresponding Entity Collection is executed. The visible property of the EntityCollectionsObject is set, which controls the visibility of Entity Collection. This property is a Boolean value and is set based on the on the current visibility of the Entity Collection. The getVisible() method of the Entity Collection is executed to determine its current visibility. The JavaScript NOT logical operator (!) is applied to the result to toggle the value (true to false or false to true). Applying this value to the visible property of the EntityCollectionObject toggles the visibility of the Entity Collection.

Wrap-up:

The previous example demonstrated how you can implement layer type functionality via the Entity Collection class. Two layers, each containing 10 randomly placed push pins, were added to the map. Once the layers were in place we then had the ability to manipulate those layers, in this case by toggling the visibility of a given layer.

As always, feedback, comments or questions are welcome. I look forward to hearing from you.

Return to Home Page

©2007-2014, Mike Garza, All Rights Reserved