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