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 @ 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
}