// USGS_NATMAP_scale.js

// Values used in scale calculations.
// IMPORTANT NOTE: These values are to be used for rough approximations
// of relative scale (eg. zoom to an approximate target scale), 
// not for rigorous calculations of scale in the viewer. If
// a more accurate representation of scale is required these
// values and this approach will need to be revisited.
//
// The assumption here is that the map unit dimensions 
// are equivalent in the x and y directions of the display
// device, eg. a given pixel has the same extension (in this
// case degrees) in both the x-direction and the y-direction.
// This is a simplifying assumption to reduce complexity. No attempt
// should be made to derive ground distances or measures from
// these decimal degree extents. If the map units were in a
// projected coordinate system the extents would more accurately
// represent ground distances.
//
// Furthermore no attempt should be made to derive ground distance
// from measuring the view on the output device and deviding by the 
// a relative scale. This is highly dependant on the actual resolution
// of the output device (as in Dots per inch).  We use 96 dpi which
// is reasonable for a typical computer monitor, but is very wrong 
// for something like an overhead projector shown on an 2 meter screen.
// 96 dpi is also used by default for scale calculations by commercial 
// map servers. 
//

var METERS_PER_INCH = 0.0254;
// Assumed dots per inch of display device
var ASSUMED_DPI = 96;

// pixel size at assumed dpi, in meters
var pixelSizeInMeters = METERS_PER_INCH / ASSUMED_DPI;   // = 0.000265

// meters per degree on Earth's surface. Assumed circular
// earth with radius of 6,370,000 meters.
var metersPerDegree = 111195;

// See caveat at top of file!
function getDegreesPerPixel(scaleDenominator) {
	return scaleDenominator * pixelSizeInMeters / metersPerDegree;
}

// See caveat at top of file!
function getScaleDenominator(degreesPerPixel) {
	return degreesPerPixel * metersPerDegree / pixelSizeInMeters;
}

var scaleToolBreakScales = new Array();
scaleToolBreakScales[0] = REL_SCALE_MULTI_STATE * 2;
scaleToolBreakScales[1] = ((REL_SCALE_MULTI_STATE - REL_SCALE_STATE) / 2) + REL_SCALE_STATE;
scaleToolBreakScales[2] = ((REL_SCALE_STATE - REL_SCALE_REGION) / 2) + REL_SCALE_REGION;
scaleToolBreakScales[3] = ((REL_SCALE_REGION - REL_SCALE_CITY) / 2) + REL_SCALE_CITY;
scaleToolBreakScales[4] = ((REL_SCALE_CITY - REL_SCALE_NEIGHBORHOOD) / 2) + REL_SCALE_NEIGHBORHOOD;
scaleToolBreakScales[5] = ((REL_SCALE_NEIGHBORHOOD - REL_SCALE_LOCAL) / 2) + REL_SCALE_LOCAL;

var scaleToolZoomScales = new Array();
scaleToolZoomScales[0] = null;
scaleToolZoomScales[1] = REL_SCALE_MULTI_STATE;
scaleToolZoomScales[2] = REL_SCALE_STATE;
scaleToolZoomScales[3] = REL_SCALE_REGION;
scaleToolZoomScales[4] = REL_SCALE_CITY;
scaleToolZoomScales[5] = REL_SCALE_NEIGHBORHOOD;
scaleToolZoomScales[6] = REL_SCALE_LOCAL;

function setScaleToolBar (inExtent, inPixelHeight, inPixelWidth) {
  var curRelScale = getScaleDenominator(inExtent.ySize / inPixelHeight);
  var i = 0;
  for (i = 0; i < scaleToolBreakScales.length; i++) {
    if (curRelScale > scaleToolBreakScales[i]) {
      break;
    }
  }
  parent.ScaleBar.moveScale(i);
}

// Zoom to point, given lat-lon coords and relative 
// scale factor denominator (eg. if target scale
// is 1:12,000 relScale should equal 12000).
function zoomToPointAtScale(xIn, yIn, relScale) {
  handleRelScalePointZoom(xIn, yIn, relScale);  
  requestNewMainMap();
}

function handleRelScalePointZoom(x, y, relScale) {
  // see caveat at the top of USGS_NATMAP_scale.js
  var degreesPerPixel = getDegreesPerPixel(relScale);
  var halfReqHeight = (iHeight * degreesPerPixel) / 2;
  var halfReqWidth = (iWidth * degreesPerPixel) / 2;
  updateExtent(x, y, halfReqWidth, halfReqHeight);
}

function zoomToScale(relScale, inExtent) {
  var centerX = inExtent.minX + (inExtent.xSize / 2);
  var centerY = inExtent.minY + (inExtent.ySize / 2);
  zoomToPointAtScale(centerX, centerY, relScale);
}