예제 #1
0
  /**
   * Perform decomposition for given tile.
   *
   * @param targetBand The target band.
   * @param targetTile The current tile associated with the target band to be computed.
   * @throws OperatorException If an error occurs during computation of the filtered value.
   */
  public void computeTile(final Band targetBand, final Tile targetTile) {
    PolBandUtils.PolSourceBand srcBandList = bandMap.get(targetBand);

    if (!clusterCentersComputed) {
      computeTerrainClusterCenters(srcBandList, op);
    }

    final Rectangle targetRectangle = targetTile.getRectangle();
    final int x0 = targetRectangle.x;
    final int y0 = targetRectangle.y;
    final int w = targetRectangle.width;
    final int h = targetRectangle.height;
    final int maxY = y0 + h;
    final int maxX = x0 + w;
    final ProductData targetData = targetTile.getDataBuffer();
    final TileIndex trgIndex = new TileIndex(targetTile);
    // System.out.println("x0 = " + x0 + ", y0 = " + y0 + ", w = " + w + ", h = " + h);

    for (int y = y0; y < maxY; ++y) {
      trgIndex.calculateStride(y);
      for (int x = x0; x < maxX; ++x) {
        targetData.setElemIntAt(trgIndex.getIndex(x), getOutputClusterIndex(x, y));
      }
    }
  }
예제 #2
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);
    }
  }