Exemplo n.º 1
0
  /**
   * Inverse project x,y coordinates into a LatLonPoint.
   *
   * @param x integer x coordinate
   * @param y integer y coordinate
   * @param llp LatLonPoint
   * @return LatLonPoint llp
   * @see Proj#inverse(Point2D)
   */
  public <T extends Point2D> T inverse(double x, double y, T llp) {

    if (llp == null) {
      llp = (T) new LatLonPoint.Double();
    }

    // convert from screen to world coordinates
    x -= wx;
    y = hy - y;

    // Debug.output("Gnomonic.inverse: x,y=" + x + "," + y);

    double rho = Math.sqrt(x * x + y * y);
    if (rho == 0) {
      Debug.message("proj", "Gnomonic.inverse: center!");
      llp.setLocation(ProjMath.radToDeg(centerX), ProjMath.radToDeg(centerY));
      return llp;
    }

    double c = Math.atan2(rho, scaled_radius);
    double cosC = Math.cos(c);
    double sinC = Math.sin(c);

    // calculate latitude
    double lat = Math.asin(cosC * sinCtrLat + (y * sinC * (cosCtrLat / rho)));

    // calculate longitude
    double lon = centerX + Math.atan2((x * sinC), (rho * cosCtrLat * cosC - y * sinCtrLat * sinC));
    // Debug.output("Gnomonic.inverse: lat,lon=" +
    // ProjMath.radToDeg(lat) + "," +
    // ProjMath.radToDeg(lon));

    // check if point in outer space
    // if (MoreMath.approximately_equal(lat, ctrLat) &&
    // MoreMath.approximately_equal(lon, ctrLon) &&
    // (Math.abs(x-(width/2))<2) &&
    // (Math.abs(y-(height/2))<2))

    if (Double.isNaN(lat) || Double.isNaN(lon)) {
      Debug.message("proj", "Gnomonic.inverse(): outer space!");
      lat = centerY;
      lon = centerX;
    }

    llp.setLocation(Math.toDegrees(wrapLongitude(lon)), Math.toDegrees(normalizeLatitude(lat)));
    return llp;
  }
Exemplo n.º 2
0
  /**
   * Called when some fundamental parameters change.
   *
   * <p>Each projection will decide how to respond to this change. For instance, they may need to
   * recalculate "constant" parameters used in the forward() and inverse() calls.
   *
   * <p>
   */
  protected synchronized void computeParameters() {
    int w, h;

    if (ul == null) ul = new Point(0, 0); // HACK

    // quick calculate the maxscale
    maxscale = CADRG_calc_maxscale();
    if (scale > maxscale) scale = maxscale;

    // Compute the "ADRG" scale, which gets used below.
    double adrgscale = 1000000.0 / scale; // 1 million (from
    // ADRG
    // spec)
    if (adrgscale > CADRG_SCALE_LIMIT) {
      Debug.message("proj", "CADRG: adrgscale > CADRG_SCALE_LIMIT");
      adrgscale = CADRG_SCALE_LIMIT;
    }

    // Compute the y pixel constant based on scale.
    y_pix_constant = CADRG_y_pix_constant(adrgscale);
    if (Debug.debugging("proj")) {
      Debug.output("Y pix constant = " + y_pix_constant);
    }

    // ////

    /** Pixels per degree */
    double ppd = y_pix_constant / 90.0;
    if (upper_zone_extents == null || lower_zone_extents == null) {
      upper_zone_extents = new double[CADRG_get_zone_old_extents.length];
      lower_zone_extents = new double[CADRG_get_zone_old_extents.length + 1];

      lower_zone_extents[0] = 0f;
      lower_zone_extents[8] = 80f;
      upper_zone_extents[8] = 90f;

      // figure out new extents - from CADRG spec
      for (int x = 0; x < CADRG_get_zone_old_extents.length - 1 /* 8 */; x++) {
        double pivot = Math.floor(ppd * CADRG_get_zone_old_extents[x] / 1536.0);
        lower_zone_extents[x + 1] = pivot * 1536.0 / ppd;
        // Can't go further than the equator.
        // if (x == 0) lower_zone_extents[x] = 0;
        pivot++;
        upper_zone_extents[x] = pivot * 1536.0 / ppd;
        Debug.message("proj", "lower_zone_extents[" + x + "] = " + lower_zone_extents[x]);
        Debug.message("proj", "upper_zone_extents[" + x + "] = " + upper_zone_extents[x]);
      }
    }
    // ////

    // What zone are we in? To try to reduce pixel spacing jumping when
    // zoomed
    // out, just set the zone level to one when zoomed out past 1:60M. There
    // aren't any charts available at those scales in this projection type.

    if (scale > 60000000) {
      zone = 1;
    } else {
      zone = getZone(ProjMath.radToDeg(centerY), y_pix_constant);
    }
    if (Debug.debugging("proj")) {
      Debug.output("Zone = " + zone);
    }

    // Compute the x pixel constant, based on scale and zone.
    x_pix_constant = CADRG_x_pix_constant(adrgscale, zone);

    // If the x_pix_constant, or number of pixels around the earth is less
    // than or equal to the width of the map window, then the corner
    // coordinates become equal or inverted (ul vs lr).
    if (width >= x_pix_constant) {
      x_pix_constant = width + 1;
    }

    if (Debug.debugging("proj")) {
      Debug.output("x_pix_constant = " + x_pix_constant);
    }
    // Now I can compute the world coordinate.
    if (world == null) world = new Point(0, 0);
    world.x = (int) ProjMath.roundAdjust(x_pix_constant);
    world.y = (int) ProjMath.roundAdjust(y_pix_constant * 4.0 / 2.0);
    Debug.message("proj", "world = " + world.x + "," + world.y);

    // Compute scaled pixels per RADIAN, not SCOORD
    spps_x = (double) x_pix_constant / MoreMath.TWO_PI /*
                                                           * MoreMath.DEG_TO_SC(360
                                                           * )
                                                           */;
    spps_y = (double) y_pix_constant / MoreMath.HALF_PI /*
                                                            * MoreMath.DEG_TO_SC(
                                                            * 90 )
                                                            */;
    Debug.message("proj", "spps = " + spps_x + "," + spps_y);

    // Fix the "small world" situation, computing ox, oy.
    if (width > world.x) {
      Debug.message("proj", "CADRG: fixing small world");
      w = world.x;
      // ox = (int) ProjMath.roundAdjust((width - w) / 2.0);
    } else {
      w = width;
      // ox = 0;
    }
    if (height > world.y) {
      h = (int) world.y;
      oy = (int) ProjMath.roundAdjust((height - h) / 2.0);
    } else {
      h = height;
      oy = 0;
    }

    // compute the "upper left" adjustment.
    long temp = (long) ProjMath.roundAdjust(spps_y * centerY);
    if (Debug.debugging("proj")) {
      Debug.output("CADRG.temp = " + temp);
    }
    if (ul == null) ul = new Point(0, 0);
    ul.x = (int) ProjMath.roundAdjust(-w / 2.0);
    if ((temp != 0) && (oy != 0)) {
      ul.y = (int) ProjMath.roundAdjust(h / 2.0);
    } else {
      ul.y = (int) temp + (int) ProjMath.roundAdjust(h / 2.0);
    }

    if (Debug.debugging("proj")) {
      Debug.output("CADRG: ul = " + ul.x + "," + ul.y);
      Debug.output(/* "ox = " + ox + */ " oy = " + oy);
    }

    // Finally compute some useful cylindrical projection
    // parameters
    // maxscale = (CADRG_ARC_A[0] * (1000000/width));// HACK!!!
    half_world = world.x / 2;

    if (scale > maxscale) {
      scale = maxscale;
    }
    // scaled_radius = planetPixelRadius/scale;
    Debug.message("proj", "CADRG.computeParameters(): maxscale: " + maxscale);
  }