svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.buffer.impl / src / main / java / org / gvsig / raster / lib / buffer / impl / statistics / DefaultHistogramBand.java @ 44831
History | View | Annotate | Download (7.92 KB)
1 |
package org.gvsig.raster.lib.buffer.impl.statistics; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
import java.util.Collections; |
5 |
import java.util.Iterator; |
6 |
import java.util.List; |
7 |
|
8 |
import org.gvsig.raster.lib.buffer.api.Band; |
9 |
import org.gvsig.raster.lib.buffer.api.BufferManager; |
10 |
import org.gvsig.raster.lib.buffer.api.statistics.HistogramBand; |
11 |
import org.gvsig.raster.lib.buffer.api.statistics.HistogramClass; |
12 |
|
13 |
|
14 |
/**
|
15 |
* @author fdiaz
|
16 |
*
|
17 |
*/
|
18 |
public class DefaultHistogramBand implements HistogramBand { |
19 |
|
20 |
Band band; |
21 |
List<HistogramClass> histogramClasses;
|
22 |
|
23 |
|
24 |
public DefaultHistogramBand(Band band){
|
25 |
this.band=band;
|
26 |
this.histogramClasses=new ArrayList<HistogramClass>(); |
27 |
} |
28 |
|
29 |
public DefaultHistogramBand(Band band, List<HistogramClass> histogramClasses){ |
30 |
this.band=band;
|
31 |
this.histogramClasses=histogramClasses;
|
32 |
Collections.sort(this.histogramClasses); |
33 |
} |
34 |
|
35 |
@Override
|
36 |
public long getNumValues() { |
37 |
long count = 0; |
38 |
for (Iterator iterator = histogramClasses.iterator(); iterator.hasNext();) { |
39 |
HistogramClass histogramClass = (HistogramClass) iterator.next(); |
40 |
count += histogramClass.getValue(); |
41 |
} |
42 |
|
43 |
return count;
|
44 |
} |
45 |
|
46 |
@Override
|
47 |
public int getDataType() { |
48 |
return this.band.getDataType(); |
49 |
} |
50 |
|
51 |
@Override
|
52 |
public long getHistogramValue(double value) { |
53 |
HistogramClass histogramClass=getHistogramClass(value); |
54 |
if (histogramClass==null){ |
55 |
return 0; |
56 |
}else{
|
57 |
return histogramClass.getValue();
|
58 |
} |
59 |
} |
60 |
|
61 |
private HistogramClass getHistogramClass(double value){ |
62 |
for (HistogramClass histogramClass: histogramClasses){
|
63 |
if (histogramClass.isIn(value)){
|
64 |
return histogramClass;
|
65 |
} |
66 |
} |
67 |
|
68 |
if(histogramClasses.size() == 0){ |
69 |
return null; |
70 |
} |
71 |
|
72 |
HistogramClass lastHistogramClass = histogramClasses.get(histogramClasses.size()-1);
|
73 |
if(lastHistogramClass.getMax() == value){
|
74 |
return lastHistogramClass;
|
75 |
} |
76 |
|
77 |
return null; |
78 |
} |
79 |
|
80 |
@Override
|
81 |
public boolean union(HistogramBand hist) { |
82 |
//First we must check that histograms are compatible
|
83 |
if (this.getNumClasses()==hist.getNumClasses()){ |
84 |
for (int i=0; i<histogramClasses.size(); i++){ |
85 |
if ( this.getIntervalMin(i)!=hist.getIntervalMin(i) || |
86 |
this.getIntervalMax(i)!=hist.getIntervalMax(i)){
|
87 |
return false; |
88 |
} |
89 |
} |
90 |
}else{
|
91 |
return false; |
92 |
} |
93 |
//Once checked compatibility, values are added
|
94 |
for (int i=0; i<histogramClasses.size(); i++){ |
95 |
histogramClasses.get(i).increment(hist.getValueCount(i)); |
96 |
} |
97 |
return true; |
98 |
} |
99 |
|
100 |
@Override
|
101 |
public long[] getFrequencies() { |
102 |
|
103 |
Integer dataType = getDataType();
|
104 |
|
105 |
int size;
|
106 |
int rangeMin;
|
107 |
int rangeMax;
|
108 |
switch (dataType) {
|
109 |
case BufferManager.TYPE_BYTE:
|
110 |
rangeMin = 0;
|
111 |
rangeMax = 255;
|
112 |
size = 256;
|
113 |
break;
|
114 |
case BufferManager.TYPE_SHORT:
|
115 |
rangeMin = Short.MIN_VALUE;
|
116 |
rangeMax = Short.MAX_VALUE;
|
117 |
size = rangeMax-rangeMin+1;
|
118 |
break;
|
119 |
case BufferManager.TYPE_USHORT:
|
120 |
rangeMin = 0;
|
121 |
rangeMax = Math.abs(Short.MIN_VALUE) + Short.MAX_VALUE; |
122 |
size = rangeMax-rangeMin+1;
|
123 |
break;
|
124 |
case BufferManager.TYPE_INT:
|
125 |
rangeMin = Integer.MIN_VALUE;
|
126 |
rangeMax = Integer.MAX_VALUE;
|
127 |
size = rangeMax-rangeMin+1;
|
128 |
break;
|
129 |
default:
|
130 |
throw new IllegalArgumentException("Can't process type '" + dataType + "'"); |
131 |
} |
132 |
long[] table = new long[size]; |
133 |
for (int j = 0; j < table.length; j++) { |
134 |
table[j] = getHistogramValue(j); |
135 |
} |
136 |
return table;
|
137 |
|
138 |
} |
139 |
|
140 |
@Override
|
141 |
public int getNumClasses() { |
142 |
return histogramClasses.size();
|
143 |
} |
144 |
|
145 |
@Override
|
146 |
public long getValueCount(int interval) { |
147 |
return histogramClasses.get(interval).getValue();
|
148 |
} |
149 |
|
150 |
@Override
|
151 |
public double getIntervalMin(int interval) { |
152 |
return histogramClasses.get(interval).getMin();
|
153 |
} |
154 |
|
155 |
@Override
|
156 |
public double getIntervalMax(int interval) { |
157 |
return histogramClasses.get(interval).getMax();
|
158 |
} |
159 |
|
160 |
@Override
|
161 |
public double getMedian() { |
162 |
double halfn=(getNumValues())/2d; |
163 |
return getUmpteenth(halfn);
|
164 |
} |
165 |
|
166 |
/**
|
167 |
* Obtiene el en?simo valor
|
168 |
* @param n
|
169 |
* @return
|
170 |
*/
|
171 |
private double getUmpteenth(double n) { |
172 |
long contValues = 0; |
173 |
|
174 |
if (this.getDataType() == BufferManager.TYPE_FLOAT |
175 |
|| this.getDataType() == BufferManager.TYPE_DOUBLE) { // Valores no |
176 |
// discretos
|
177 |
|
178 |
for (int i = 0; i < histogramClasses.size(); i++) { |
179 |
HistogramClass histogramClass = histogramClasses.get(i); |
180 |
long anteriorCont = contValues;
|
181 |
if (n == contValues) {
|
182 |
return histogramClass.getMin();
|
183 |
} |
184 |
contValues += histogramClass.getValue(); |
185 |
if (n == contValues) {
|
186 |
return histogramClass.getMax();
|
187 |
} |
188 |
if (n < contValues) {
|
189 |
double median;
|
190 |
|
191 |
double nM = n; // getBandLenght() / 2; |
192 |
double nA = anteriorCont;
|
193 |
double fI = histogramClass.getValue();
|
194 |
double interval = histogramClass.getMax() - histogramClass.getMin();
|
195 |
double min = histogramClass.getMin();
|
196 |
|
197 |
median = min + ((nM - nA) / fI) * interval; |
198 |
return median;
|
199 |
} |
200 |
} |
201 |
|
202 |
} else { // Valores discretos |
203 |
double antMax = Double.NEGATIVE_INFINITY; |
204 |
|
205 |
for (int i = 0; i < histogramClasses.size(); i++) { |
206 |
HistogramClass histogramClass = histogramClasses.get(i); |
207 |
|
208 |
if (n == contValues) {
|
209 |
return (histogramClass.getMin() + antMax) / 2; |
210 |
} |
211 |
|
212 |
contValues += histogramClass.getValue(); |
213 |
|
214 |
if (n < contValues) {
|
215 |
|
216 |
return histogramClass.getMin();
|
217 |
} |
218 |
antMax = histogramClass.getMax(); |
219 |
} |
220 |
|
221 |
} |
222 |
return 0; |
223 |
} |
224 |
|
225 |
/**
|
226 |
* Adds value to histogram
|
227 |
*
|
228 |
* @param value
|
229 |
*/
|
230 |
public void addValue(double value){ |
231 |
HistogramClass histogramClass = getHistogramClass(value); |
232 |
if(histogramClass == null){ |
233 |
histogramClass = new DefaultHistogramClass(value, value);
|
234 |
histogramClass.setValue(1);
|
235 |
histogramClasses.add(histogramClass); |
236 |
// So that the list is always sorted
|
237 |
Collections.sort(histogramClasses);
|
238 |
} else {
|
239 |
histogramClass.increment(1);
|
240 |
} |
241 |
} |
242 |
|
243 |
@Override
|
244 |
public double[] getTailTrimValue(double percent) { |
245 |
if(percent>100 || percent <0){ |
246 |
StringBuilder builder = new StringBuilder(); |
247 |
builder.append("Percent ");
|
248 |
builder.append(percent); |
249 |
builder.append(" is out of range [0,100]");
|
250 |
throw new IllegalArgumentException(builder.toString()); |
251 |
} |
252 |
long lowPosition = Math.round(getNumValues()*percent/100); |
253 |
long upperPosition = Math.round(getNumValues()*(100-percent)/100); |
254 |
|
255 |
double[] result = new double[2]; |
256 |
|
257 |
result[0] = getUmpteenth(lowPosition);
|
258 |
result[1] = getUmpteenth(upperPosition);
|
259 |
return result;
|
260 |
} |
261 |
|
262 |
@Override
|
263 |
public double[] getTailTrimValue(int pos) { |
264 |
long lowPosition = pos;
|
265 |
long upperPosition = getNumValues()-pos;
|
266 |
|
267 |
double[] result = new double[2]; |
268 |
|
269 |
result[0] = getUmpteenth(lowPosition);
|
270 |
result[1] = getUmpteenth(upperPosition);
|
271 |
return result;
|
272 |
} |
273 |
|
274 |
|
275 |
|
276 |
} |