
// Mercator functions "borrowed" from http://mapnut.com/testzoom.html

// return degrees per pixel for given Yahoo zoom level
function DegPerPixel(zoom) {
  // At the lowest zoom level, the world is 65536 tile images wide.
  // Each tile image is 512 pixels wide.
  // Therefore, the equator is 360/(512*65536) degrees per pixel, 
  // or 0.000010728836 degrees per pixel
  // (0.000009 is 1 m/pixel at equator)
  var degperpixelatequator = 0.000010728836;
  return (degperpixelatequator * Math.pow(2.0,(zoom-1)));
}

// return "projected latitude" in degrees
function MercatorProjectY(latitude) {
  var latradians = latitude * Math.PI / 180.0;
  var YProjradians = Math.log((1 + Math.sin(latradians))/(1 - Math.sin(latradians))) / 2.0;
  return (YProjradians * 180.0 / Math.PI);
}

// return latitude (from "projected latitude") in degrees
function InverseMercatorProjectY(YProj) {	
  var YProjradians = YProj * Math.PI /180.0;
  var latradians = 2 * Math.atan(Math.exp(YProjradians)) - Math.PI / 2;
  return (latradians * 180.0 / Math.PI);
}

// YGeoPoint -> local YCoordPoint
function project(point,map) {
  // absolute x,y of given point
  var givenXY = absproject(point,map.getZoomLevel());
  // absolute x,y of top left map corner
  var bounds = map.getBoundsLatLon();
  var cornerXY = absproject(new YGeoPoint(bounds.LatMax,bounds.LonMin),map.getZoomLevel());
  return new YCoordPoint(givenXY.x-cornerXY.x,cornerXY.y-givenXY.y);
}

// YGeoPoint -> absolute YCoordPoint
function absproject(point,zoom) {
  var sc = DegPerPixel(zoom);
  var x = (point.Lon + 180.0) / sc;
  var y = (MercatorProjectY(point.Lat) + 90.0) / sc;
  return new YCoordPoint(Math.round(x),Math.round(y));
}