Statistics
| Revision:

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
}