var map;
var routePoints=new Array(0);
var colour="#cc0000";
var total_distance=0;
var lineWidth=5;
var lineColor='#ff0000';
var lines=[];
var degreesPerRadian=180.0/Math.PI;
var radiansPerDegree=Math.PI/180.0
var earthRadiusMeters=6367460.0;
var metersPerDegree=2.0*Math.PI*earthRadiusMeters/360.0;
var MILES={
label:"miles",
f:function(distance){
return distance/1609.344;
}
}
var KMS={
label:"km",
f:function(distance){
return distance/1000;
}
}
var unit_handler=KMS;
function onLoad(){
map=new GMap(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.centerAndZoom(new GLatLng(41.9, 12.2), 11);
map.setCenter(new GLatLng(45.464886, 9.184999), 13);
GEvent.addListener(map,"click",function(overlay,point){
if(point){
routePoints.push(point);
redraw();
updateDisplay();
}
});
}
function redraw(){
map.clearOverlays();
total_distance=0;
var marker=new GMarker(routePoints[0]);
map.addOverlay(marker);
GEvent.addListener(marker,"click",function(){
routePoints.push(routePoints[0]);
var lat1=routePoints[0].lat();
var long1=routePoints[0].lng();
var lat2=routePoints[routePoints.length-1].lat();
var long2=routePoints[routePoints.length-1].lng();
total_distance+=((LatLon.distHaversine(lat1,long1,lat2,long2).toPrecision(4))*1000);
redraw();
updateDisplay();
});
for(var j=1;j<routePoints.length;++j)
{
var marker2=new GMarker(routePoints[j]);
map.addOverlay(marker2);
if(routePoints.length>1){
var lat1=routePoints[j].lat();
var long1=routePoints[j].lng();
var lat2=routePoints[j-1].lat();
var long2=routePoints[j-1].lng();
total_distance+=((LatLon.distHaversine(lat1,long1,lat2,long2).toPrecision(4))*1000);
AddPolylines(lines,GreatCirclePoints(routePoints[routePoints.length-j],routePoints[routePoints.length-1-j]),lineColor,lineWidth);
}
}}
function clearLastLeg(){
if(routePoints.length<2)
return;
routePoints.pop();
redraw();
updateDisplay();
}
function clearMap(){
total_distance=0.00;
routePoints=[];
map.clearOverlays();
updateDisplay();
}
function statert(){
alert(document.getElementById("rjour").checked);
}
function changeColourWhite(){
colour="#ffffff";
map.addOverlay(new GPolyline(routePoints,colour));
}
function changeColourBlack(){
colour="#000000";
map.addOverlay(new GPolyline(routePoints,colour));
}
function changeColourBlue(){
colour="#0000ff";
map.addOverlay(new GPolyline(routePoints,colour));
}
function changeColourGreen(){
colour="#99ff00";
map.addOverlay(new GPolyline(routePoints,colour));
}
function updateDisplay(){
var dist=unit_handler.f(total_distance);
document.getElementById("distance").value=dist.toFixed(3);
}
function toggleUnits(arg){
if(arg=="MILES")
unit_handler=MILES;
else
unit_handler=KMS;
updateDisplay();
}
function calculateDistance(points){
if(points.length<2)
return 0;
var dist=0.0;
for(var i=0;i<points.length-1;i++){
dist+=distance_between_points(points[i],points[i+1]);
}
return dist;
}
Math.deg2rad=function(x){
return x*(Math.PI/180.0);
}
var EARTH_RADIUS=6367000;
function distance_between_points(p1,p2){
var a=Math.deg2rad(90-p1.y);
var b=Math.deg2rad(90-p2.y);
var theta=Math.deg2rad(p2.x-p1.x);
var c=Math.acos(Math.cos(a)*Math.cos(b)+Math.sin(a)*Math.sin(b)*Math.cos(theta));
return c*EARTH_RADIUS;
}
function toggleReturn(){
if((document.getElementById("rjour").checked)==true)
{
total_distance*=2;
}
if((document.getElementById("rjour").checked)==false)
{
total_distance/=2;
}
updateDisplay();
}
function resizeMap(map,points){
var minLong=999;
var minLat=999;
var maxLong=-999;
var maxLat=-999;
var size=map.getSpanLatLng();
var mapWidth=size.width;
var mapHeight=size.height;
var baseWidth=mapWidth;
var baseHeight=mapHeight;
if(map.getZoomLevel()>0){
baseWidth/=Math.pow(2,map.getZoomLevel());
baseHeight/=Math.pow(2,map.getZoomLevel());
}
for(var i=0;i<points.length;i++){
if(points[i].x<minLong)minLong=points[i].x;
if(points[i].x>maxLong)maxLong=points[i].x;
if(points[i].y<minLat)minLat=points[i].y;
if(points[i].y>maxLat)maxLat=points[i].y;
}
var wZoom=0;
var w=Math.abs(maxLong-minLong);
for(var i=1;i<16;i++){
if(baseWidth>w)break;
baseWidth*=2;
wZoom=i;
}
var hZoom=0;
var h=Math.abs(maxLat-minLat);
for(var i=1;i<16;i++){
if(baseHeight>h)break;
baseHeight*=2;
hZoom=i;
}
map.centerAndZoom(
new GPoint((minLong+maxLong)/2,(minLat+maxLat)/2),(wZoom>hZoom?wZoom:hZoom)
);
}
function ZoomOut(){
resizeMap(map,routePoints);
}
function x_half_distance_between_points(p1,p2){
var a=p2.y+p1.y;
return a/2;
}
function y_half_distance_between_points(p1,p2){
var a=p2.x+p1.x;
return a/2;
}
function disHalf(){
var hwc=GreatCirclePoints(routePoints[routePoints.length-2],routePoints[routePoints.length-1]).length;
var midpc=Math.ceil(hwc/2);
var midpf=Math.floor(hwc/2);
var pointsc=[];
var pointsf=[];
points=GreatCirclePoints(routePoints[routePoints.length-2],routePoints[routePoints.length-1]);
var xh=x_half_distance_between_points(points[midpc],points[midpf]);
var yh=y_half_distance_between_points(points[midpc],points[midpf]);
var hwp=new GPoint(yh,xh);
var marker3=new GMarker(hwp);
map.addOverlay(marker3);
}
function AddPolylines(lines,ps,lineColor,lineWidth)
{
var line=new GPolyline(ps,lineColor,lineWidth);
lines.push(line);
map.addOverlay(line);
}
function GreatCirclePoints(p1,p2)
{
var maxDistanceMeters=200000.0;
var ps=[];
if(p1.distanceFrom(p2)<=maxDistanceMeters)
{
ps.push(p1);
ps.push(p2);
}
else
{
var theta1=p1.lng()*radiansPerDegree;
var phi1=(90.0-p1.lat())*radiansPerDegree;
var x1=earthRadiusMeters*Math.cos(theta1)*Math.sin(phi1);
var y1=earthRadiusMeters*Math.sin(theta1)*Math.sin(phi1);
var z1=earthRadiusMeters*Math.cos(phi1);
var theta2=p2.lng()*radiansPerDegree;
var phi2=(90.0-p2.lat())*radiansPerDegree;
var x2=earthRadiusMeters*Math.cos(theta2)*Math.sin(phi2);
var y2=earthRadiusMeters*Math.sin(theta2)*Math.sin(phi2);
var z2=earthRadiusMeters*Math.cos(phi2);
var x3=(x1+x2)/2.0;
var y3=(y1+y2)/2.0;
var z3=(z1+z2)/2.0;
var r3=Math.sqrt(x3*x3+y3*y3+z3*z3);
var theta3=Math.atan2(y3,x3);
var phi3=Math.acos(z3/r3);
var p3=new GLatLng(90.0-phi3*degreesPerRadian,theta3*degreesPerRadian);
var s1=GreatCirclePoints(p1,p3);
var s2=GreatCirclePoints(p3,p2);
for(var i=0;i<s1.length;++i)
ps.push(s1[i]);
for(var i=1;i<s2.length;++i)
ps.push(s2[i]);
}
return ps;
}
LatLon.distHaversine=function(lat1,lon1,lat2,lon2){
var R=6371;
var dLat=(lat2-lat1).toRad();
var dLon=(lon2-lon1).toRad();
lat1=lat1.toRad(),lat2=lat2.toRad();
var a=Math.sin(dLat/2)*Math.sin(dLat/2)+
Math.cos(lat1)*Math.cos(lat2)*
Math.sin(dLon/2)*Math.sin(dLon/2);
var c=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
var d=R*c;
return d;
}
LatLon.distCosineLaw=function(lat1,lon1,lat2,lon2){
var R=6371;
var d=Math.acos(Math.sin(lat1.toRad())*Math.sin(lat2.toRad())+
Math.cos(lat1.toRad())*Math.cos(lat2.toRad())*Math.cos((lon2-lon1).toRad()))*R;
return d;
}
LatLon.bearing=function(lat1,lon1,lat2,lon2){
lat1=lat1.toRad();lat2=lat2.toRad();
var dLon=(lon2-lon1).toRad();
var y=Math.sin(dLon)*Math.cos(lat2);
var x=Math.cos(lat1)*Math.sin(lat2)-
Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
return Math.atan2(y,x).toBrng();
}
LatLon.midPoint=function(lat1,lon1,lat2,lon2){
lat1=lat1.toRad();
lat2=lat2.toRad();
var dLon=(lon2-lon1).toRad();
var Bx=Math.cos(lat2)*Math.cos(dLon);
var By=Math.cos(lat2)*Math.sin(dLon);
lat3=Math.atan2(Math.sin(lat1)+Math.sin(lat2),
Math.sqrt((Math.cos(lat1)+Bx)*(Math.cos(lat1)+Bx)+By*By));
lon3=lon1.toRad()+Math.atan2(By,Math.cos(lat1)+Bx);
if(isNaN(lat3)||isNaN(lon3))return null;
return new LatLon(lat3.toDeg(),lon3.toDeg());
}
LatLon.prototype.destPoint=function(brng,d){
var R=6371;
var lat1=this.lat.toRad(),lon1=this.lon.toRad();
brng=brng.toRad();
var lat2=Math.asin(Math.sin(lat1)*Math.cos(d/R)+
Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng));
var lon2=lon1+Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
if(isNaN(lat2)||isNaN(lon2))return null;
return new LatLon(lat2.toDeg(),lon2.toDeg());
}
LatLon.prototype.finalBrng=function(brng,d){
var p1=this,p2=p1.destPoint(brng,d);
var rev=LatLon.bearing(p2.lat,p2.lon,p1.lat,p1.lon);
var rev=(rev+180)%360;
return rev;
}
LatLon.distRhumb=function(lat1,lon1,lat2,lon2){
var R=6371;
var dLat=(lat2-lat1).toRad(),dLon=Math.abs(lon2-lon1).toRad();
var dPhi=Math.log(Math.tan(lat2.toRad()/2+Math.PI/4)/Math.tan(lat1.toRad()/2+Math.PI/4));
var q=dLat/dPhi;
if(!isFinite(q))q=Math.cos(lat1.toRad());
if(dLon>Math.PI)dLon=2*Math.PI-dLon;
var d=Math.sqrt(dLat*dLat+q*q*dLon*dLon);
return d*R;
}
LatLon.brngRhumb=function(lat1,lon1,lat2,lon2){
var dLon=(lon2-lon1).toRad();
var dPhi=Math.log(Math.tan(lat2.toRad()/2+Math.PI/4)/Math.tan(lat1.toRad()/2+Math.PI/4));
if(Math.abs(dLon)>Math.PI)dLon=dLon>0?-(2*Math.PI-dLon):(2*Math.PI+dLon);
return Math.atan2(dLon,dPhi).toBrng();
}
LatLon.prototype.destPointRhumb=function(brng,dist){
var R=6371;
var d=parseFloat(dist)/R;
var lat1=this.lat.toRad(),lon1=this.lon.toRad();
brng=brng.toRad();
lat2=lat1+d*Math.cos(brng);
var dPhi=Math.log(Math.tan(lat2/2+Math.PI/4)/Math.tan(lat1/2+Math.PI/4));
var q=(lat2-lat1)/dPhi;
if(!isFinite(q))q=Math.cos(lat1);
var dLon=d*Math.sin(brng)/q;
if(Math.abs(lat2)>Math.PI/2)lat2=lat2>0?Math.PI-lat2:-Math.PI-lat2;
lon2=(lon1+dLon+Math.PI)%(2*Math.PI)-Math.PI;
if(isNaN(lat2)||isNaN(lon2))return null;
return new LatLon(lat2.toDeg(),lon2.toDeg());
}
function LatLon(lat,lon){
this.lat=lat;
this.lon=lon;
}
LatLon.prototype.toString=function(){
return this.lat.toLat()+', '+this.lon.toLon();
}
String.prototype.parseDeg=function(){
if(!isNaN(this))return Number(this);
var degLL=this.replace(/^-/,'').replace(/[NSEW]/i,'');
var dms=degLL.split(/[^0-9.,]+/);
for(var i in dms)if(dms[i]=='')dms.splice(i,1);
switch(dms.length){
case 3:
var deg=dms[0]/1+dms[1]/60+dms[2]/3600;break;
case 2:
var deg=dms[0]/1+dms[1]/60;break;
case 1:
if(/[NS]/i.test(this))degLL='0'+degLL;
var deg=dms[0].slice(0,3)/1+dms[0].slice(3,5)/60+dms[0].slice(5)/3600;break;
default:return NaN;
}
if(/^-/.test(this)||/[WS]/i.test(this))deg=-deg;
return deg;
}
Number.prototype.toRad=function(){
return this*Math.PI/180;
}
Number.prototype.toDeg=function(){
return this*180/Math.PI;
}
Number.prototype.toBrng=function(){
return(this.toDeg()+360)%360;
}
Number.prototype.toDMS=function(){
var d=Math.abs(this);
d+=1/7200;
var deg=Math.floor(d);
var min=Math.floor((d-deg)*60);
var sec=Math.floor((d-deg-min/60)*3600);
if(deg<100)deg='0'+deg;if(deg<10)deg='0'+deg;
if(min<10)min='0'+min;
if(sec<10)sec='0'+sec;
return deg+'\u00B0'+min+'\u2032'+sec+'\u2033';
}
Number.prototype.toLat=function(){
return this.toDMS().slice(1)+(this<0?'S':'N');
}
Number.prototype.toLon=function(){
return this.toDMS()+(this>0?'E':'W');
}
Number.prototype.toPrecision=function(fig){
if(this==0)return 0;
var scale=Math.ceil(Math.log(this)*Math.LOG10E);
var mult=Math.pow(10,fig-scale);
return Math.round(this*mult)/mult;
}
