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