Пример #1
0
  /**
   * Called by the framework in order to compute the stack of tiles for the given target bands.
   *
   * <p>The default implementation throws a runtime exception with the message "not implemented".
   *
   * @param targetTiles The current tiles to be computed for each target band.
   * @param targetRectangle The area in pixel coordinates to be computed (same for all rasters in
   *     <code>targetRasters</code>).
   * @param pm A progress monitor which should be used to determine computation cancelation
   *     requests.
   * @throws OperatorException if an error occurs during computation of the target rasters.
   */
  @Override
  public void computeTileStack(
      Map<Band, Tile> targetTiles, Rectangle targetRectangle, ProgressMonitor pm)
      throws OperatorException {

    final int x0 = targetRectangle.x;
    final int y0 = targetRectangle.y;
    final int w = targetRectangle.width;
    final int h = targetRectangle.height;
    // System.out.println("x0 = " + x0 + ", y0 = " + y0 + ", w = " + w + ", h = " + h);

    double[] tileOverlapPercentage = {0.0, 0.0};
    try {
      if (!isElevationModelAvailable) {
        getElevationModel();
      }
      computeTileOverlapPercentage(x0, y0, w, h, tileOverlapPercentage);
      // System.out.println("x0 = " + x0 + ", y0 = " + y0 + ", w = " + w + ", h = " + h +
      //                   ", tileOverlapPercentageMin = " + tileOverlapPercentage[0] +
      //                   ", tileOverlapPercentageMax = " + tileOverlapPercentage[1]);
    } catch (Exception e) {
      throw new OperatorException(e);
    }

    final Tile latTile = targetTiles.get(targetProduct.getBand(LATITUDE_BAND_NAME));
    final Tile lonTile = targetTiles.get(targetProduct.getBand(LONGITUDE_BAND_NAME));
    final ProductData latData = latTile.getDataBuffer();
    final ProductData lonData = lonTile.getDataBuffer();
    final double[][] latArray = new double[h][w];
    final double[][] lonArray = new double[h][w];
    for (int r = 0; r < h; r++) {
      Arrays.fill(latArray[r], noDataValue);
      Arrays.fill(lonArray[r], noDataValue);
    }

    final int ymin = Math.max(y0 - (int) (tileSize * tileOverlapPercentage[1]), 0);
    final int ymax = y0 + h + (int) (tileSize * Math.abs(tileOverlapPercentage[0]));
    final int xmax = x0 + w;

    final PositionData posData = new PositionData();
    final GeoPos geoPos = new GeoPos();

    try {
      if (reGridMethod) {
        final double[] latLonMinMax = new double[4];
        computeImageGeoBoundary(x0, xmax, ymin, ymax, latLonMinMax);

        final double latMin = latLonMinMax[0];
        final double latMax = latLonMinMax[1];
        final double lonMin = latLonMinMax[2];
        final double lonMax = latLonMinMax[3];
        final int nLat = (int) ((latMax - latMin) / delLat) + 1;
        final int nLon = (int) ((lonMax - lonMin) / delLon) + 1;

        final double[][] tileDEM = new double[nLat + 1][nLon + 1];
        double alt;

        for (int i = 0; i < nLat; i++) {
          final double lat = latMin + i * delLat;
          for (int j = 0; j < nLon; j++) {
            double lon = lonMin + j * delLon;
            if (lon >= 180.0) {
              lon -= 360.0;
            }
            geoPos.setLocation(lat, lon);
            alt = dem.getElevation(geoPos);
            if (alt == demNoDataValue) {
              continue;
            }

            tileDEM[i][j] = alt;

            if (!getPosition(lat, lon, alt, x0, y0, w, h, posData)) {
              continue;
            }

            final int ri = (int) Math.round(posData.rangeIndex);
            final int ai = (int) Math.round(posData.azimuthIndex);
            if (ri < x0 || ri >= x0 + w || ai < y0 || ai >= y0 + h) {
              continue;
            }

            latArray[ai - y0][ri - x0] = lat;
            lonArray[ai - y0][ri - x0] = lon;
          }
        }

      } else {

        final double[][] localDEM = new double[ymax - ymin + 2][w + 2];
        final TileGeoreferencing tileGeoRef =
            new TileGeoreferencing(sourceProduct, x0, ymin, w, ymax - ymin);

        final boolean valid =
            DEMFactory.getLocalDEM(
                dem,
                demNoDataValue,
                demResamplingMethod,
                tileGeoRef,
                x0,
                ymin,
                w,
                ymax - ymin,
                sourceProduct,
                true,
                localDEM);

        if (!valid) {
          return;
        }

        for (int y = ymin; y < ymax; y++) {
          final int yy = y - ymin;

          for (int x = x0; x < xmax; x++) {
            final int xx = x - x0;
            double alt = localDEM[yy + 1][xx + 1];

            if (alt == demNoDataValue) {
              continue;
            }

            tileGeoRef.getGeoPos(x, y, geoPos);
            if (!geoPos.isValid()) {
              continue;
            }

            double lat = geoPos.lat;
            double lon = geoPos.lon;
            if (lon >= 180.0) {
              lon -= 360.0;
            }

            if (orbitMethod) {
              double[] latlon = jOrbit.lp2ell(new Point(x + 0.5, y + 0.5), meta);
              lat = latlon[0] * Constants.RTOD;
              lon = latlon[1] * Constants.RTOD;
              alt = dem.getElevation(new GeoPos(lat, lon));
            }

            if (!getPosition(lat, lon, alt, x0, y0, w, h, posData)) {
              continue;
            }

            final int ri = (int) Math.round(posData.rangeIndex);
            final int ai = (int) Math.round(posData.azimuthIndex);
            if (ri < x0 || ri >= x0 + w || ai < y0 || ai >= y0 + h) {
              continue;
            }

            latArray[ai - y0][ri - x0] = lat;
            lonArray[ai - y0][ri - x0] = lon;
          }
        }
      }

      // todo should replace the following code with Delaunay interpolation
      final TileIndex trgIndex = new TileIndex(latTile);
      for (int y = y0; y < y0 + h; y++) {
        final int yy = y - y0;
        trgIndex.calculateStride(y);
        for (int x = x0; x < x0 + w; x++) {
          final int xx = x - x0;
          final int index = trgIndex.getIndex(x);

          if (latArray[yy][xx] == noDataValue) {
            latData.setElemDoubleAt(index, fillHole(xx, yy, latArray));
          } else {
            latData.setElemDoubleAt(index, latArray[yy][xx]);
          }

          if (lonArray[yy][xx] == noDataValue) {
            lonData.setElemDoubleAt(index, fillHole(xx, yy, lonArray));
          } else {
            lonData.setElemDoubleAt(index, lonArray[yy][xx]);
          }
        }
      }

    } catch (Throwable e) {
      OperatorUtils.catchOperatorException(getId(), e);
    }
  }
Пример #2
0
  /**
   * Compute source image geodetic boundary (minimum/maximum latitude/longitude) from the its corner
   * latitude/longitude.
   *
   * @throws Exception The exceptions.
   */
  private void computeImageGeoBoundary(
      final int xmin, final int xmax, final int ymin, final int ymax, double[] latLonMinMax)
      throws Exception {

    final GeoCoding geoCoding = sourceProduct.getSceneGeoCoding();
    if (geoCoding == null) {
      throw new OperatorException("Product does not contain a geocoding");
    }
    final GeoPos geoPosFirstNear = geoCoding.getGeoPos(new PixelPos(xmin, ymin), null);
    final GeoPos geoPosFirstFar = geoCoding.getGeoPos(new PixelPos(xmax, ymin), null);
    final GeoPos geoPosLastNear = geoCoding.getGeoPos(new PixelPos(xmin, ymax), null);
    final GeoPos geoPosLastFar = geoCoding.getGeoPos(new PixelPos(xmax, ymax), null);

    final double[] lats = {
      geoPosFirstNear.getLat(),
      geoPosFirstFar.getLat(),
      geoPosLastNear.getLat(),
      geoPosLastFar.getLat()
    };
    final double[] lons = {
      geoPosFirstNear.getLon(),
      geoPosFirstFar.getLon(),
      geoPosLastNear.getLon(),
      geoPosLastFar.getLon()
    };
    double latMin = 90.0;
    double latMax = -90.0;
    for (double lat : lats) {
      if (lat < latMin) {
        latMin = lat;
      }
      if (lat > latMax) {
        latMax = lat;
      }
    }

    double lonMin = 180.0;
    double lonMax = -180.0;
    for (double lon : lons) {
      if (lon < lonMin) {
        lonMin = lon;
      }
      if (lon > lonMax) {
        lonMax = lon;
      }
    }

    latLonMinMax[0] = latMin;
    latLonMinMax[1] = latMax;
    latLonMinMax[2] = lonMin;
    latLonMinMax[3] = lonMax;
  }
Пример #3
0
  private void computeTileOverlapPercentage(
      final int x0, final int y0, final int w, final int h, double[] overlapPercentages)
      throws Exception {

    final PixelPos pixPos = new PixelPos();
    final GeoPos geoPos = new GeoPos();
    final PosVector earthPoint = new PosVector();
    final PosVector sensorPos = new PosVector();
    double tileOverlapPercentageMax = -Double.MAX_VALUE;
    double tileOverlapPercentageMin = Double.MAX_VALUE;
    for (int y = y0; y < y0 + h; y += 20) {
      for (int x = x0; x < x0 + w; x += 20) {
        pixPos.setLocation(x, y);
        sourceGeoCoding.getGeoPos(pixPos, geoPos);
        final double alt = dem.getElevation(geoPos);
        GeoUtils.geo2xyzWGS84(geoPos.getLat(), geoPos.getLon(), alt, earthPoint);

        final double zeroDopplerTime =
            SARGeocoding.getEarthPointZeroDopplerTime(
                firstLineUTC,
                lineTimeInterval,
                wavelength,
                earthPoint,
                orbit.sensorPosition,
                orbit.sensorVelocity);

        if (zeroDopplerTime == SARGeocoding.NonValidZeroDopplerTime) {
          continue;
        }

        final double slantRange =
            SARGeocoding.computeSlantRange(zeroDopplerTime, orbit, earthPoint, sensorPos);

        final double zeroDopplerTimeWithoutBias =
            zeroDopplerTime + slantRange / Constants.lightSpeedInMetersPerDay;

        final int azimuthIndex =
            (int) ((zeroDopplerTimeWithoutBias - firstLineUTC) / lineTimeInterval + 0.5);

        double tileOverlapPercentage = (double) (azimuthIndex - y) / (double) tileSize;

        if (tileOverlapPercentage > tileOverlapPercentageMax) {
          tileOverlapPercentageMax = tileOverlapPercentage;
        }
        if (tileOverlapPercentage < tileOverlapPercentageMin) {
          tileOverlapPercentageMin = tileOverlapPercentage;
        }
      }
    }

    if (tileOverlapPercentageMin != Double.MAX_VALUE && tileOverlapPercentageMin < 0.0) {
      overlapPercentages[0] = tileOverlapPercentageMin - 0.5;
    } else {
      overlapPercentages[0] = 0.0;
    }

    if (tileOverlapPercentageMax != -Double.MAX_VALUE && tileOverlapPercentageMax > 0.0) {
      overlapPercentages[1] = tileOverlapPercentageMax + 0.5;
    } else {
      overlapPercentages[1] = 0.0;
    }
  }