function MakeCaller(func,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10){ 
	return function(){func(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10);};
}
function Props(o)
{var s='';for(p in o)
{if(s.length!=0)
s+='\n';s+=p+': '+o[p];}
return s;}
var degreesPerRadian=180.0/Math.PI;var radiansPerDegree=Math.PI/180.0;
function Bearing(from,to)
{var lat1=from.lat()*radiansPerDegree;var lon1=from.lng()*radiansPerDegree;var lat2=to.lat()*radiansPerDegree;var lon2=to.lng()*radiansPerDegree;var angle=-Math.atan2(Math.sin(lon1-lon2)*Math.cos(lat2),Math.cos(lat1)*Math.sin(lat2)-Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon1-lon2));if(angle<0.0)
angle+=Math.PI*2.0;angle=angle*degreesPerRadian;return angle;}
function BadBearing(from,to)
{var a=from.lat();var b=to.lat();var l=to.lng()-from.lng();var episilon=0.0000000001;if(Math.abs(l)<=episilon)
if(a>b)
return 180.0;else
return 0.0;else if(Math.abs(Math.abs(l)-180.0)<=episilon)
if(a>=0.0&&b>=0.0)
return 0.0;else if(a<0.0&&b<0.0)
return 180.0;else if(a>=0.0)
if(a>-b)
return 0.0;else
return 180.0;else
if(a>-b)
return 180.0;else
return 0.0;a*=radiansPerDegree;b*=radiansPerDegree;l*=radiansPerDegree;var d=Math.acos(Math.sin(a)*Math.sin(b)+Math.cos(a)*Math.cos(b)*Math.cos(l));var angle=Math.acos((Math.sin(b)-Math.sin(a)*Math.cos(d))/(Math.cos(a)*Math.sin(d)));angle=angle*degreesPerRadian;if(Math.sin(l)<0)
angle=360.0-angle;return angle;}



var mapDiv=document.getElementById('map');
var map;var points=[];var markers=[];var lines=[];var polygonPoints=[];var polygon=null;var lineWidth=5;var lineColor='#ff0000';var closerColor='#0000ff';var fillColor='#e9f288';var redIcon=new GIcon(G_DEFAULT_ICON);redIcon.image='js_plugins/measure_area/red.png';redIcon.iconSize=new GSize(20,34);redIcon.shadowSize=new GSize(37,34);redIcon.iconAnchor=new GPoint(9,34);redIcon.infoWindowAnchor=new GPoint(9,2);redIcon.infoShadowAnchor=new GPoint(18,25);var blueIcon=new GIcon(redIcon);blueIcon.image='js_plugins/measure_area/blue.png';


function UpdatePedometerLink()
{var mapCenter=map.getCenter();var mapZoom=map.getZoom();var mapTypeLetter=MapTypeToLetter(map.getCurrentMapType());mapTypeLetter=mapTypeLetter.toLowerCase();}


function Display()
{
var areaDiv=document.getElementById('area');
for(var i=0;i<markers.length;++i)
map.removeOverlay(markers[i]);markers=[];for(var i=0;i<lines.length;++i)
map.removeOverlay(lines[i]);lines=[];polygonPoints=[];if(polygon!=null)
{map.removeOverlay(polygon);polygon=null;}
for(var i=0;i<points.length;++i)
{var marker=new GMarker(points[i],{icon:i==points.length-1?blueIcon:redIcon});markers.push(marker);map.addOverlay(marker);GEvent.addListener(marker,'click',MakeCaller(MarkerClick,i));if(i>0&&points.length>=3)
AddPolylines(lines,GreatCirclePoints(points[i-1],points[i]),lineColor,lineWidth);}
if(points.length>=2)
AddPolylines(lines,GreatCirclePoints(points[points.length-1],points[0]),closerColor,lineWidth);if(points.length>=3)
{polygon=new GPolygon(polygonPoints,lineColor,0,0,fillColor,0.5);map.addOverlay(polygon);}
var smallFontOpen='<font size="-1">';var fontClose='</font>';var mapInst='Drag the map with your mouse, or double-click to center.';var clickInst='Click on the map to place points.';var html=smallFontOpen+mapInst+'<p>'+clickInst;areaDiv.innerHTML='&nbsp;';
	if(points.length<=2) {
		html = '<div style="text-align:right;"><a href="javascript:showHidemeasureArea();">Schlie&szlig;en <img src="img/icons/close.png" align="absmiddle" border="0"></a></div><input type="radio" name="radMessen" value="area" onclick="measureArea();" checked> Fl&auml;che <input type="radio" name="radMessen" value="line" onclick="measureDistance();"> Linie<br><div id="area_text">Bitte beschreiben Sie eine Fl&auml;che mit mindestens drei Punkten <u>im Uhrzeigersinn</u>.</div>';
		areaDiv.innerHTML=html;
	} else {
		html = '<div style="text-align:right;"><a href="javascript:showHidemeasureArea();">Schlie&szlig;en <img src="img/icons/close.png" align="absmiddle" border="0"></a></div><input type="radio" name="radMessen" value="area" onclick="measureArea();" checked> Fl&auml;che <input type="radio" name="radMessen" value="line" onclick="measureDistance();"> Linie<br><div id="area_text">';
		html+='<u>Selektierte Fl&auml;che:</u><br>Werte sind N&auml;herungswerte.<br>';
		var areaMeters2=SphericalPolygonAreaMeters2(points);
		if(areaMeters2<1000000.0)areaMeters2=PlanarPolygonAreaMeters2(points);areaDiv.innerHTML=html+smallFontOpen+Areas(areaMeters2)+fontClose;
		html += '</div>';
	}
html+=fontClose;
}


function AddPolylines(lines,ps,lineColor,lineWidth)
{var line=new GPolyline(ps,lineColor,lineWidth);lines.push(line);map.addOverlay(line);for(var i=0;i<ps.length;++i)
polygonPoints.push(ps[i]);}
var metersPerKm=1000.0;var meters2PerHectare=10000.0;var feetPerMeter=3.2808399;var feetPerMile=5280.0;var acresPerMile2=640;

function Areas(areaMeters2)
{var areaHectares=areaMeters2/meters2PerHectare;var areaKm2=areaMeters2/metersPerKm/metersPerKm;var areaFeet2=areaMeters2*feetPerMeter*feetPerMeter;var areaMiles2=areaFeet2/feetPerMile/feetPerMile;var areaAcres=areaMiles2*acresPerMile2;return Math.round(areaMeters2)+' m&sup2; <br> '+areaHectares.toPrecision(4)+' ha <br> '+areaKm2.toPrecision(4)+' km&sup2; <!--/ '+areaFeet2.toPrecision(4)+' ft&sup2; / '+areaAcres.toPrecision(4)+' acres / '+areaMiles2.toPrecision(4)+' mile&sup2;-->';}
var earthRadiusMeters=6367460.0;var metersPerDegree=2.0*Math.PI*earthRadiusMeters/360.0;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;}


function PlanarPolygonAreaMeters2(points)
{var a=0.0;for(var i=0;i<points.length;++i)
{var j=(i+1)%points.length;var xi=points[i].lng()*metersPerDegree*Math.cos(points[i].lat()*radiansPerDegree);var yi=points[i].lat()*metersPerDegree;var xj=points[j].lng()*metersPerDegree*Math.cos(points[j].lat()*radiansPerDegree);var yj=points[j].lat()*metersPerDegree;a+=xi*yj-xj*yi;}
return Math.abs(a/2.0);}


function SphericalPolygonAreaMeters2(points)
{var totalAngle=0.0;for(i=0;i<points.length;++i)
{var j=(i+1)%points.length;var k=(i+2)%points.length;totalAngle+=Angle(points[i],points[j],points[k]);}
var planarTotalAngle=(points.length-2)*180.0;var sphericalExcess=totalAngle-planarTotalAngle;if(sphericalExcess>420.0)
{totalAngle=points.length*360.0-totalAngle;sphericalExcess=totalAngle-planarTotalAngle;}
else if(sphericalExcess>300.0&&sphericalExcess<420.0)
{sphericalExcess=Math.abs(360.0-sphericalExcess);}
return sphericalExcess*radiansPerDegree*earthRadiusMeters*earthRadiusMeters;}


function Angle(p1,p2,p3)
{var bearing21=Bearing(p2,p1);var bearing23=Bearing(p2,p3);var angle=bearing21-bearing23;if(angle<0.0)
angle+=360.0;return angle;}
var clicked=false,doubleClicked;function MapClick(overlay,point)
{try
{if(overlay==null&&point!=null)
{if(clicked)
doubleClicked=true;else
{clicked=true;doubleClicked=false;setTimeout(MakeCaller(MapClickLater,point),250);}}}
catch(e)
{GLog.write('MapClick:\n'+Props(e));}}


function MapClickLater(point)
{try
{if(!doubleClicked)
{points.push(point);Display();}
clicked=false;}
catch(e)
{GLog.write('MapClickLater:\n'+Props(e));}}


function MarkerClick(pointIndex)
{try
{RotatePoints(pointIndex+1);Display();}
catch(e)
{GLog.write('MarkerClick:\n'+Props(e));}}


function RotatePoints(n)
{var t=[];for(var i=0;i<points.length;++i)
t.push(points[(i+n)%points.length]);points=t;}


function DeleteLastPoint()
{if(points.length>0)
points.length--;Display();}


function ClearAllPoints()
{points=[];Display();}
