package com.nutiteq.maps.projections; import henson.midp.Float11; import com.nutiteq.components.Point; import com.nutiteq.maps.BaseMap; import com.nutiteq.ui.Copyright; import com.nutiteq.ui.StringCopyright; public abstract class Lambert extends BaseMap implements Projection { private static double n = 0.85417585805D; // pre-calculated value private static final double F = 1.7988478514D; // pre-calculated value private static double p0 = 4020205.4790000D; // pre-calculated value // Coordinates of Origin private static final double FALSE_NORTHING = 6375000.0000000D; // False Northing private static final double FALSE_EASTING = 500000.0000000D; // False Easting private final Ellipsoid ellipsoid; public Lambert(final Ellipsoid ellipsoid, final Copyright copyright, final int tileSize, final int minZoom, final int maxZoom) { super(copyright, tileSize, minZoom, maxZoom); this.ellipsoid = ellipsoid; } public Lambert(final Ellipsoid ellipsoid, final String copyright, final int tileSize, final int minZoom, final int maxZoom) { this(ellipsoid, new StringCopyright(copyright), tileSize, minZoom, maxZoom); } public Point fromWgs(final Point from) { final double L = Math.toRadians(from.getX() / 1000000D); final double B = Math.toRadians(from.getY() / 1000000D); final double Lo = 24 * Math.PI / 180; final double t = Math.sqrt((1 - Math.sin(B)) / (1 + Math.sin(B)) * Float11.pow((1 + ellipsoid.getEccentricity() * Math.sin(B)) / (1 - ellipsoid.getEccentricity() * Math.sin(B)), ellipsoid.getEccentricity())); final double theta = n * (L - Lo); final double p = ellipsoid.getEquatorialRadius() * F * Float11.pow(t, n); final double x = p * Math.sin(theta) + FALSE_EASTING; final double y = p0 - p * Math.cos(theta) + FALSE_NORTHING; return new Point((int) x, (int) y); } public Point toWgs(final Point from) { final double Lo = 24 * Math.PI / 180; double ux = from.getX() - FALSE_EASTING; double uy = from.getY() - FALSE_NORTHING; final double sx = ux; ux = uy; uy = sx; final double theta = Float11.atan(uy / (p0 - ux)); final double tmpL = theta / n + Lo; double p = p0 - ux; p *= p; uy *= uy; p += uy; p = Math.sqrt(p); final double t = Float11.pow(p / (ellipsoid.getEquatorialRadius() * F), 1 / n); final double u = Math.PI / 2D - 2D * Float11.atan(t); //TODO jaanus : some of these calculations could be precalculated? final double tmpB = u + (Float11.pow(ellipsoid.getEccentricity(), 2) / 2 + 5 * Float11.pow(ellipsoid.getEccentricity(), 2) * Float11.pow(ellipsoid.getEccentricity(), 2) / 24 + Float11.pow(ellipsoid.getEccentricity(), 6) / 12 + 13 * Float11.pow(ellipsoid .getEccentricity(), 8) / 360) * Math.sin(2 * u) + (7 * Float11.pow(ellipsoid.getEccentricity(), 4) / 48 + 29 * Float11.pow(ellipsoid.getEccentricity(), 6) / 240 + 811 * Float11.pow(ellipsoid .getEccentricity(), 8) / 11520) * Math.sin(4 * u) + (7 * Float11.pow(ellipsoid.getEccentricity(), 6) / 120 + 81 * Float11.pow(ellipsoid .getEccentricity(), 8) / 1120) * Math.sin(6 * u); return new Point((int) (Math.toDegrees(tmpL) * 1000000), (int) (Math.toDegrees(tmpB) * 1000000)); } }