Геоинструменты: общая площадь, где GridCoverage имеет значение x

Я работаю в Geotools с Java. Пока у меня есть GridCoverage2D и список геометрий. GridCoverage2D — это цифровая модель высот, полученная из геотиффа. Все работает нормально до сих пор.

Теперь я хочу получить площадь для каждого полигона, где высота имеет определенное значение. Например, для этой геометрии я хочу знать общую площадь, где высота составляет 27 м. Как я могу этого добиться?

Я понятия не имею, как начать :(

Я имею в виду два варианта:

  • Разделение геометрии на мелкие части (как это сделать), для каждой точки получить центральную точку (я могу это сделать), а затем оценить этот GridCoverage2D. Таким образом, у меня есть список с очень маленькими геометриями и высотой, соответствующей каждой геометрии. Некоторая магия массива — это все, что нужно дальше. Хороший ли это план, и как мне быстро разделить геометрию на мелкие части?
  • Использование фильтра/запроса. Тем не менее, я не знаю, как это работает, и учебник не помогает. Можно ли вообще добиться того, чего я хочу, с помощью фильтра?

person jeanke    schedule 04.01.2015    source источник


Ответы (2)


Это оказалось сложнее, чем я ожидал, что, вероятно, означает, что я упустил что-то очевидное. Вы можете решить этот вопрос, создав гистограмму покрытия, а затем выбрав ячейку, содержащую ваше значение. Все, что вам нужно сделать, это умножить общее количество ячеек на площадь ячейки.

Итак, если вы прочитали или создали репортаж:

 private double selectCells(GridCoverage2D cov, int value) {
    GridGeometry2D geom = cov.getGridGeometry();
    // cov.show();
    final OperationJAI op = new OperationJAI("Histogram");
    ParameterValueGroup params = op.getParameters();
    GridCoverage2D coverage;
    params.parameter("Source").setValue(cov);
    coverage = (GridCoverage2D) op.doOperation(params, null);
    javax.media.jai.Histogram hist = (Histogram) coverage
            .getProperty("histogram");

    int total = hist.getSubTotal(0, value, value);
    double area = calcAreaOfCell(geom);
    Unit<?> unit = cov.getCoordinateReferenceSystem().getCoordinateSystem()
            .getAxis(0).getUnit();
    System.out.println("which gives " + (area * total) + " " + unit
            + "^2 area with value " + value);
    return area * total;
}

private double calcAreaOfCell(GridGeometry2D geom) {
    GridEnvelope gridRange = geom.getGridRange();
    int width = gridRange.getHigh(0) - gridRange.getLow(0) + 1; // allow for the
    int height = gridRange.getHigh(1) - gridRange.getLow(1) + 1;// 0th row/col
    Envelope envelope = geom.getEnvelope();
    double dWidth = envelope.getMaximum(0) - envelope.getMinimum(0);
    double dHeight = envelope.getMaximum(1) - envelope.getMinimum(1);
    double cellWidth = dWidth / width;
    double cellHeight = dHeight / height;

    return cellWidth * cellHeight;
}

Очевидно, что если вы планируете вызывать его более одного раза, вы можете кэшировать гистограмму и размер ячейки.

person Ian Turton    schedule 05.01.2015
comment
Вы, сэр, настоящий герой! - person jeanke; 06.01.2015

Чао, еще один вариант — использовать зональную статистику или, что еще лучше, процесс.

Операция является частью модуля покрытия:

https://github.com/geotools/geotools/blob/12.x/modules/library/coverage/src/main/java/org/geotools/coverage/processing/operation/ZonalStats.java https://github.com/geotools/geotools/blob/12.x/modules/library/coverage/src/test/java/org/geotools/coverage/processing/ZonalStasTest.java

Процесс находится в неподдерживаемом растре процесса: https://github.com/geotools/geotools/blob/12.x/modules/unsupported/process-raster/src/main/java/org/geotools/process/raster/RasterZonalStatistics.java https://github.com/geotools/geotools/blob/12.x/modules/unsupported/process-raster/src/test/java/org/geotools/process/raster/ZonalStatsProcessTest.java

Надеюсь, это поможет.

person simogeo    schedule 16.01.2015