At one of the local golf courses I frequent, there is an open grass field next to the course. It is about eight acres in size and mowed regularly. It is permissible to hit golf balls there—you bring and shag our own balls. My golf colleagues and I spend hours there practicing, chatting and in general just wasting time.
One of the guys brings Ginger, the amazing, incredible, wonder dog.
Ginger is a Hungarian Vizlas (or Hungarian pointer). She chases squirrels, begs for snacks and supervises us closely to make sure we don't misbehave.
Anyway, I decided to make a dedicated web page to measure distances on the field in yards using online mapping services. I started with Google maps and then did the same application with Bing maps. It is a good way to become familiar with the APIs.
Here are images of the final two maps:
Google:
Bing:
To start with online mapping services, you need to visit the respective websites and get a developers key.
I pared the code down to the minimum to make it easier to compare the APIs. Google maps required this CSS (or it wouldn't work):
html
{
height: 100%;
}
body
{
height: 100%;
margin: 0;
padding: 0;
}
Here is how the map scripts are included. Google requires the developer Key when loading the JavaScript, Bing requires it when the map object is created:
Google:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=XXXXXXX&libraries=geometry&sensor=false" > </script>
Bing:
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"> </script>
Note: I use jQuery to manipulate the DOM elements which may be overkill, but I may add more stuff to this application and I didn't want to have to add it later. Plus, I really like jQuery.
Here is how the maps are created:
Common Code (the same for both Google and Bing Maps):
<script type="text/javascript">
var gTheMap;
var gMarker1;
var gMarker2;
$(document).ready(DocLoaded);
function DocLoaded()
{
var StartLat = 44.924254;
var StartLng = -93.366859;
var mapdiv = $("#map_div")[0];
Google:
var StartPoint = new google.maps.LatLng(StartLat, StartLng);
gTheMap = new google.maps.Map(mapdiv,
{
center: StartPoint,
zoom: 18,
mapTypeId: google.maps.MapTypeId.SATELLITE
});
marker1 = PlaceMarker(new google.maps.LatLng(StartLat, StartLng + .0001));
marker2 = PlaceMarker(new google.maps.LatLng(StartLat, StartLng - .0001));
DragEnd(null);
}
Bing:
var StartPoint = new Microsoft.Maps.Location(StartLat, StartLng);
gTheMap = new Microsoft.Maps.Map(mapdiv,
{
credentials: 'xxxxxxxxxxxxxxxxxxxxxxxx',
center: StartPoint,
zoom: 18,
mapTypeId: Microsoft.Maps.MapTypeId.aerial
});
marker1 = PlaceMarker(new Microsoft.Maps.Location(StartLat, StartLng + .0001));
marker2 = PlaceMarker(new Microsoft.Maps.Location(StartLat, StartLng - .0001));
DragEnd(null);
}
Note: In the Bing documentation, mapTypeId: was missing from the list of options even though the sample code included it.
Note: When creating the Bing map, use the developer Key for the credentials property.
I immediately place two markers/pins on the map which is simpler that creating them on the fly with mouse clicks (as I first tried). The markers/pins are draggable and I capture the DragEnd event to calculate and display the distance in yards and draw a line when the user finishes dragging.
Here is the code to place a marker:
Google:
function PlaceMarker(location)
{
var marker = new google.maps.Marker(
{
position: location,
map: gTheMap,
draggable: true
});
marker.addListener('dragend', DragEnd);
return marker;
}
Bing:
function PlaceMarker(location)
{
var marker = new Microsoft.Maps.Pushpin(location,
{
draggable : true
});
Microsoft.Maps.Events.addHandler(marker, 'dragend', DragEnd);
gTheMap.entities.push(marker);
return marker;
}
Here is the code than runs when the user stops dragging a marker:
Google:
var gLine = null;
function DragEnd(Event)
{
var meters = google.maps.geometry.spherical.computeDistanceBetween(marker1.position, marker2.position);
var yards = meters * 1.0936133;
$("#message").text(yards.toFixed(1) + ' yards');
var Endpoints = [marker1.position, marker2.position];
if (gLine == null)
{
gLine = new google.maps.Polyline(
{ path: Endpoints,
strokeColor: "#FFFF00",
strokeOpacity: 1.0,
strokeWeight: 2,
map: gTheMap
});
}
else
gLine.setPath(Endpoints);
}
Bing:
var gLine = null;
function DragEnd(Args)
{
var Distance = CalculateDistance(marker1._location, marker2._location);
$("#message").text(Distance.toFixed(1) + ' yards');
var Endpoints = [marker1._location, marker2._location];
if (gLine == null)
{
gLine = new Microsoft.Maps.Polyline(Endpoints,
{
strokeColor: new Microsoft.Maps.Color(0xFF, 0xFF, 0xFF, 0),
strokeThickness : 2
});
gTheMap.entities.push(gLine);
}
else
gLine.setLocations(Endpoints);
}
}
Note: I couldn't find a function to calculate the distance between points in the Bing API, so I wrote my own (CalculateDistance). If you want to see the source for it, you can pick it off the web page.
Note: I was able to verify the accuracy of the measurements by using the golf hole next to the field. I put a pin/marker on the center of the green, and then by zooming in, I was able to see the 150 markers on the fairway and put the other pin/marker on one of them.
Final Notes:
All in all, the APIs are very similar. Both made it easy to accomplish a lot with a minimum amount of code.
In one aerial view, there are leaves on the tree, in the other, the trees are bare. I don't know which service has the newer data.
Here are links to working pages:
Bing Map Demo
Google Map Demo
I hope someone finds this useful.
Steve Wellens
CodeProject