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
Boundaries:
Concept: Moveable Push Pins, Part 5 - Custom Push Pins

Now that we have a seemingly feature rich map with moveable push pins, it only seems appropriate that a little time is spent on aesthetics. In this example, custom icons will be implemented to give then end user more of a visual cue that the push pin is being moved.

New custom push pins have been added to the map that gives the map a little more depth. When a user moves a given push pin (by right-clicking on it), the icon changes to give an indication that it is being moved. Additionally, the mouse cursor is also changed so that the push pin can be more accurately placed.

Disclaimer: Just for the record, I am not, by any means, a graphic designer. I had to beg, borrow and steal borrow to come up with a new look for the push pins. If someone has the ability and time to work on better versions of these push pins, please send the fruits of your labor my way and I will add them to the site, giving you full credit, of course.


Walk Through:

Before we get into the code, I wanted to spend some time discussing the VECustomIconSpecification class. The VECustomIconSpecification call is an effective way to control the attributes of a custom icon to determine how it will be displayed on the map. Unfortunately, it could not be used.

While I was able to implement the functionality I was looking for with the VECustomIconSpecification class, it did not seem to work with Firefox. In setting the ImageOffset property on the VECustomIconSpecification class (with a VEPixel object). Firefox does not seem to recognize the value of the “top” style attribute that is being set. IE does not seem to have a problem. I can only presume that this has to do with some sort of style incompatibility. If anyone has more information, please let me know.

Since it was important to have a working example in at least IE and Firefox (sorry all other browsers, but I can only test so much), I took an alternative approach. Instead of implementing the VECustomIconSpecification class, I used HTML with style attributes to produce the same effect.

Before I figured out how I wanted to position my push pins, I spent some time looking at how VE positions push pin icons by default. It seems that the size of the icon is irrelevant to how the push pin icon is placed. I created several different size icons that displayed a grid pattern so that positioning could be determined. Regardless of the size of the grid, the push pin icon was always positioned about 10 pixels in from the top and 10 pixels down from the top. If someone has more information on this, please send it my way.

I wanted to determine the default positioning so I knew how the custom push pin icons needed to be placed. In providing a mechanism to move push pins, it was important to me to have the push pin point as close as possible to the actual point.

Changing the icons on a push pin is not a complicated process in and of itself. For a given push pin (VEShape object), the SetCustomIcon method can be passed the appropriate information to set the icon. This information can be a URL that points to the icon information (image) or custom HTML that defines the look of the icon. As mentioned the latter approach, HTML was taken.

As you’ve undoubtedly figured, this example builds off of the previous. That being the case, I will touch on the parts that have changed and not take you through all of the code. These changes are as follows:

First, two new global variables are defined. These variables are pinIconHTML and moveIconHTML. The implementation is as follows:
    var pinIconHTML = '<div style=\'position:relative;top:-20px;\'><img src=\'images/PushPin.png\'></div>'
    var moveIconHTML = '<div style=\'position:relative;top:-30px;\'><img src=\'images/movePushPin.png\'></div>'
    
As you can see, these variables contain the HTML needed to define the look of the icon. In both cases the HTML for the corresponding image is defined and the image is wrapped in a DIV tag. Style attributes are applied to the DIV to control the positioning. Yes, this style information could be contained in a style sheet, but it was included in the HTML for illustration purposed. The “top” attribute is being set to handle the “offset” from the actual anchor point that the push pin icon would normally be placed.

Now that the look of the push pins has been defined, it needs to be implemented in the appropriated places. pinIconHTML represents the look of the normal push pin and moveIconHTML represents the look of a push pin being moved.

When the push pins are initially created in the “load()” function, the pinIconHTML is applied to each push pin. This is implemented as follows:
    ...
    marker.SetCustomIcon(pinIconHTML);
    ...
    
The pinIconHTML is passed to the SetCustomIcon() method on VEShape object, marker. This is done for each of the push pins.

Next the mouseDownHandler function is updated to change the look of the push pin being moved. As you recall, this function initially determines if the push pin is being moved and acts accordingly. The following code was added:
    ...
    currentShape.SetCustomIcon(moveIconHTML);
    currentShape.SetPoints(map.PixelToLatLong(new VEPixel(e.mapX, e.mapY)));
    ...
    
Once it has been determined that a push pin is being moved, the icon of that push pin is changed to the “moving” version. The moveIconHTML variable is passed to the SetCustomIcon() method on the VEShape Object, currentShape. Additionally, the location of the push pin is updated to the current location of the cursor to “smooth” out the transition. This is accomplished by passing the latitude and longitude of the current location of the cursor to the SetPoints() method on the VEShape object, currentShape.

The last set of changes takes place in the mouseUpHandler function. No changes were need needed for the moving process itself as functionally speaking, it still works the same. Since the mouseUpHandler is responsible for undoing what the mouseDownHandler function does, it has to reset the push pin icon to the original state. The is accomplished as follows:
    ...
    currentShape.SetCustomIcon(pinIconHTML);
    ...
    
As with the creation of the push pins, the pinIconHTML variable is used. Here it is passed to the SetCustomIcon() method on the VEShape object, currentShape. This resets the push pin icon to the original state.

Wrap-up:

The previous has been an overview of how you can implement custom icons to enhance the visual functionality of a map. I some cases the default push pins will more than suffice, but in others, custom icons may be implemented to enhance the map.

In this example, custom icons were used to more accurately present where the push pins were pointing to and to add some flair to the look while moving the push pins.

This will more than likely be the last part of this series, unless there are other topics/enhancements that people would like to have examined. If you have any suggestions or comments, please feel free to contact me.

Any feedback, comments or questions are welcome.

Return to Home Page

©2007-2017, Mike Garza, All Rights Reserved