Adjusting AJAX Pushpin Anchors

I haven’t written a code-based blog post in a while, so it was time. I had a question recently about anchoring pins to a specific part of the pin image, so I had to chase this beast down. In the original VEPushpin Class (now deprecated) the Bing Maps AJAX API allowed for relative specification of which part of a pin image was anchored to the lat/lon (bottomleft, topright, bottomcenter, etc). The replacement APIs (VEShape) actually give you more freedom, but take a bit of understanding to get it right. And, the default pushpins will only allow you to anchor to a lat/lon (no fun). If you want to anchor a specific part of your pushpin image to a lat/lon there are a couple ways to go about it.

First, here’s how you would load a custom pushpin. I’m using a giant image, so the move is quite obvious. Notice the image is tied to the lat/lon using the image pixel 0,0 (upper, left). One small tech nugget: the default pushpin in the API is set to anchor to pixels –12.5, –12.5 so that a pushpin that’s 25 x 25 pixels would be pinned to the lat/lon in the center of the image.

AJAXAnchor_0

Adding a Custom Pushpin 

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html>
   <head>
      <title></title>
      <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

      <script type=”text/javascript” src=”http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2″></script>

      <script type=”text/javascript”>
         var map = null;
         function GetMap()
         {
            map = new VEMap(‘myMap’);
            map.LoadMap(new VELatLong(47.616601580416564,-122.19294790473617), 16, ‘r’);
         } 

    function SetPinOffset(xPixel, yPixel)
    {
        var myPin = new VEShape(VEShapeType.Pushpin, map.GetCenter());
        var myCustomPin = new VECustomIconSpecification();
        myCustomPin.Image = ‘http://www.bing.com/community/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.09.55.98.83/CPBlogPic.jpg’;
        myPin.SetCustomIcon(myCustomPin);
        map.AddShape(myPin);
    }
      </script>
   </head>
   <body onload=”GetMap();” style=’font-family:Arial’>
      <div id=’myMap’ style=’position:relative; width:400px; height:400px;’></div>
      <input id=”btnSetOffset” type=”button” value=”Set Pixel Offset” onclick=”SetPinOffset()”><br />
   </body>
</html>

Now, let’s say I want to pin the lower right corner of the image to the specified lat/lon. I can do this one of two ways – (1) using the VECustomIconSpecification.ImageOffset Property or (2) passing HTML into the VEShape.SetCustomIcon() method. Let’s look at both of these.

 

Setting Custom Icon Anchors Using VECustomIconSpecification.ImageOffset

Using the same code above, we’ll add two lines and notice, the image is now pinned using the lower right corner. The pixel offset numbers I’ve used coorespond to the size of my image of

AJAXAnchor_1

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html>
   <head>
      <title></title>
      <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

      <script type=”text/javascript” src=”http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2″></script>

      <script type=”text/javascript”>
         var map = null;
         function GetMap()
         {
            map = new VEMap(‘myMap’);
            map.LoadMap(new VELatLong(47.616601580416564,-122.19294790473617), 16, ‘r’);
         } 

    function SetPinOffset(xPixel, yPixel)
    {
        var myPin = new VEShape(VEShapeType.Pushpin, map.GetCenter());
        var myCustomPin = new VECustomIconSpecification();
        myCustomPin.Image = ‘http://www.bing.com/community/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.09.55.98.83/CPBlogPic.jpg’;
        var myPixelOffset = new VEPixel(-50, -50);
        myCustomPin.ImageOffset = myPixelOffset;
        myPin.SetCustomIcon(myCustomPin);
        map.AddShape(myPin);
    }
      </script>
   </head>
   <body onload=”GetMap();” style=’font-family:Arial’>
      <div id=’myMap’ style=’position:relative; width:400px; height:400px;’></div>
      <input id=”btnSetOffset” type=”button” value=”Set Pixel Offset” onclick=”SetPinOffset()”><br />
   </body>
</html>

Setting Custom Icon Anchors Using VEShape.SetCustomIcon()

If you’d rather use HTML to adjust how your pushpin is anchored to the map, you can do so with the SetCustomIcon() method as follows.

 

AJAXAnchor_1 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html>
   <head>
      <title></title>
      <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

      <script type=”text/javascript” src=”http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2″></script>

      <script type=”text/javascript”>
         var map = null;
         function GetMap()
         {
            map = new VEMap(‘myMap’);
            map.LoadMap(new VELatLong(47.616601580416564,-122.19294790473617), 16, ‘r’);
         } 

    function SetPinOffset(xPixel, yPixel)
    {
        var myPin = new VEShape(VEShapeType.Pushpin, map.GetCenter());
        var myCustomPin = new VECustomIconSpecification();
        myPin.SetCustomIcon(“<img src=’
http://www.bing.com/community/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.09.55.98.83/CPBlogPic.jpg’ style=’position:relative;left:-123px;top:-80px’></img>’);
        map.AddShape(myPin);
    }
      </script>
   </head>
   <body onload=”GetMap();” style=’font-family:Arial’>
      <div id=’myMap’ style=’position:relative; width:400px; height:400px;’></div>
      <input id=”btnSetOffset” type=”button” value=”Set Pixel Offset” onclick=”SetPinOffset()”><br />
   </body>
</html>

CP – Follow me on Twitter @ChrisPendleton

Join the conversation

2 comments
  1. Blackpool UK

    Thank you for the javascript information.

  2. givelord

    Very useful to know. Although, I use scarcely javascript, because javascript bugs are awesome to fix.

Comments are closed.