/** * Transform a geographic point (in radians), producing a projected result (in the units of the * target coordinate system). * * @param x the geographic x ordinate (in radians) * @param y the geographic y ordinate (in radians) * @param dst the projected coordinate (in coordinate system units) * @return the target coordinate */ private ProjCoordinate projectRadians(double x, double y, ProjCoordinate dst) { project(x, y, dst); if (unit == Units.DEGREES) { // convert radians to DD dst.x *= RTD; dst.y *= RTD; } else { // assume result is in metres dst.x = totalScale * dst.x + totalFalseEasting; dst.y = totalScale * dst.y + totalFalseNorthing; } return dst; }
public ProjCoordinate project(double lplam, double lpphi, ProjCoordinate xy) { if (spherical) { xy.x = Math.asin(Math.cos(lpphi) * Math.sin(lplam)); xy.y = Math.atan2(Math.tan(lpphi), Math.cos(lplam)) - projectionLatitude; } else { xy.y = ProjectionMath.mlfn(lpphi, n = Math.sin(lpphi), c = Math.cos(lpphi), en); n = 1. / Math.sqrt(1. - es * n * n); tn = Math.tan(lpphi); t = tn * tn; a1 = lplam * c; c *= es * c / (1 - es); a2 = a1 * a1; xy.x = n * a1 * (1. - a2 * t * (C1 - (8. - t + 8. * c) * a2 * C2)); xy.y -= m0 - n * tn * a2 * (.5 + (5. - t + 6. * c) * a2 * C3); } return xy; }
/** * Inverse-transforms a point (in the units defined by the coordinate system), producing a * geographic result (in radians) * * @param src the input projected coordinate (in coordinate system units) * @param dst the inverse-projected geographic coordinate (in radians) * @return the target coordinate */ public ProjCoordinate inverseProjectRadians(ProjCoordinate src, ProjCoordinate dst) { double x; double y; if (unit == Units.DEGREES) { // convert DD to radians x = src.x * DTR; y = src.y * DTR; } else { x = (src.x - totalFalseEasting) / totalScale; y = (src.y - totalFalseNorthing) / totalScale; } projectInverse(x, y, dst); if (dst.x < -Math.PI) dst.x = -Math.PI; else if (dst.x > Math.PI) dst.x = Math.PI; if (projectionLongitude != 0) dst.x = ProjectionMath.normalizeLongitude(dst.x + projectionLongitude); return dst; }
public ProjCoordinate projectInverse(double xyx, double xyy, ProjCoordinate out) { if (spherical) { out.y = Math.asin(Math.sin(dd = xyy + projectionLatitude) * Math.cos(xyx)); out.x = Math.atan2(Math.tan(xyx), Math.cos(dd)); } else { double ph1; ph1 = ProjectionMath.inv_mlfn(m0 + xyy, es, en); tn = Math.tan(ph1); t = tn * tn; n = Math.sin(ph1); r = 1. / (1. - es * n * n); n = Math.sqrt(r); r *= (1. - es) * n; dd = xyx / n; d2 = dd * dd; out.y = ph1 - (n * tn / r) * d2 * (.5 - (1. + 3. * t) * d2 * C3); out.x = dd * (1. + t * d2 * (-C4 + (1. + 3. * t) * d2 * C5)) / Math.cos(ph1); } return out; }
public ProjCoordinate project(ProjCoordinate in, ProjCoordinate out) { double lon = ProjectionMath.normalizeLongitude(in.x - projectionLongitude); double lat = in.y; double rho, theta, hold1, hold2, hold3; hold2 = Math.pow( ((1.0 - eccentricity * Math.sin(lat)) / (1.0 + eccentricity * Math.sin(lat))), 0.5 * eccentricity); hold3 = Math.tan(ProjectionMath.QUARTERPI - 0.5 * lat); hold1 = (hold3 == 0.0) ? 0.0 : Math.pow(hold3 / hold2, n); rho = radius * f * hold1; theta = n * lon; out.x = rho * Math.sin(theta); out.y = rho0 - rho * Math.cos(theta); return out; }
public ProjCoordinate inverseProject(ProjCoordinate in, ProjCoordinate out) { double theta, temp, rho, t, tphi, phi = 0, delta; theta = Math.atan(in.x / (rho0 - in.y)); out.x = (theta / n) + projectionLongitude; temp = in.x * in.x + (rho0 - in.y) * (rho0 - in.y); rho = Math.sqrt(temp); if (n < 0) rho = -rho; t = Math.pow((rho / (radius * f)), 1. / n); tphi = ProjectionMath.HALFPI - 2.0 * Math.atan(t); delta = 1.0; for (int i = 0; i < 100 && delta > 1.0e-8; i++) { temp = (1.0 - eccentricity * Math.sin(tphi)) / (1.0 + eccentricity * Math.sin(tphi)); phi = ProjectionMath.HALFPI - 2.0 * Math.atan(t * Math.pow(temp, 0.5 * eccentricity)); delta = Math.abs(Math.abs(tphi) - Math.abs(phi)); tphi = phi; } out.y = phi; return out; }
/** * Computes the inverse projection of a given point (i.e. from projection space to geographics). * This should be overridden for all projections. * * @param x the projected x ordinate (in coordinate system units) * @param y the projected y ordinate (in coordinate system units) * @param dst the inverse-projected geographic coordinate (in radians) * @return the target coordinate */ protected ProjCoordinate projectInverse(double x, double y, ProjCoordinate dst) { dst.x = x; dst.y = y; return dst; }
/** * Inverse-projects a point (in the units defined by the coordinate system), producing a * geographic result (in degrees) * * @param src the input projected coordinate (in coordinate system units) * @param dst the inverse-projected geographic coordinate (in degrees) * @return the target coordinate */ public ProjCoordinate inverseProject(ProjCoordinate src, ProjCoordinate dst) { inverseProjectRadians(src, dst); dst.x *= RTD; dst.y *= RTD; return dst; }
public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp) { if (spherical) { double c, rh, sinc, cosc; sinc = Math.sin(c = 2. * Math.atan((rh = ProjectionMath.distance(x, y)) / akm1)); cosc = Math.cos(c); lp.x = 0.; switch (mode) { case EQUATOR: if (Math.abs(rh) <= EPS10) lp.y = 0.; else lp.y = Math.asin(y * sinc / rh); if (cosc != 0. || x != 0.) lp.x = Math.atan2(x * sinc, cosc * rh); break; case OBLIQUE: if (Math.abs(rh) <= EPS10) lp.y = projectionLatitude; else lp.y = Math.asin(cosc * sinphi0 + y * sinc * cosphi0 / rh); if ((c = cosc - sinphi0 * Math.sin(lp.y)) != 0. || x != 0.) lp.x = Math.atan2(x * sinc * cosphi0, c * rh); break; case NORTH_POLE: y = -y; case SOUTH_POLE: if (Math.abs(rh) <= EPS10) lp.y = projectionLatitude; else lp.y = Math.asin(mode == SOUTH_POLE ? -cosc : cosc); lp.x = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y); break; } } else { double cosphi, sinphi, tp, phi_l, rho, halfe, halfpi; rho = ProjectionMath.distance(x, y); switch (mode) { case OBLIQUE: case EQUATOR: default: // To prevent the compiler complaining about uninitialized vars. cosphi = Math.cos(tp = 2. * Math.atan2(rho * cosphi0, akm1)); sinphi = Math.sin(tp); phi_l = Math.asin(cosphi * sinphi0 + (y * sinphi * cosphi0 / rho)); tp = Math.tan(.5 * (ProjectionMath.HALFPI + phi_l)); x *= sinphi; y = rho * cosphi0 * cosphi - y * sinphi0 * sinphi; halfpi = ProjectionMath.HALFPI; halfe = .5 * e; break; case NORTH_POLE: y = -y; case SOUTH_POLE: phi_l = ProjectionMath.HALFPI - 2. * Math.atan(tp = -rho / akm1); halfpi = -ProjectionMath.HALFPI; halfe = -.5 * e; break; } for (int i = 8; i-- != 0; phi_l = lp.y) { sinphi = e * Math.sin(phi_l); lp.y = 2. * Math.atan(tp * Math.pow((1. + sinphi) / (1. - sinphi), halfe)) - halfpi; if (Math.abs(phi_l - lp.y) < EPS10) { if (mode == SOUTH_POLE) lp.y = -lp.y; lp.x = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y); return lp; } } throw new ConvergenceFailureException("Iteration didn't converge"); } return lp; }
public ProjCoordinate project(double lam, double phi, ProjCoordinate xy) { double coslam = Math.cos(lam); double sinlam = Math.sin(lam); double sinphi = Math.sin(phi); if (spherical) { double cosphi = Math.cos(phi); switch (mode) { case EQUATOR: xy.y = 1. + cosphi * coslam; if (xy.y <= EPS10) throw new ProjectionException(); xy.x = (xy.y = akm1 / xy.y) * cosphi * sinlam; xy.y *= sinphi; break; case OBLIQUE: xy.y = 1. + sinphi0 * sinphi + cosphi0 * cosphi * coslam; if (xy.y <= EPS10) throw new ProjectionException(); xy.x = (xy.y = akm1 / xy.y) * cosphi * sinlam; xy.y *= cosphi0 * sinphi - sinphi0 * cosphi * coslam; break; case NORTH_POLE: coslam = -coslam; phi = -phi; case SOUTH_POLE: if (Math.abs(phi - ProjectionMath.HALFPI) < TOL) throw new ProjectionException(); xy.x = sinlam * (xy.y = akm1 * Math.tan(ProjectionMath.QUARTERPI + .5 * phi)); xy.y *= coslam; break; } } else { double sinX = 0, cosX = 0, X, A; if (mode == OBLIQUE || mode == EQUATOR) { sinX = Math.sin(X = 2. * Math.atan(ssfn(phi, sinphi, e)) - ProjectionMath.HALFPI); cosX = Math.cos(X); } switch (mode) { case OBLIQUE: A = akm1 / (cosphi0 * (1. + sinphi0 * sinX + cosphi0 * cosX * coslam)); xy.y = A * (cosphi0 * sinX - sinphi0 * cosX * coslam); xy.x = A * cosX; break; case EQUATOR: A = 2. * akm1 / (1. + cosX * coslam); xy.y = A * sinX; xy.x = A * cosX; break; case SOUTH_POLE: phi = -phi; coslam = -coslam; sinphi = -sinphi; case NORTH_POLE: xy.x = akm1 * ProjectionMath.tsfn(phi, sinphi, e); xy.y = -xy.x * coslam; break; } xy.x = xy.x * sinlam; } return xy; }