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

   
Concept: Updated Polygon Drag Handles - Bing Maps 7

The previous article, Polygon Drag Handles with Bing Maps 7, took an example that was built in Bing Maps v6.x and ported it over to work with Bing Maps v7.0. The goal in providing this example, as with some of the other examples that were ported, was to show how existing code against the v6.x framework could be moved to v7.0.

Shortly after posting the latest ported example, I starting thinking that while the example is now functional against the v7.0 framework, it may not necessarily be the most efficient way to implement that type of functionality within the v7.0 framework.

As you know, version 7 of the Bing Maps AJAX control has a new and improved approach toward implementing mapping for your web applications. That said, it only made sense to try and take advantage of the new features of the framework.

So...I tore apart the previous example and reworked it to take advantage of some of the new features of the Bing Maps AJAX Control v7.0. Here is that example...


Walk Through:

Conceptually and functionally this example is the same as the previous versions, in that you have the ability to turn on drag handles to edit the polyline on the map. Where this example differs is that instead of using map oriented events, the events are all relative to the push pins or the drag handles.

I am not going to touch on all the code involved in initializing the map. This was covered in the previous examples, so you can refer to that for more information. Again, the main difference with the approach is that the events that control the editing of the polyline are wired to the push pins that are the drag handles (instead of using map events).

When the drag handles are created, three events are wired to each drag handle. The implementation for this example is as follows:

    //Add drag handles
    for (i = 0; i <= (points.length - 1); i++) {
        var dragHandle = new Microsoft.Maps.Pushpin(points[i], { draggable: true, icon: 'images/DragHandle2.gif', height: 10, width: 10, anchor: new Microsoft.Maps.Point(5, 5) });
        Microsoft.Maps.Events.addHandler(dragHandle, 'dragstart', StartDragHandler);
        Microsoft.Maps.Events.addHandler(dragHandle, 'drag', DragHandler);
        Microsoft.Maps.Events.addHandler(dragHandle, 'dragend', EndDragHandler);
        DragHandleLayer.push(dragHandle);
    }
    

In this section of code, the drag handles are added to the map using the points that were created for the polyline. On lines 4-6, the events are wired up for the drag handle. The events are “dragstart”, “drag” and “dragend”. The dragstart event is fired when you click on the drag handle. The drag event is fired when fired when you are moving the drag handle. The dragend event is fired when you release drag handle. Comparing this to the implementation in the previous examples, you can think of this as being similar (but not exact) to a mousedown, mousemove and mouseup event specific for the push pin.

The other change in the drag handle implementation is on line 3 where the drag handle is created. The “draggable” option has been added and has been set to true. This enables the dragging feature for the push pins or drag handles.

Now that the events have been wired up, we need to implement the functions that support them. Since the events are relative to each push pin, there is less complexity in the overall logic. We no longer have to test for the “mode” of the map as we did in the previous example and when clicking, we no longer have to test to see if a push pin or drag handle was actually clicked.

The process begins when a drag handle is clicked, which fires the dragstart event and executes the “startDragHandler”. The implementation of that function is as follows:

    //Start Dragging
    function StartDragHandler(e) {
        var handleLocation = e.entity.getLocation();

        //Determine point index
        for (i = 0; i <= (points.length - 1); i++) {
            if (handleLocation == points[i]) {
                pointIndex = i;
                break;
            }
        }

    }
    
Effectively we are performing logic as the mouseDownHandler function of the previous example; it is just simpler since we are working directly with the drag handle. The MouseEventsArgs is passed to this function and assigned to the variable “e”. In the “e” object, there is a property named “entity” which is the object that raised the event. We retrieve the location object of drag handle by calling the getLocation method of the entity object/property of the MouseEventsArgs object ,e and assign it to the variable “handleLocation”.

Then, just as with the previous version of the example, we loop through the “points” array, which contains the Location objects that define the polyline and find the point that corresponds to the location of the drag handle (lines 5 – 10). One the point is identified, the index of that point is assigned to the variable “pointIndex”, which is used later in the process.

Now that we’ve captured the corresponding point of the polyline, we can start updating the polyline as the drag handle is moved. When the drag handle is moved, the “drag” event is fired and the “DragHandler” function is executed. The implementation of that function is as follows:

    //Dragging
    function DragHandler(e) {
        var loc = e.entity.getLocation();
        points[pointIndex] = loc;
        polylineMask.setLocations(points);
    }
    

Again, we have the MouseEventsArgs object being passed to the function and assigned to the variable “e”. We capture the current Location object of the drag handle by calling the getLocation method of the entity property (which is the push pin/drag handle object) of the MouseEventsArgs object, e and assign it to the variable “loc”.

Next the corresponding point of the polyline is updated. As mentioned previous, the “point” array contains the location objects that are the points of the polyline. In the StartDragHandler function we captured the index (pointsIndex) of the point that corresponded to the drag handle. Now that the new location of the drag handle has been captured, it is used to replace the corresponding location object in the points array (line 4). Lastly, the polyline object, polylineMask, is then updated by passing the “points” array to the setLocations method in the polylineMask object.

This process executes each time the mouse is moved. Once the mouse button is released the last part of the process is executed, which is the EndDragHandler. The implementation is as follows:

    //End Dragging
    function EndDragHandler(e) {
        polyline.setLocations(points);
    }
    
This function is relatively simple. Since the end user has released the mouse button, it signals the end of the dragging. The only thing left to do is to update the original polyline with the new points that have been established. This is accomplished by passing the “points” array to the setLocation method of the polyline object.

As with the previous version of the example, there is a button that toggles the edit mode of the map. The implementation is the same and you can refer to the previous example for more information.

Wrap-up:

In this example we took an existing example (ported from 6.x to 7.0) and updated the application logic to take advantage of the newer features of v7 of the Bing Maps AJAX control. In doing so, the application logic becomes simpler, cleaner and easier to implement. The one thing that I hope you take away from this is that as you move from v6.x to v7.x, you should evaluate your code to determine if there is a more effective way to implement the same logic using the new conventions that v7 offers. Based on the previous examples, we’ve seen that you can port code over to v7 following similar patterns, but it does make sense to see if the newer framework can optimize and improve on the previous approaches that you may have taken.

This is just one approach that can be taken to implement this type of functionality and is intended to illustrate the mechanics behind this concept. Your implementation will vary depending on your specific needs. As always, feedback, comments or questions are welcome. I look forward to hearing from you.

Return to Home Page

©2007-2017, Mike Garza, All Rights Reserved