jaitools.media.jai.zonalstats.ZonalStats Maven / Gradle / Ivy
Show all versions of jt-all Show documentation
/*
* Copyright 2009-2010 Michael Bedward
*
* This file is part of jai-tools.
*
* jai-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* jai-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with jai-tools. If not, see .
*
*/
package jaitools.media.jai.zonalstats;
import jaitools.CollectionFactory;
import jaitools.numeric.Range;
import jaitools.numeric.Statistic;
import jaitools.numeric.StreamingSampleStats;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
/**
* Holds the results of the ZonalStats operator.
* An instance of this class is stored as a property of the destination
* image.
*
* The result for each combination of data image band, zone image integer zone (if
* provided) and requested statistic is stored as a {@code Result} object.
* The most basic usage is to iterate through the results as follows...
*
* RenderedOp op = JAI.create("zonalstats", myParamBlock);
* ZonalStats allStats = (ZonalStats) op.getProperty(ZonalStatsDescriptor.ZONAL_STATS_PROPERTY);
* for (Result r : allStats.results()) {
* System.out.prinln(r);
* }
*
*
* Alternatively, the attributes of {@code Result} objects can be retrieved selectively...
*
* ZonalStats allStats = ...
* for (Result r : allStats.results()) {
* if (r.getStatistic() == Statistic.MEAN) {
* System.out.printf("%4d %4d %8.4f\n",
* r.getImageBand(), r.getZone(), r.getValue());
* }
* }
*
*
* For most uses it may be easier to use the chaining methods provided by {@code ZonalStats}
* to select the subset of results required...
*
* ZonalStats allStats = ...
*
* // Get results for a given band
* int bandIndex = ...
* List bandResults = allStats.band(bandIndex).results();
*
*
* // Get Statistic.MEAN values for the specified band and zone
* List subsetResults = allStats.band(b).zone(z).statistic(Statistic.MEAN).results();
*
*
* // Impress your friends with pretty printing !
* Statistic[] statistics = {
* Statistic.MIN,
* Statistic.MAX,
* Statistic.MEDIAN,
* Statistic.APPROX_MEDIAN,
* Statistic.SDEV
* };
*
* System.out.println(" exact approx");
* System.out.println(" band zone min max median median sdev");
* System.out.println("-----------------------------------------------------------");
*
* for (int b : allStats.getImageBands()) {
* for (int z : zs.getZones()) {
* System.out.printf(" %4d %4d", b, z);
* ZonalStats subset = zs.band(b).zone(z);
* for (Statistic s : statistics) {
* System.out.printf(" %8.4f", zoneSubset.statistic(s).results().get(0).getValue());
* }
* System.out.println();
* }
* }
*
*
*
* @see Result
* @see ZonalStatsDescriptor
*
* @author Michael Bedward
* @author Daniele Romagnoli, GeoSolutions S.A.S.
* @since 1.0
* @version $Id: ZonalStats.java 1383 2011-02-10 11:22:29Z michael.bedward $
*/
public class ZonalStats {
private List results;
/**
* Constructor. Package-private; called by ZonalStatsOpImage.
*/
ZonalStats() {
results = CollectionFactory.list();
}
/**
* Copy constructor. Used by the chaining methods such as {@linkplain #band(int)}.
*
* @param src source object
* @param band selected image band or {@code null} for all bands
* @param zone selected zone or {@code null} for all zones
* @param stat selected statistic or {@code null} for all statistics
* @param ranges selected ranges or {@code null} for all ranges
*/
private ZonalStats(ZonalStats src, Integer band, Integer zone, Statistic stat, List ranges) {
results = CollectionFactory.list();
for (Result r : src.results) {
if ((band == null || r.getImageBand() == band) &&
(zone == null || r.getZone() == zone) &&
(stat == null || r.getStatistic() == stat)) {
if (ranges == null || ranges.isEmpty()) {
results.add(r);
} else {
if (r.getRanges().containsAll(ranges)) {
results.add(r);
} else {
for (Range range : ranges) {
if (r.getRanges().contains(range)) {
results.add(r);
}
}
}
}
}
}
}
/**
* Store the results for the given zone. Package-private method used by
* {@code ZonalStatsOpImage}.
*/
void setResults(int band, int zone, StreamingSampleStats stats, List includedRanges) {
for (Statistic s : stats.getStatistics()) {
Result r = new Result(band, zone, s, includedRanges,
stats.getStatisticValue(s),
stats.getNumOffered(s),
stats.getNumAccepted(s),
stats.getNumNaN(s),
stats.getNumNoData(s));
results.add(r);
}
}
/**
* Store the results for the given zone. Package-private method used by
* {@code ZonalStatsOpImage}.
*/
void setResults(int band, int zone, StreamingSampleStats stats) {
setResults(band, zone, stats, null);
}
/**
* Get the integer IDs read from the zone image. If a zone image
* was not used all results are treated as being in zone 0.
*
* Note that statistics will not necessarily have been calculated for
* all zones.
*
* @return the sorted zone IDs
*/
public SortedSet getZones() {
SortedSet ids = CollectionFactory.sortedSet();
for (Result r : results) {
ids.add(r.getZone());
}
return ids;
}
/**
* Get the subset of results for the given band.
*
* See the example of chaining this method in the class docs.
*
* @param b band index
*
* @return a new {@code ZonalStats} object containing results for the band
* (data are shared with the source object rather than copied)
*/
public ZonalStats band(int b) {
return new ZonalStats(this, b, null, null, null);
}
/**
* Get the subset of results for the given zone.
*
* See the example of chaining this method in the class docs.
*
* @param z zone ID
*
* @return a new {@code ZonalStats} object containing results for the zone
* (data are shared with the source object rather than copied)
*/
public ZonalStats zone(int z) {
return new ZonalStats(this, null, z, null, null);
}
/**
* Get the subset of results for the given {@code Statistic}.
*
* See the example of chaining this method in the class docs.
*
* @param s the statistic
*
* @return a new {@code ZonalStats} object containing results for the statistic
* (data are shared with the source object rather than copied)
*/
public ZonalStats statistic(Statistic s) {
return new ZonalStats(this, null, null, s, null);
}
/**
* Get the subset of results for the given {@code Ranges}.
*
* @param ranges the Ranges
*
* @return a new {@code ZonalStats} object containing results for the ranges
* (data are shared with the source object rather than copied)
*/
public ZonalStats ranges(List ranges) {
return new ZonalStats(this, null, null, null, ranges);
}
/**
* Returns the list of {@code Result} objects.
*
* @return the results
* @see Result
*/
public List results() {
return Collections.unmodifiableList(results);
}
}