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