gvsig-raster / org.gvsig.raster.principalcomponents / trunk / org.gvsig.raster.principalcomponents / org.gvsig.raster.principalcomponents.algorithm / src / main / java / org / gvsig / raster / principalcomponents / algorithm / PrincipalComponentsProcess.java @ 2125
History | View | Annotate | Download (7.98 KB)
1 |
package org.gvsig.raster.principalcomponents.algorithm; |
---|---|
2 |
|
3 |
import java.awt.geom.Point2D; |
4 |
import java.awt.geom.Rectangle2D; |
5 |
import java.util.List; |
6 |
|
7 |
import org.gvsig.fmap.dal.coverage.RasterLocator; |
8 |
import org.gvsig.fmap.dal.coverage.dataset.Buffer; |
9 |
import org.gvsig.fmap.dal.coverage.datastruct.Extent; |
10 |
import org.gvsig.fmap.dal.coverage.datastruct.NoData; |
11 |
import org.gvsig.fmap.dal.coverage.exception.CloneException; |
12 |
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException; |
13 |
import org.gvsig.fmap.dal.coverage.store.RasterDataStore; |
14 |
import org.gvsig.i18n.Messages; |
15 |
import org.gvsig.raster.algorithm.process.DataProcess; |
16 |
import org.gvsig.raster.algorithm.process.ProcessException; |
17 |
import org.gvsig.raster.roi.ROI; |
18 |
|
19 |
import Jama.Matrix; |
20 |
|
21 |
/**
|
22 |
* PCA Process
|
23 |
* @author Nacho Brodin (nachobrodin@gmail.com)
|
24 |
*/
|
25 |
public class PrincipalComponentsProcess extends DataProcess { |
26 |
public static String RASTER_STORE = "RASTER_STORE"; |
27 |
public static String PATH = "PATH"; |
28 |
public static String FILENAME = "FILENAME"; |
29 |
|
30 |
public static final String BUFFERS = "BUFFERS"; |
31 |
public static final String SELECTEDPCS = "SELECTEDPCS"; |
32 |
public static final String PCSTATISTICS = "PCSTATISTICS"; |
33 |
public static final String DATAROI = "DATAROI"; |
34 |
public static final String EXTENT = "EXTENT"; |
35 |
public static final String GRAPHIC_DATA = "GRAPHIC_DATA"; |
36 |
public static final String BANDS = "BANDS"; |
37 |
|
38 |
private RasterDataStore store = null; |
39 |
private String filename = null; |
40 |
|
41 |
private PCStatsDataStructure pcStatistics = null; |
42 |
private List<ROI> rois = null; |
43 |
private Extent extentResult = null; |
44 |
private boolean[] selectedPCs = null; |
45 |
private boolean[] bands = null; |
46 |
private int[] selectedBands = null; |
47 |
private NoData nodata = null; |
48 |
|
49 |
|
50 |
public static void registerParameters() { |
51 |
registerInputParameter(RASTER_STORE, RasterDataStore.class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL); |
52 |
registerInputParameter(PCSTATISTICS, PCStatsDataStructure.class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL); |
53 |
registerInputParameter(PATH, String.class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL);
|
54 |
registerInputParameter(DATAROI, List.class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL);
|
55 |
registerInputParameter(SELECTEDPCS, Boolean[].class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL); |
56 |
registerInputParameter(BANDS, Boolean[].class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL); |
57 |
|
58 |
registerOutputParameter(FILENAME, String.class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL);
|
59 |
registerOutputParameter(GRAPHIC_DATA, Double[].class, PrincipalComponentsAlgorithmLibrary.PC_PROCESS_LABEL); |
60 |
} |
61 |
|
62 |
@SuppressWarnings("unchecked") |
63 |
public void init() { |
64 |
store = getParam(RASTER_STORE) != null ? (RasterDataStore)getParam(RASTER_STORE) : null; |
65 |
filename = getStringParam(PATH); |
66 |
selectedPCs = (boolean[]) getParam(SELECTEDPCS); |
67 |
bands = (boolean[]) getParam(BANDS); |
68 |
pcStatistics = (PCStatsDataStructure) getParam(PCSTATISTICS); |
69 |
rois = getParam(DATAROI) != null ? (List<ROI>) getParam(DATAROI) : null; |
70 |
} |
71 |
|
72 |
|
73 |
/**
|
74 |
* Gets the bounding box of the source in pixel coordinates
|
75 |
* @param ext
|
76 |
* @return
|
77 |
*/
|
78 |
private Rectangle2D getSourcePxBox(Extent ext) { |
79 |
if(rois == null) |
80 |
return new Rectangle2D.Double(0, 0, store.getWidth(), store.getHeight()); |
81 |
Point2D p1 = store.worldToRaster(new Point2D.Double(ext.getULX(), ext.getULY())); |
82 |
Point2D p2 = store.worldToRaster(new Point2D.Double(ext.getLRX(), ext.getLRY())); |
83 |
return new Rectangle2D.Double(p1.getX(), p1.getY(), Math.abs(p2.getX() - p1.getX()), Math.abs(p2.getY() - p1.getY())); |
84 |
} |
85 |
|
86 |
public void process() throws ProcessInterruptedException, ProcessException { |
87 |
insertLineLog(Messages.getText("processing_pc"));
|
88 |
try {
|
89 |
if (store == null) |
90 |
throw new PrincipalComponentsException(Messages.getText("need_a_input")); |
91 |
|
92 |
try {
|
93 |
store = ((RasterDataStore)store).cloneDataStore(); |
94 |
} catch (CloneException e) {
|
95 |
new PrincipalComponentsException("Error cloning the input DataStore", e); |
96 |
} |
97 |
|
98 |
extentResult = getExtentResult(rois, store); |
99 |
Rectangle2D sourcePxBBox = getSourcePxBox(extentResult);
|
100 |
|
101 |
double cellSize = store.getCellSize();
|
102 |
|
103 |
nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, Buffer.TYPE_DOUBLE); |
104 |
double nodataValue = nodata.getValue().doubleValue();
|
105 |
|
106 |
int numberOfOutputBands = getNumberOfOutputBands(selectedPCs);
|
107 |
|
108 |
Buffer outputBuffer = createOutputBuffer((int)sourcePxBBox.getWidth(), (int)sourcePxBBox.getHeight(), numberOfOutputBands); |
109 |
Buffer sourceBuffer = createSourceBuffer(store, sourcePxBBox, bands);
|
110 |
|
111 |
// Matriz Autovectores
|
112 |
// Colocamos la matriz en el orden correcto:
|
113 |
/*
|
114 |
* b3 b2 b1 c1 c2 c3 | | | | Cambio de orden de columnas de la matriz
|
115 |
* transpuesta ___ \ / V c1 c2 c3 b1 b2 b3
|
116 |
*/
|
117 |
Matrix autovect = changeColumns((pcStatistics.getAutoVectorsMatrix().transpose())); |
118 |
insertLineLog(Messages.getText("writting_in_buffer"));
|
119 |
|
120 |
for (int i = 0; i < sourceBuffer.getHeight(); i++) { |
121 |
for (int j = 0; j < sourceBuffer.getWidth(); j++) { |
122 |
|
123 |
if (isInsideOfROI(j, i, rois, extentResult)) {
|
124 |
for (int iComponent = 0; iComponent < sourceBuffer.getBandCount(); iComponent++) { |
125 |
if(selectedPCs[iComponent]) {
|
126 |
double valor = 0; |
127 |
for (int iBand = 0; iBand < sourceBuffer.getBandCount(); iBand++) { |
128 |
valor += getData(sourceBuffer, i, j, iBand) * autovect.get(iBand, iComponent); |
129 |
} |
130 |
int indexBandResult = indexBandResult(selectedPCs, iComponent);
|
131 |
outputBuffer.setElem(i, j, indexBandResult, (double) valor);
|
132 |
} |
133 |
} |
134 |
|
135 |
} else {
|
136 |
for (int iBand = 0; iBand < outputBuffer.getBandCount(); iBand++) { |
137 |
outputBuffer.setElem(i, j, iBand, nodataValue); |
138 |
} |
139 |
} |
140 |
} |
141 |
updatePercent((int)(i * 100 / sourcePxBBox.getHeight()), 100); |
142 |
} |
143 |
|
144 |
super.exportRaster(filename,
|
145 |
outputBuffer, |
146 |
cellSize, |
147 |
extentResult.getULX(), |
148 |
extentResult.getULY(), |
149 |
nodata); |
150 |
|
151 |
addOutputValue(FILENAME, filename); |
152 |
addOutputValue(GRAPHIC_DATA, filename); |
153 |
} catch (PrincipalComponentsException e) {
|
154 |
if (incrementableTask != null) |
155 |
incrementableTask.processFinalize(); |
156 |
messageBoxError("...", null, e); |
157 |
} |
158 |
} |
159 |
|
160 |
|
161 |
/**
|
162 |
* Gets the number of the selected bands
|
163 |
* @param bandsPCs
|
164 |
* @return
|
165 |
*/
|
166 |
private int getNumberOfOutputBands(boolean[] b) { |
167 |
int bandCount = 0; |
168 |
for (int i = 0; i < b.length; i++) { |
169 |
if(b[i])
|
170 |
bandCount++; |
171 |
} |
172 |
return bandCount;
|
173 |
} |
174 |
|
175 |
/**
|
176 |
* Gets the band index of the result buffer
|
177 |
* @param bandsPCs
|
178 |
* @param indexIn
|
179 |
* @return
|
180 |
*/
|
181 |
private int indexBandResult(boolean[] bandsPCs, int indexIn) { |
182 |
if(selectedBands == null) { |
183 |
selectedBands = new int[bandsPCs.length]; |
184 |
int indexOut = 0; |
185 |
for (int i = 0; i < bandsPCs.length; i++) { |
186 |
if(bandsPCs[i]) {
|
187 |
selectedBands[i] = indexOut; |
188 |
indexOut++; |
189 |
} else
|
190 |
selectedBands[i] = -1;
|
191 |
} |
192 |
} |
193 |
return selectedBands[indexIn];
|
194 |
} |
195 |
|
196 |
public double getScaleFactor(Buffer buffer, int sizePreview) { |
197 |
double x = 0, y = 0; |
198 |
x = 200.0 / buffer.getWidth();
|
199 |
y = 200.0 / buffer.getHeight();
|
200 |
|
201 |
if (x > y) {
|
202 |
return y;
|
203 |
} else {
|
204 |
return x;
|
205 |
} |
206 |
} |
207 |
|
208 |
private Matrix changeColumns(Matrix m) {
|
209 |
Matrix result = new Matrix(m.getRowDimension(), m.getColumnDimension());
|
210 |
int k = m.getColumnDimension() - 1; |
211 |
for (int i = 0; i < m.getRowDimension(); i++) { |
212 |
for (int j = 0; j < m.getColumnDimension(); j++) { |
213 |
result.set(i, j, m.get(k - i, j)); |
214 |
} |
215 |
} |
216 |
return result;
|
217 |
} |
218 |
|
219 |
public String getTitle() { |
220 |
return Messages.getText("..."); |
221 |
} |
222 |
} |