// Content-type: text/javascript
// File-name: wgsgmap.js
// NAME: WPoint and WBounds for Google Maps API
// VERSION: 1.3 Aug. 6 2005
// SYNOPSYS:
//   var wpoint = new WPoint(WGS_x, WGS_y);
//   var wpoint = WPoint.fromGPoint(gpoint);
//   var gpoint = wpoint.gpoint();
//   map.centerLatLng((new WPoint(WGS_x, WGS_y)).gpoint());
//   var wpoint = WPoint.fromGPoint(map.getCenterLatLng());
//   var wbounds = new WBounds(WGS_minX, WGS_minY, WGS_maxX, WGS_maxY);
//   var wbounds = WBounds.fromGBounds(gbounds);
//   var gbounds = wbounds.gbounds();
//   var wbounds = WBounds.fromGBounds(map.getBoundsLatLng());
// DESCRIPTION:
//   From 12 Jul. 2005, Google Maps uses
//   the Geodetic System mixed World and Tokyo.
//   Later is available in the range of
//     east longitude between 115.0 to 152.0 degree
//     and north latitude between 30.0 to 50.0 degree.
//   Following snipets provides you using WGS84 for all area on the earth.
// OBSOLUTE:
//   Version 1.1 lost 3 columns at most east.
// LICENSE:
//   This is the free software under Berkeley Software Distribution License.
//   You can use, modify, and redistribute it without author's permissions.
// AUTHOR: MIZUTANI Tociyuki
// URL: http://tociyuki.cool.ne.jp/ (sorry japanese only)

function WPoint(a, b, c) {
  this.x = a; this.y = b;
}

WPoint.VERSION = '1.3';

WPoint.prototype.toString = function() {
  return '(' + this.x + ', ' + this.y + ')';
}

WPoint.prototype.gpoint = function() {
  var d = WPoint.delta(this.x, this.y);
  return new GPoint(this.x - d.x, this.y - d.y);
}

WPoint.fromGPoint = function(a) {
  return WPoint.fromGPointXY(a.x,a.y);
}

WPoint.fromGPointXY = function(a,b) {
  var r = WPoint.delta(a,b);
  r.x = a + r.x;
  r.y = b + r.y;
  return r;
}

// WGS = Tokyo + ( latitude(dy), longitude(dx) ) in second.
// The license of following data is as same as the web page
//   <http://vldb.gsi.go.jp/sokuchi/coordinates/localtrans.html>.
WPoint.tTokyo2WGS84 = [
[[0,0],[12.71,-8.17],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[12.53,-8.21],[12.57,-8.4],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[12.28,-8.25],[12.37,-8.55],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[12,-8.15],[12.06,-8.38],[12.17,-8.69],[12.23,-8.99],[12.21,-9.21],[12.28,-9.6],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[11.87,-8.23],[11.84,-8.44],[11.94,-8.71],[11.99,-9.02],[12.05,-9.36],[12.1,-9.64],[12.1,-10.08],[12.07,-10.25],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[11.65,-8.59],[11.68,-8.8],[11.73,-9.04],[11.72,-9.48],[11.81,-9.74],[11.88,-10.1],[11.91,-10.35],[11.9,-10.7],[12.02,-11.09],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[11.44,-9.21],[11.47,-9.52],[11.55,-9.8],[11.61,-10.12],[11.66,-10.47],[11.78,-10.79],[11.85,-11.13],[11.9,-11.47],[11.91,-11.69],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[11.27,-9.31],[11.33,-9.52],[11.38,-9.86],[11.41,-10.14],[11.39,-10.52],[11.49,-10.83],[11.58,-11.21],[11.65,-11.53],[11.72,-11.8],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[11.11,-10.59],[11.16,-10.97],[11.29,-11.23],[11.36,-11.59],[11.44,-11.88],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[10.83,-10.77],[10.95,-11],[10.97,-11.34],[11.04,-11.69],[11.17,-12.05],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[10.67,-10.86],[10.68,-10.97],[10.8,-11.53],[10.8,-11.73],[10.92,-12.16],[11,-12.25],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[10.54,-11.96],[10.65,-12.27],[10.67,-12.5],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[10.29,-12.13],[10.33,-12.27],[10.45,-12.61],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[9.91,-12.21],[10.08,-12.35],[10.19,-12.74],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[9.81,-12.29],[9.81,-12.45],[9.92,-12.79],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[9.55,-12.63],[9.62,-12.62],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[9.25,-12.72],[9.39,-12.91],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[8.9,-12.68],[8.99,-12.8],[9,-13.07],[9.21,-13.51],[9.33,-13.66],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[8.79,-13],[8.84,-13.31],[8.98,-13.59],[9.1,-13.91],[9.17,-14.27],[9.23,-14.52]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[8.63,-13.49],[8.71,-13.73],[8.84,-14.03],[8.98,-14.33],[9.1,-14.56]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[8.37,-13.65],[8.44,-13.87],[8.61,-14.06],[8.73,-14.3],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[8.1,-13.81],[8.15,-13.95],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[7.92,-13.88],[7.94,-13.97],[0,0],[0,0],[0,0]],
];

WPoint.delta = function(a,b) {
  var dx = 0, dy = 0;
  if (_SATELLITE_TYPE.japanDatumHack) {
    if (a > 115 && a < 152 && b > 30 && b < 50) {
      var m = b * 60;
      if (1840 <= m && m <= 2800 && 129 <= a && a <= 147) {
        var j = Math.floor((m - 1840)/40);
        var i = Math.floor(a - 129);
        var v = WPoint.tTokyo2WGS84[j][i];
        return new WPoint(v[1]/3600, v[0]/3600);
      }
      dx = -0.0032027777777777775;
      dy = +0.003236111111111111;
    }
  }
  return new WPoint(dx, dy);
}

function WBounds(a,b,c,d) {
  this.minX = a; this.minY = b; this.maxX = c; this.maxY = d;
}

WBounds.VERSION = '1.0';

WBounds.prototype.toString = function() {
  return 'Bounds(' + this.minX + ',' + this.minY + ',' + this.maxX + ',' + this.maxY + ')';
}

WBounds.prototype.gbounds = function() {
  var minR = (new WPoint(this.minX, this.minY)).gpoint();
  var maxR = (new WPoint(this.maxX, this.maxX)).gpoint();
  return new GBounds(minR.x, minR.y, maxR.x, maxR.y);
}

WBounds.fromGBounds = function(a) {
  var minR = WPoint.fromGPointXY(a.minX, a.minY);
  var maxR = WPoint.fromGPointXY(a.maxX, a.maxY);
  return new WBounds(minR.x, minR.y, maxR.x, maxR.y);
}
