Revision 2100 org.gvsig.raster.principalcomponents/trunk/org.gvsig.raster.principalcomponents/org.gvsig.raster.principalcomponents.algorithm/src/main/java/org/gvsig/raster/principalcomponents/algorithm/PrincipalComponentsProcess.java

View differences:

PrincipalComponentsProcess.java
1 1
package org.gvsig.raster.principalcomponents.algorithm;
2 2

  
3
import java.awt.geom.AffineTransform;
4 3
import java.awt.geom.Point2D;
4
import java.awt.geom.Rectangle2D;
5 5

  
6
import org.cresques.cts.IProjection;
7
import org.gvsig.fmap.dal.coverage.RasterLibrary;
8 6
import org.gvsig.fmap.dal.coverage.RasterLocator;
9 7
import org.gvsig.fmap.dal.coverage.RasterManager;
10 8
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
9
import org.gvsig.fmap.dal.coverage.dataset.BufferParam;
11 10
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
12 11
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
12
import org.gvsig.fmap.dal.coverage.exception.BufferCreationException;
13 13
import org.gvsig.fmap.dal.coverage.exception.CloneException;
14 14
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
15 15
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
16 16
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
17 17
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
18 18
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
19
import org.gvsig.fmap.dal.exception.CloseException;
20
import org.gvsig.fmap.dal.exception.DataException;
21
import org.gvsig.fmap.geom.primitive.Envelope;
22
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
23 19
import org.gvsig.i18n.Messages;
24 20
import org.gvsig.raster.algorithm.process.DataProcess;
21
import org.gvsig.raster.algorithm.process.ProcessException;
25 22
import org.gvsig.raster.fmap.roi.VectorialROI;
26 23

  
27 24
import Jama.Matrix;
28 25

  
29 26
/**
30 27
 * PCA Process 
28
 * @author Nacho Brodin (nachobrodin@gmail.com)
31 29
 */
32 30
public class PrincipalComponentsProcess extends DataProcess {
33 31
	public static String         RASTER_STORE        = "RasterStore";
......
45 43
	private String                filename           = null;
46 44
	
47 45
	private PCStatsDataStructure  pcStatistics       = null;
48
	private Object[]              dataROI            = null;
46
	private VectorialROI[]        dataROI            = null;
49 47
	private Extent                extentResult       = null;
50 48
	private boolean[]             selectedPCs        = null;
49
	private int[]                 selectedBands      = null;
50
	private NoData                nodata             = null;
51 51
	
52
	
52 53
	public static void registerParameters() {
53 54
		registerInputParameter(RASTER_STORE, RasterDataStore.class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
54
		registerInputParameter(RASTER_STORE, RasterDataStore.class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
55
		registerInputParameter(PCSTATISTICS, PCStatsDataStructure.class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
55 56
		registerInputParameter(PATH, String.class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
57
		registerInputParameter(DATAROI, VectorialROI[].class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
56 58
		registerOutputParameter(FILENAME, String.class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
57 59
		registerOutputParameter(GRAPHIC_DATA, Double[].class, PrincipalComponentsAlgorithmLibrary.PROCESS_LABEL);
58 60
	}
......
62 64
		filename = getStringParam(PATH);
63 65
		selectedPCs = (boolean[]) getParam(SELECTEDPCS);
64 66
		pcStatistics = (PCStatsDataStructure) getParam(PCSTATISTICS);
65
		extentResult = (Extent) getParam(EXTENT);
66
		dataROI = (Object[]) getParam(DATAROI);
67
		dataROI = (VectorialROI[]) getParam(DATAROI);
67 68
	}
68 69
	
69
	public Extent getExtentResult() {
70
	/**
71
	 * Gets the bounding box taking into account if there are ROIs or not
72
	 * @return
73
	 */
74
	private Extent getExtentResult() {
70 75
		if(dataROI == null)
71 76
			return store.getExtent();
72 77
		else {
73
			Extent ext = RasterLocator.getManager().getDataStructFactory().createExtent();
74
			
78
			Extent maxExtent = null;
79
			for (int i = 0; i < dataROI.length; i++) {
80
				if(i == 0)
81
					maxExtent = dataROI[i].getExtent();
82
				else
83
					maxExtent = maxExtent.encloseBoundinBoxes(dataROI[i].getExtent());
84
			}
85
			return maxExtent;
75 86
		}
76 87
	}
88
	
89
	/**
90
	 * Gets the bounding box of the source in pixel coordinates
91
	 * @param ext
92
	 * @return
93
	 */
94
	private Rectangle2D getSourcePxBox(Extent ext) {
95
		if(dataROI == null)
96
			return new Rectangle2D.Double(0, 0, store.getWidth(), store.getHeight());
97
		Point2D p1 = store.worldToRaster(new Point2D.Double(ext.getULX(), ext.getULY()));
98
		Point2D p2 = store.worldToRaster(new Point2D.Double(ext.getLRX(), ext.getLRY()));
99
		return new Rectangle2D.Double(p1.getX(), p1.getY(), Math.abs(p2.getX() - p1.getX()), Math.abs(p2.getY() - p1.getY()));
100
	}
77 101

  
78
	public void process() throws ProcessInterruptedException {
79
		RasterManager rManager = RasterLocator.getManager();
80
		
102
	public void process() throws ProcessInterruptedException, ProcessException {
81 103
		insertLineLog(Messages.getText("..."));
82 104
		try {
83 105
			if (store == null)
84
				throw new PrincipalComponentsException("...");
106
				throw new PrincipalComponentsException(Messages.getText("need_a_input"));
85 107
			
86
			store = ((RasterDataStore)store).cloneDataStore();
108
			try {
109
				store = ((RasterDataStore)store).cloneDataStore();
110
			} catch (CloneException e) {
111
				new PrincipalComponentsException("Error cloning the input DataStore", e);
112
			}
87 113
			
88
			VectorialROI vectROI = (VectorialROI) dataROI[0];
89
			int shiftX = (Integer) dataROI[1];
90
			int shiftY = (Integer) dataROI[2];
114
			extentResult = getExtentResult();
115
			Rectangle2D sourcePxBBox = getSourcePxBox(extentResult);
91 116
			
92 117
			double cellSize = store.getCellSize();
93
			IProjection proj = store.getProjection();
94
			AffineTransform at = getAffineTransform(store, extentResult);
95 118
			
96
			int widthResult = (int) Math.round(extentResult.width() / cellSize);
97
			int heightResult = (int) Math.round(extentResult.height() / cellSize);
98
			widthResult = adjustToImageWidth(widthResult);
99
			heightResult = adjustToImageHeight(heightResult);
119
			nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, Buffer.TYPE_DOUBLE);
120
			double nodataValue = nodata.getValue().doubleValue();
100 121
			
101
			NoData nd = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, Buffer.TYPE_DOUBLE);
102
			double nodata = nd.getValue().doubleValue();
122
			int bandCount = getNumberOfSelectedBands(selectedPCs);
103 123
			
104
			int numbandas = 0;
105
			for (int i = 0; i < selectedPCs.length; i++)
106
				if (selectedPCs[i])
107
					numbandas++;
124
			Buffer outputBuffer = createOutputBuffer(sourcePxBBox, bandCount);
125
			Buffer sourceBuffer = createSourceBuffer(sourcePxBBox, selectedPCs);
108 126
			
109
			Buffer bufferResult = rManager.createBuffer(Buffer.TYPE_DOUBLE,
110
					(int)store.getWidth(), (int)store.getHeight(), numbandas, true);
111
			
112 127
			// Matriz Autovectores
113 128
			// Colocamos la matriz en el orden correcto:
114 129
			/*
115 130
			 * b3 b2 b1 c1 c2 c3 | | | | Cambio de orden de columnas de la matriz
116 131
			 * transpuesta ___ \ / V c1 c2 c3 b1 b2 b3
117 132
			 */
118
			Matrix autovect = ChangeColumns((pcStatistics.getAutoVectorsMatrix().transpose()));
133
			Matrix autovect = changeColumns((pcStatistics.getAutoVectorsMatrix().transpose()));
134
			insertLineLog(Messages.getText("writting_in_buffer"));
119 135
			
120
			int numPoints = numPointsDataEstadistics();
121
			int contador = 0;
122
			int sizebuffer = (int)(store.getWidth() * store.getHeight());
123
			int numGraphicData = 0;// contador para los datos de la grafica
124
			Object[] graphicsData = new Object[numbandas];
125
			for (int i = 0; i < graphicsData.length; i++) {
126
				graphicsData[i] = new double[numPoints];
127
			}
128
			insertLineLog("Escribiendo en buffer");
129
			
130
			double valor = 0;
131
			// BUFFER TYPE DOUBLE
132
			int indexbandresult = 0;
133
			// i = Fila de buffer
134
			for (int i = 0; i < store.getHeight(); i++) {
135
				for (int j = 0; j < store.getWidth(); j++) {
136
					contador++;
136
			for (int i = 0; i < sourcePxBBox.getHeight(); i++) {
137
				for (int j = 0; j < sourcePxBBox.getWidth(); j++) {
137 138

  
138
					// Si el elemento es nodata asignamos no data en todas las
139
					// bandas de la imagen resultante
140
					if ((vectROI == null)
141
							|| (vectROI.isInGrid(j + shiftX, i + shiftY))) {
142
						// c = numero de componente
143
						for (int c = 0; c < selectedPCs.length; c++) {
144
							// Si el componente esta seleccionado
145
							if (selectedPCs[c]) {
146
								// k = numero de banda (necesitamos todas) (Filas de
147
								// matriz
148
								// autovect)
149
								for (int k = 0; k < store.getBandCount(); k++) {
150
									b = buffers[k];
151
									valor += getData(b, i, j, 0)
152
											* autovect.get(k, c);
139
					if (isInsideOfROI(j, i)) {
140
						for (int iComponent = 0; iComponent < sourceBuffer.getBandCount(); iComponent++) {
141
							if(selectedPCs[iComponent]) {
142
								double valor = 0;
143
								for (int iBand = 0; iBand < sourceBuffer.getBandCount(); iBand++) {
144
									valor += getData(sourceBuffer, i, j, iBand) * autovect.get(iBand, iComponent);
153 145
								}
154
								bufferResult.setElem(i, j, indexbandresult,
155
										(double) valor);
156

  
157
								if ((contador % ((sizebuffer / numPointsDataEstadistics()) + 1) == 0)) {
158
									double[] d = (double[]) graphicsData[indexbandresult];
159
									d[numGraphicData] = valor;
160
								}
161
								indexbandresult++;
162
								valor = 0;
163

  
146
								int indexBandResult = indexBandResult(selectedPCs, iComponent);
147
								outputBuffer.setElem(i, j, indexBandResult, (double) valor);
164 148
							}
165 149
						}
166
						if ((contador % ((sizebuffer / numPointsDataEstadistics()) + 1) == 0)) {
167
							numGraphicData++;
168
						}
169

  
170
						indexbandresult = 0;
150
						
171 151
					} else {
172
						for (int nb = 0; nb < numbandas; nb++) {
173
							bufferResult.setElem(i, j, nb, nodata);
152
						for (int iBand = 0; iBand < outputBuffer.getBandCount(); iBand++) {
153
							outputBuffer.setElem(i, j, iBand, nodataValue);
174 154
						}
175

  
176
						valor = 0;
177
						indexbandresult = 0;
178 155
					}
179 156
				}
180 157
				updatePercent((int)(i * 100 / store.getHeight()), 100);
181 158
			}
182 159
			
183
			//////////////////////////
184
			//TODO:PROCESS!!
185
			
186
			//updatePercent(row, buf.getHeight());
187
			
188
			/*if(export) {
189 160
			super.exportRaster(filename, 
190
					buf, 
161
					outputBuffer, 
191 162
					cellSize, 
192
					windowExtent.getULX(), 
193
					windowExtent.getULY());
194
			}*/
163
					extentResult.getULX(), 
164
					extentResult.getULY());
195 165
			
196 166
			addOutputValue(FILENAME, filename);
197
			addOutputValue(FILENAME, filename);
167
			addOutputValue(GRAPHIC_DATA, filename);
198 168
		} catch (PrincipalComponentsException e) {
199 169
			if (incrementableTask != null)
200 170
				incrementableTask.processFinalize();
201
			messageBoxError("...", this, e);
171
			messageBoxError("...", null, e);
202 172
		}
203 173
	}
204 174
	
205 175
	/**
176
	 * Checks if the point in pixel coordinates is inside the region of 
177
	 * interest or not
178
	 * @param x
179
	 * @param y
180
	 * @return
181
	 */
182
	private boolean isInsideOfROI(int x, int y) {
183
		if(dataROI == null)
184
			return true;
185
		for (int i = 0; i < dataROI.length; i++) {
186
			if(dataROI[i].isInGrid(x, y))
187
				return true;
188
		}
189
		return false;
190
	}
191
	
192
	/**
193
	 * Gets the number of the selected bands
194
	 * @param bandsPCs
195
	 * @return
196
	 */
197
	private int getNumberOfSelectedBands(boolean[] bandsPCs) {
198
		int bandCount = 0;
199
        for (int i = 0; i < bandsPCs.length; i++) {
200
			if(bandsPCs[i])
201
				bandCount++;
202
		}
203
        return bandCount;
204
	}
205
	
206
	/**
207
	 * Gets the band index of the result buffer 
208
	 * @param bandsPCs
209
	 * @param indexIn
210
	 * @return
211
	 */
212
	private int indexBandResult(boolean[] bandsPCs, int indexIn) {
213
		if(selectedBands == null) {
214
			selectedBands = new int[bandsPCs.length];
215
			int indexOut = 0;
216
			for (int i = 0; i < bandsPCs.length; i++) {
217
				if(bandsPCs[i]) {
218
					selectedBands[i] = indexOut;
219
					indexOut++;
220
				} else
221
					selectedBands[i] = -1;
222
			}
223
		}
224
		return selectedBands[indexIn];
225
	}
226
	
227
	/**
228
	 * Builds the output buffer
229
	 * @param sourcePxBBox
230
	 * @param bandCount
231
	 * @return
232
	 */
233
	private Buffer createOutputBuffer(Rectangle2D sourcePxBBox, int bandCount) {
234
		RasterManager rManager = RasterLocator.getManager();
235
		BufferParam bParams = rManager.getBufferFactory().createBufferParams(
236
				(int)sourcePxBBox.getWidth(), 
237
				(int)sourcePxBBox.getHeight(), 
238
				bandCount, 
239
				Buffer.TYPE_DOUBLE, 
240
				true);
241
		Buffer resultBuffer = null;
242
		try {
243
			resultBuffer = rManager.getBufferFactory().createBuffer(bParams);
244
		} catch (BufferCreationException e) {
245
			new ProcessException("Error creating the output buffer", e);
246
		}
247
		return resultBuffer;
248
	}
249
	
250
	/**
206 251
	 * Gets a buffer of a raster 
207 252
     */
208
    private Buffer prepareBufferImage(int index, Point2D shift, int w, int h) throws RasterDriverException, InvalidSetViewException, CloneException, CloseException {
253
    private Buffer createSourceBuffer(Rectangle2D sourcePxBBox, boolean[] bandsPCs) throws PrincipalComponentsException {
209 254
        RasterManager rManager = RasterLocator.getManager();
210 255
        RasterQuery query = rManager.createQuery();
211 256
        query.setReadOnly(true);
257
        
212 258
        query.setAllDrawableBands();
213
        query.setAreaOfInterest((int)shift.getX(), (int)shift.getY(), w, h);
259
        query.setAreaOfInterest(
260
        		(int)sourcePxBBox.getX(), 
261
        		(int)sourcePxBBox.getY(), 
262
        		(int)sourcePxBBox.getWidth(), 
263
        		(int)sourcePxBBox.getHeight());
214 264

  
215
        Buffer buffer;
216 265
        try {
217
            buffer = store.query(query);
218
            return buffer;
266
        	Buffer buffer = null;
267
        	try {
268
        		buffer = store.query(query);
269
        	} catch (RasterDriverException e) {
270
        		new PrincipalComponentsException("Error creating the input buffer", e);
271
        	}  catch (InvalidSetViewException e) {
272
        		new PrincipalComponentsException("Error creating the input buffer", e);
273
        	} 
274
        	return buffer;
219 275
        } catch (ProcessInterruptedException e) {
220 276
        	logger.error("Error al crear buffer de escritura.");
221 277
        }
222 278
        return null;
223 279
    }   
224
	
225
	private AffineTransform getAffineTransform(RasterDataStore im, Extent extentResult) {
226
		AffineTransform at = new AffineTransform(im.getAffineTransform()
227
				.getScaleX(), im.getAffineTransform().getShearY(), im
228
				.getAffineTransform().getShearX(), im.getAffineTransform()
229
				.getScaleY(), extentResult.getULX(), extentResult.getULY());
230 280

  
231
		return at;
232
	}
233
	
234
	/**
235
	 * Devuelve el Extent de la zona de estudio en coordenadas pixel
236
	 * 
237
	 * @param zoneLayer
238
	 * @return
239
	 * @throws DataException
240
	 **/
241
	private Point2D getPointWorldXminYmaxExactPixel(FLyrVect zoneLayer)
242
			throws DataException {
243
		Envelope env = zoneLayer.getFullEnvelope();
244
		Point2D pointXMinYMax = new Point2D.Double(env.getMinimum(0),
245
				env.getMaximum(1));
246
		Point2D pointxminymax = new Point2D.Double(
247
				(int)store.worldToRaster(pointXMinYMax).getX(), 
248
				(int)store.worldToRaster(pointXMinYMax).getY());
249
		Point2D pointXminMaxExactPixel = new Point2D.Double(
250
				(int)store.rasterToWorld(pointxminymax).getX(),
251
				(int)store.rasterToWorld(pointxminymax).getY());
281
	private double getData(Buffer b, int j, int i, int band) {
282
		double val = 0;
252 283

  
253
		return pointXminMaxExactPixel;
284
		if (b.getDataType() == Buffer.TYPE_BYTE) {
285
			val = (double) b.getElemByte(j, i, band);
286
			return val;
287
		}
288
		if (b.getDataType() == Buffer.TYPE_DOUBLE) {
289
			val = (double) b.getElemDouble(j, i, band);
290
			return val;
291
		}
292
		if (b.getDataType() == Buffer.TYPE_FLOAT) {
293
			val = (double) b.getElemFloat(j, i, band);
294
			return val;
295
		}
296
		if (b.getDataType() == Buffer.TYPE_INT) {
297
			val = (double) b.getElemInt(j, i, band);
298
			return val;
299
		}
300
		if (b.getDataType() == Buffer.TYPE_SHORT) {
301
			val = (double) b.getElemShort(j, i, band);
302
			return val;
303
		}
304
		return nodata.getValue().doubleValue();
254 305
	}
255 306
	
256
	private int adjustToImageWidth(int withResult) {
257
		double min = store.getWidth();//Math.min(Math.min(image.getPxWidth(), image.getPxWidth()),
258
				//Math.min(image.getPxWidth(), image.getPxWidth()));
259
		return (int)(Math.min(min, withResult));
260
	}
261

  
262
	private int adjustToImageHeight(int heightResult) {
263
		double min = store.getHeight();//Math.min(Math.min(image.getPxHeight(), image.getPxHeight()),
264
				//Math.min(image.getPxHeight(), image.getPxHeight()));
265
		return (int)(Math.min(min, heightResult));
266
	}
267
	
268
	/**
269
	 * Devuelve el numero de puntos que tendra el set de puntos de la grafica
270
	 * 
271
	 * @param buffer
272
	 * @return
273
	 **/
274
	public int numPointsDataEstadistics() {
275
		if ((store.getWidth()) * (store.getHeight()) < 50000)
276
			return (int)(store.getWidth() * store.getHeight());
277
		else
278
			return 50000;
279
	}
280

  
281 307
	public double getScaleFactor(Buffer buffer, int sizePreview) {
282 308
		double x = 0, y = 0;
283 309
		x = 200.0 / buffer.getWidth();
......
290 316
		}
291 317
	}
292 318
	
293
	private Matrix ChangeColumns(Matrix m) {
319
	private Matrix changeColumns(Matrix m) {
294 320
		Matrix result = new Matrix(m.getRowDimension(), m.getColumnDimension());
295 321
		int k = m.getColumnDimension() - 1;
296 322
		for (int i = 0; i < m.getRowDimension(); i++) {

Also available in: Unified diff