001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.data.projection.datum; 003 004 import org.openstreetmap.josm.data.coor.LatLon; 005 import org.openstreetmap.josm.data.projection.Ellipsoid; 006 007 /** 008 * Datum provides general conversion from one ellipsoid to another. 009 * 010 * Seven parameters can be specified: 011 * - 3D offset 012 * - general rotation 013 * - scale 014 * 015 * This method is described by EPSG as EPSG::9606. 016 */ 017 public class SevenParameterDatum extends AbstractDatum { 018 019 protected double dx, dy, dz, rx, ry, rz, s; 020 021 /** 022 * 023 * @param name name of the datum 024 * @param proj4Id Proj.4 identifier for this datum (or null) 025 * @param ellps the ellipsoid used 026 * @param dx x offset in meters 027 * @param dy y offset in meters 028 * @param dz z offset in meters 029 * @param rx rotational parameter in seconds of arc 030 * @param ry rotational parameter in seconds of arc 031 * @param rz rotational parameter in seconds of arc 032 * @param s scale change in parts per million 033 */ 034 public SevenParameterDatum(String name, String proj4Id, Ellipsoid ellps, double dx, double dy, double dz, double rx, double ry, double rz, double s) { 035 super(name, proj4Id, ellps); 036 this.dx = dx; 037 this.dy = dy; 038 this.dz = dz; 039 this.rx = Math.toRadians(rx / 3600); 040 this.ry = Math.toRadians(ry / 3600); 041 this.rz = Math.toRadians(rz / 3600); 042 this.s = s / 1e6; 043 } 044 045 @Override 046 public LatLon toWGS84(LatLon ll) { 047 double[] xyz = ellps.latLon2Cart(ll); 048 double x = dx + xyz[0]*(1+s) + xyz[2]*ry - xyz[1]*rz; 049 double y = dy + xyz[1]*(1+s) + xyz[0]*rz - xyz[2]*rx; 050 double z = dz + xyz[2]*(1+s) + xyz[1]*rx - xyz[0]*ry; 051 return Ellipsoid.WGS84.cart2LatLon(new double[] { x, y, z }); 052 } 053 054 @Override 055 public LatLon fromWGS84(LatLon ll) { 056 double[] xyz = Ellipsoid.WGS84.latLon2Cart(ll); 057 double x = (1-s)*(-dx + xyz[0] + ((-dz+xyz[2])*(-ry) - (-dy+xyz[1])*(-rz))); 058 double y = (1-s)*(-dy + xyz[1] + ((-dx+xyz[0])*(-rz) - (-dz+xyz[2])*(-rx))); 059 double z = (1-s)*(-dz + xyz[2] + ((-dy+xyz[1])*(-rx) - (-dx+xyz[0])*(-ry))); 060 return this.ellps.cart2LatLon(new double[] { x, y, z }); 061 } 062 063 }