package com.revolsys.geometry.cs.projection; import com.revolsys.geometry.cs.Datum; import com.revolsys.geometry.cs.GeographicCoordinateSystem; import com.revolsys.geometry.cs.ProjectedCoordinateSystem; import com.revolsys.geometry.cs.ProjectionParameterNames; import com.revolsys.geometry.cs.Spheroid; import com.revolsys.math.Angle; public class Mercator1SPSpherical extends AbstractCoordinatesProjection { /** The central origin. */ private final double lambda0; private final double r; private final double x0; private final double y0; public Mercator1SPSpherical(final ProjectedCoordinateSystem cs) { final GeographicCoordinateSystem geographicCS = cs.getGeographicCoordinateSystem(); final Datum datum = geographicCS.getDatum(); final double centralMeridian = cs .getDoubleParameter(ProjectionParameterNames.LONGITUDE_OF_CENTER); final Spheroid spheroid = datum.getSpheroid(); this.x0 = cs.getDoubleParameter(ProjectionParameterNames.FALSE_EASTING); this.y0 = cs.getDoubleParameter(ProjectionParameterNames.FALSE_NORTHING); this.lambda0 = Math.toRadians(centralMeridian); this.r = spheroid.getSemiMinorAxis(); } @Override public void inverse(final double x, final double y, final double[] targetCoordinates, final int targetOffset) { final double dX = x - this.x0; final double dY = y - this.y0; final double lambda = dX / this.r + this.lambda0; final double phi = Angle.PI_OVER_2 - 2 * Math.atan(Math.pow(Math.E, -dY / this.r)); targetCoordinates[targetOffset] = lambda; targetCoordinates[targetOffset + 1] = phi; } @Override public void project(final double lambda, final double phi, final double[] targetCoordinates, final int targetOffset) { final double x = this.r * (lambda - this.lambda0); final double y = this.r * Math.log(Math.tan(Angle.PI_OVER_4 + phi / 2)); targetCoordinates[targetOffset] = this.x0 + x; targetCoordinates[targetOffset + 1] = this.y0 + y; } }