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