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