Dec 19 2009

Ruler for Google Maps v3 to measure distance on map

Category: Google Maps,JavascriptGiulio Pons @ 9:30 am

I’ve made a ruler to measure distances on a Google Map V3. The file Ruler.js contains a two function: one to calculate the distance between two points on the map with their position expressed in decimal degrees, and one function that add the ruler. Ther “ruler” is composed with two markers, a poly and two labels which show the distance. The labels are placed on the map with the Labels.js class from Marc Ridley, downloaded from his blog.

Here is the link to the demo and here is the link for download it.

ruler

Here is the code for ruler.js addruler function:

function addruler() {

	ruler1 = new google.maps.Marker({
		position: map.getCenter() ,
		map: map,
		draggable: true
	});

	ruler2 = new google.maps.Marker({
		position: map.getCenter() ,
		map: map,
		draggable: true
	});

	var ruler1label = new Label({ map: map });
	var ruler2label = new Label({ map: map });
	ruler1label.bindTo('position', ruler1, 'position');
	ruler2label.bindTo('position', ruler2, 'position');

	rulerpoly = new google.maps.Polyline({
		path: [ruler1.position, ruler2.position] ,
		strokeColor: "#FFFF00",
		strokeOpacity: .7,
		strokeWeight: 8
	});
	rulerpoly.setMap(map);

	ruler1label.set('text',"0m");
	ruler2label.set('text',"0m");

	google.maps.event.addListener(ruler1, 'drag', function() {
		rulerpoly.setPath([ruler1.getPosition(), ruler2.getPosition()]);
		ruler1label.set('text',distance( ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
		ruler2label.set('text',distance( ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
	});

	google.maps.event.addListener(ruler2, 'drag', function() {
		rulerpoly.setPath([ruler1.getPosition(), ruler2.getPosition()]);
		ruler1label.set('text',distance( ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
		ruler2label.set('text',distance( ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
	});

}

And this is the function to calculate distances:

function distance(lat1,lon1,lat2,lon2) {
	var R = 6371; // km (change this constant to get miles)
	var dLat = (lat2-lat1) * Math.PI / 180;
	var dLon = (lon2-lon1) * Math.PI / 180;
	var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
		Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
		Math.sin(dLon/2) * Math.sin(dLon/2);
	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
	var d = R * c;
	if (d>1) return Math.round(d)+"km";
	else if (d<=1) return Math.round(d*1000)+"m";
	return d;
}
Share

Related posts:

  1. Decimal Degrees conversion and distance of two points on google map
  2. Clustering many markers with Google Maps v3
  3. Full Screen GControl for Google Maps
  4. Phoogle Modified Class for Google Maps
  5. Parse a float number in javascript

Tags: , , , ,

15 Responses to “Ruler for Google Maps v3 to measure distance on map”

  1. bob says:

    “var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));” can be simplified to “var c = 2 * Math.asin(Math.sqrt(a));”

  2. Kaese says:

    True – what Bob says

  3. ABM Adnan says:

    Thanks a lot man! You saved my life.

    Just one little thing, there is a very little bug in labels.js (I know you didn’t write it)
    On line 44:
    maps.google.event.removeListener(this.listeners_[i]);

    this should be:
    google.maps.event.removeListener(this.listeners_[i]);

    Regards
    Adnan

  4. anil singh says:

    thanks. will visit again

    on a learning curve.

  5. admin says:

    Right. I’ve fixed it. Thank you.

  6. piero says:

    Excellent. Good job: my congratulation.
    It would useful also to have a couple of additional features:
    1)replace the couple of labels with a single label placed in the middle of the ruler line, alway on top (I tried using zIndex with no success? any idea ?)
    2)the rule line binded to the objects you’re measuring the distance. Suppose we would like to continously track the distance changes among a couple of moving markers (i.e. vehicles).

    PG Ornolio

  7. phicarre says:

    Hello,
    If I attribute an icon to the rulers then the behaviour changes !
    How to change the standard icons ?

    Thank you.

  8. pani100 says:

    Really good and handy code.
    If i wanted to change the distance to miles would this be correct?
    function distance(lat1,lon1,lat2,lon2) {
    var R = 3959; // km (change this constant to get miles. 3959 for m, 6371 for km also change 1000 to 1760)
    var dLat = (lat2-lat1) * Math.PI / 180;
    var dLon = (lon2-lon1) * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    if (d>1) return Math.round(d)+”miles”;
    else if (d<=1) return Math.round(d*1760)+"yards";
    return d;

    Regards
    Pani

  9. Web Design Huntersville says:

    How do you remove a ruler?

  10. Francisco says:

    how do you remove a ruler,,, can you helps us

  11. Marius says:

    Very nice, i also though want to know how to remove the ruler ?

  12. Marius says:

    I changed the script a bit, and now you can remove the ruler. Simply pass a ‘true’ or ‘false’ to the addruler call

    var ruler1;
    var ruler2;
    var ruler1label;
    var ruler2label;
    var rulerpoly;

    function addruler(remove) {

    if (remove) {
    google.maps.event.clearListeners(ruler1, ‘drag’);
    ruler1.setMap(null);
    google.maps.event.clearListeners(ruler2, ‘drag’);
    ruler2.setMap(null);
    ruler1label.setMap(null);
    ruler2label.setMap(null);
    rulerpoly.setMap(null);
    }
    else {
    ruler1 = new google.maps.Marker({
    position: map.getCenter(),
    map: map,
    title: ‘Starting Point’,
    draggable: true
    });

    ruler2 = new google.maps.Marker({
    position: map.getCenter(),
    map: map,
    title: ‘End Point’,
    draggable: true
    });
    ruler1label = new Label({ map: map });
    ruler2label = new Label({ map: map });
    ruler1label.bindTo(‘position’, ruler1, ‘position’);
    ruler2label.bindTo(‘position’, ruler2, ‘position’);

    rulerpoly = new google.maps.Polyline({
    path: [ruler1.position, ruler2.position],
    strokeColor: “#FFFF00″,
    strokeOpacity: .7,
    strokeWeight: 7
    });

    rulerpoly.setMap(map);

    ruler1label.set(‘text’, distance(ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
    ruler2label.set(‘text’, distance(ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));

    google.maps.event.addListener(ruler1, ‘drag’, function() {
    rulerpoly.setPath([ruler1.getPosition(), ruler2.getPosition()]);
    ruler1label.set(‘text’, distance(ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
    ruler2label.set(‘text’, distance(ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
    });

    google.maps.event.addListener(ruler2, ‘drag’, function() {
    rulerpoly.setPath([ruler1.getPosition(), ruler2.getPosition()]);
    ruler1label.set(‘text’, distance(ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
    ruler2label.set(‘text’, distance(ruler1.getPosition().lat(), ruler1.getPosition().lng(), ruler2.getPosition().lat(), ruler2.getPosition().lng()));
    });
    }

    }

    function distance(lat1,lon1,lat2,lon2) {
    var R = 6371; // km (change this constant to get miles)
    var dLat = (lat2-lat1) * Math.PI / 180;
    var dLon = (lon2-lon1) * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    if (d>1) return Math.round(d)+”km”;
    else if (d<=1) return Math.round(d*1000)+"m";
    return d;
    }

  13. Marius says:

    Sorry, I lied. It works when i test it locally, but does not work when i put it on the live server :(

  14. Marius says:

    I am a dumb ass – It still had the old version in cache, so make sure you clear the cache so it gets the new js file, then it works :)

  15. Francisco says:

    thanks a lot

Leave a Reply