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

   
Mouse Location: PushPin Location:
Lat: 00.0000 Lng: 00.0000 Lat: 00.0000 Lng: 00.0000
Concept: Moveable Push Pins, Part 2

This example builds off of the Moveable Push Pin example and the concept is essentially the same. The user can take an existing pushpin and move it to a new location on the map.

Where the previous example contained a single push pin, this example contains multiple push pins. Each of the push pins on the map can be moved independently of each other. Aside from that, the map to the right works the same as with the previous example. Clicking on the map allows the user to drag the map around and moving the mouse over the push pins activates the info window. Functionality has been added so that if the user “right clicks” on any of the push pins, they can drag that push pin to a new location on the map.

Labels have been added to the top section of the map to indicate the current mouse location as well as the location of the push pin. These labels are updated as the map in interacted with.

Walk Through:

As mentioned, this example builds off of the Moveable Push Pin example. The core logic for this example is essentially the same. The same events (onmousemove, onmousedown and onmouseup) have event handlers registered and those functions provide the same conceptual functionality. Additional logic was added to these functions to now support multiple pushpins. This logic is as follows.

Push Pin(s) – During the load process, three push pins are added to the map. The implementation for each of these push pins is exactly the same. Yes, a function could have been implanted to handle the push pin creation, but for simplicity purposed the code is repeated three times.

Additionally, a global variable named “currentMarker” is added. This variable will hold an instance of a VEShape object that will refer to the push pin being dragged. This variable will be assigned the appropriate VEShape object during the “onmousedown” event.
    <script language="javascript" type="text/javascript">
        ...
        var currentMarker = null;
        ...
        
        //Add Marker 1
        marker = new VEShape(VEShapeType.Pushpin, new VELatLong('41.8756', '-87.6456'));
        marker.SetTitle('Draggable Marker 1');          
        marker.SetDescription('Hold down the right mouse button to drag me. ');
        map.AddShape(marker);

        //Add Marker 2

        ...
    </script>
    
“mouseDownHandler” – This function was extended so that it will determine which push pin is being moved. When this event is raised, the Event Object, e, contains the element ID (e.elementID) that is associated with the event. If the needed conditions are met to determine that a push pin should be moved, the push pin (VEShape object) associated with this event is assigned to the global variable “currentMarker” and the process continues. The implementation is as follows:
    //onmousedown handler
    function mouseDownHandler(e) {
        if (e.rightMouseButton && e.elementID) {
            currentShape = map.GetShapeByID(e.elementID);  // <-- new code
            moving = true;
            map.vemapcontrol.EnableGeoCommunity(true);
            document.getElementById("MapDiv").style.cursor = 'Move';
        }
    }
    
The only change in this function is the addition of line three. In this line of code, the elementID property of the event object, e, is being passed to the “GetShapeByID” method in the VEMap object (map). This method will return an instance of a VEShape class, which is the push pin associated with this event. Aside from this line of code, all of the remaining logic in this function is the same as with the Moveable Push Pin example.

“mouseMoveHandler” - Only one small change was made to this function. Lines 8 and 9 were updated to work with the new global variable “currentMarker”. Otherwise, all of the logic is the same as with Moveable Push Pin example. This function will still update the labels on the map accordingly and handle the relocation of the push pin, if appropriate. Now, this logic will work with the current instance of the push pin (VEShape object) referenced in the currentMarker variable that is set in the “mouseDownHandler” function.
    //onmousemove handler
    function mouseMoveHandler(e) {
        var loc = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
        document.getElementById("MouseLat").innerHTML = loc.Latitude.toFixed(4);
        document.getElementById("MouseLng").innerHTML = loc.Longitude.toFixed(4);
        if (moving) {
            document.getElementById("MarkerLat").innerHTML = loc.Latitude.toFixed(4);
            document.getElementById("MarkerLng").innerHTML = loc.Longitude.toFixed(4);
            map.HideInfoBox(currentShape);
            currentShape.SetPoints(loc);
        }
    }
    
“mouseUpHandler” – As with the other functions, this function executes the same logic as with the Moveable Push Pin example. Since this function main purpose is to “undo” what the mouseDownHandler does and the mouseDownHandler was extended to set the value of the global variable currentMarker, this function needs to undo that. A new line of code was added to reset the value of the currentMarker variable to its original value of NULL. The implementation is as follows:
    //onmouseup handler
    function mouseUpHandler(e) {
        if (moving && e.rightMouseButton) {
            currentShape = null;                
            moving = false;
            map.vemapcontrol.EnableGeoCommunity(false);
            document.getElementById("MapDiv").style.cursor = '';
        }
    }
    
Wrap-up:

The previous has outlined how the Moveable Push Pin example can be extended to support multiple push pins. Using the Moveable Push Pin example as a building block, minimal changes were needed to extend the functionality so that specific push pins could be moved independently of each other.

As with any application development code, there are many different ways that this task could be accomplished. This example is a means of illustrating one of the ways this type of functionality could be implemented. The code used here is by no means a complete solution.

Providing end users with this type of functionality could be a means of more accurately capturing geographic locations. For example, if the means in which specific locations are geo coded are not particularly accurate, dragging the push pin to a more specific location would yield a higher level of accuracy.

Any feedback, comments or questions are welcome.

Return to Home Page

©2007-2017, Mike Garza, All Rights Reserved