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; 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 * Also known as Bursa-Wolf. 017 */ 018public class SevenParameterDatum extends AbstractDatum { 019 020 protected double dx, dy, dz, rx, ry, rz, s; 021 022 /** 023 * 024 * @param name name of the datum 025 * @param proj4Id Proj.4 identifier for this datum (or null) 026 * @param ellps the ellipsoid used 027 * @param dx x offset in meters 028 * @param dy y offset in meters 029 * @param dz z offset in meters 030 * @param rx rotational parameter in seconds of arc 031 * @param ry rotational parameter in seconds of arc 032 * @param rz rotational parameter in seconds of arc 033 * @param s scale change in parts per million 034 */ 035 public SevenParameterDatum(String name, String proj4Id, Ellipsoid ellps, double dx, double dy, double dz, 036 double rx, double ry, double rz, double s) { 037 super(name, proj4Id, ellps); 038 this.dx = dx; 039 this.dy = dy; 040 this.dz = dz; 041 this.rx = Math.toRadians(rx / 3600); 042 this.ry = Math.toRadians(ry / 3600); 043 this.rz = Math.toRadians(rz / 3600); 044 this.s = s / 1e6; 045 } 046 047 @Override 048 public LatLon toWGS84(LatLon ll) { 049 double[] xyz = ellps.latLon2Cart(ll); 050 double x = dx + xyz[0]*(1+s) + xyz[2]*ry - xyz[1]*rz; 051 double y = dy + xyz[1]*(1+s) + xyz[0]*rz - xyz[2]*rx; 052 double z = dz + xyz[2]*(1+s) + xyz[1]*rx - xyz[0]*ry; 053 return Ellipsoid.WGS84.cart2LatLon(new double[] {x, y, z}); 054 } 055 056 @Override 057 public LatLon fromWGS84(LatLon ll) { 058 double[] xyz = Ellipsoid.WGS84.latLon2Cart(ll); 059 double x = (1-s)*(-dx + xyz[0] + ((-dz+xyz[2])*(-ry) - (-dy+xyz[1])*(-rz))); 060 double y = (1-s)*(-dy + xyz[1] + ((-dx+xyz[0])*(-rz) - (-dz+xyz[2])*(-rx))); 061 double z = (1-s)*(-dz + xyz[2] + ((-dy+xyz[1])*(-rx) - (-dx+xyz[0])*(-ry))); 062 return this.ellps.cart2LatLon(new double[] {x, y, z}); 063 } 064}