public void initialize() {
    double t;

    super.initialize();
    if (Math.abs((t = Math.abs(projectionLatitude)) - ProjectionMath.HALFPI) < EPS10)
      mode = projectionLatitude < 0. ? SOUTH_POLE : NORTH_POLE;
    else mode = t > EPS10 ? OBLIQUE : EQUATOR;
    trueScaleLatitude = Math.abs(trueScaleLatitude);
    if (!spherical) {
      double X;

      switch (mode) {
        case NORTH_POLE:
        case SOUTH_POLE:
          if (Math.abs(trueScaleLatitude - ProjectionMath.HALFPI) < EPS10)
            akm1 = 2. * scaleFactor / Math.sqrt(Math.pow(1 + e, 1 + e) * Math.pow(1 - e, 1 - e));
          else {
            akm1 =
                Math.cos(trueScaleLatitude)
                    / ProjectionMath.tsfn(trueScaleLatitude, t = Math.sin(trueScaleLatitude), e);
            t *= e;
            akm1 /= Math.sqrt(1. - t * t);
          }
          break;
        case EQUATOR:
          akm1 = 2. * scaleFactor;
          break;
        case OBLIQUE:
          t = Math.sin(projectionLatitude);
          X = 2. * Math.atan(ssfn(projectionLatitude, t, e)) - ProjectionMath.HALFPI;
          t *= e;
          akm1 = 2. * scaleFactor * Math.cos(projectionLatitude) / Math.sqrt(1. - t * t);
          sinphi0 = Math.sin(X);
          cosphi0 = Math.cos(X);
          break;
      }
    } else {
      switch (mode) {
        case OBLIQUE:
          sinphi0 = Math.sin(projectionLatitude);
          cosphi0 = Math.cos(projectionLatitude);
        case EQUATOR:
          akm1 = 2. * scaleFactor;
          break;
        case SOUTH_POLE:
        case NORTH_POLE:
          akm1 =
              Math.abs(trueScaleLatitude - ProjectionMath.HALFPI) >= EPS10
                  ? Math.cos(trueScaleLatitude)
                      / Math.tan(ProjectionMath.QUARTERPI - .5 * trueScaleLatitude)
                  : 2. * scaleFactor;
          break;
      }
    }
  }
 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;
 }
  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;
  }