Revision 4447 trunk/extensions/extGeoProcessing/src/com/iver/gvsig/geoprocessing/impl/union/UnionGeoprocess.java

View differences:

UnionGeoprocess.java
45 45
*
46 46
* $Id$
47 47
* $Log$
48
* Revision 1.6  2006-03-14 18:32:46  fjp
48
* Revision 1.7  2006-03-15 18:34:41  azabala
49
* *** empty log message ***
50
*
51
* Revision 1.6  2006/03/14 18:32:46  fjp
49 52
* Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
50 53
*
51 54
* Revision 1.5  2006/03/07 21:01:33  azabala
......
72 75
import com.iver.cit.gvsig.fmap.DriverException;
73 76
import com.iver.cit.gvsig.fmap.core.IFeature;
74 77
import com.iver.cit.gvsig.fmap.core.IGeometry;
78
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
75 79
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
76
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
77 80
import com.iver.cit.gvsig.fmap.edition.EditionException;
78 81
import com.iver.cit.gvsig.fmap.layers.FBitSet;
79 82
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
83
import com.iver.cit.gvsig.fmap.operations.CancellableMonitorable;
84
import com.iver.cit.gvsig.fmap.operations.DefaultCancellableMonitorable;
80 85
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
81 86
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
82 87
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
83 88
import com.iver.gvsig.geoprocessing.impl.AbstractGeoprocess;
84 89
import com.iver.gvsig.geoprocessing.impl.difference.DifferenceVisitor;
85 90
import com.iver.gvsig.geoprocessing.impl.intersection.IntersectVisitor;
91
import com.iver.gvsig.geoprocessing.impl.jtsprocessors.DeferredFeaturePersisterProcessor;
86 92
import com.iver.gvsig.geoprocessing.impl.jtsprocessors.FeaturePersisterProcessor2;
87 93
import com.iver.gvsig.geoprocessing.model.GeoprocessException;
88 94
import com.iver.gvsig.geoprocessing.model.IOverlayGeoprocess;
89 95
import com.iver.gvsig.geoprocessing.schemabuilder.DefinitionUtils;
90 96
import com.iver.gvsig.geoprocessing.schemabuilder.XTypes;
97
import com.iver.utiles.swing.threads.IMonitorableTask;
91 98
/**
92 99
 * Union geoprocess is known like "spatial or" because is an overlay
93 100
 * geoprocess (it computes intersections between features of
94 101
 * two layers) formed for geometries of one layer or another.
95
 * To compute that, geoprocess do this:
96
 * for each feature of first layer.
97
 * 	does intersect with features of second layer?
98
 * if not, saves the feature.
99
 * if yes, compute intersections, save intersections, and
100
 * save difference of the original feature with intersections.
101
 * mark all features of second layer that intersect with feature.
102
 * We also mark in a new FBitSet all that feature of the second layer
103
 * that are completely within first layer bounding box.
104
 * 
105
 * Secondly, saves all features of second layer that arent marked
106
 * (they dont intersect with any feature of first layer)
107
 * 
108
 * At last, we do a new pass, processing all second layer features that 
109
 * are not completily within first layer bounding box, and we will save
110
 * its differences with intersections.
102
 * <br>
103
 *  Algorithm makes these three passes:
104
 *  a) computing intersections and saves them in a temp file.
105
 *  b) computing differences with first layer.
106
 *  c) computing differences with second layer.
111 107
 * @author azabala
112 108
 *
113 109
 *TODO Is very similar to ClipGeoprocess. Build an overlay abstract class.
114 110
 *
115 111
 *
116
 *TODO Revise algorithm (probably simpler is make three passes:
117
 *a) computing intersections and saves them in a temp file.
118
 *b) computing differences with first layer.
119
 *c) computing differences with second layer.
120
 *ES MUCHO MAS SIMPLE HACERLO DE ESTA OTRA MANERA
121
 *
122 112
 */
123 113
public class UnionGeoprocess extends AbstractGeoprocess 
124 114
							implements IOverlayGeoprocess {
......
275 265
		return null;
276 266
	}
277 267

  
268
	public IMonitorableTask createTask() {
269
		try {
270
			return new UnionMonitorableTask();
271
		} catch (DriverIOException e) {
272
			return null;
273
		}
274
	}
275
	
276
	/**
277
	 * IMonitorableTask that allows to run diff geoprocess in background,
278
	 * with cancelation requests.
279
	 * 
280
	 * @author azabala
281
	 * 
282
	 * FIXME INTERNACIONALIZAR TODOS LOS TEXTOS
283
	 * 
284
	 */
285
	class UnionMonitorableTask implements IMonitorableTask {
286
		private CancellableMonitorable cancelMonitor = null;
287

  
288
		// FIXME INTERNACIONALIZAR ESTO
289
		String FIRST_PASS_MESSAGE = "Computing intersections: ";
290
		String SECOND_PASS_MESSAGE = "Computing A-B difference:";
291
		String THIRD_PASS_MESSAGE = "Computing B-A difference:";
292
		
293
		String currentMessage = "";
294
		private boolean finished = false;
295

  
296
		UnionMonitorableTask() throws DriverIOException {
297
			initialize();
298
		}
299
		void initialize() throws DriverIOException {
300
			cancelMonitor = createCancelMonitor();
301
			currentMessage = "Initializing...";
302
		}
303

  
304
		private CancellableMonitorable createCancelMonitor()
305
				throws DriverIOException {
306
			DefaultCancellableMonitorable monitor = new 
307
							DefaultCancellableMonitorable();
308
			monitor.setInitialStep(0);
309
			monitor.setDeterminatedProcess(true);
310
			int numSteps = 0;
311
			//num steps = 2 * firstlayer (intersect + diff A-B)
312
			//+ second layer (diff B-A)
313
			if (onlyFirstLayerSelection) {
314
				FBitSet selection = firstLayer.getRecordset().getSelection();
315
				numSteps += (2 * selection.cardinality());
316
			} else {
317
				numSteps += 2 * firstLayer.getSource().getShapeCount();
318
			}
319
			if(onlyClipLayerSelection) {
320
				FBitSet selection = overlayLayer.getRecordset().getSelection();
321
				numSteps += (2 * selection.cardinality());
322
			}else{
323
				numSteps += 2 * overlayLayer.getSource().getShapeCount();
324
			}
325
			monitor.setFinalStep(numSteps);
326
			return monitor;
327
		}
328

  
329
		public int getInitialStep() {
330
			return cancelMonitor.getInitialStep();
331
		}
332

  
333
		public int getFinishStep() {
334
			return cancelMonitor.getFinalStep();
335
		}
336

  
337
		public int getCurrentStep() {
338
			return cancelMonitor.getCurrentStep();
339
		}
340

  
341
		public String getStatusMessage() {
342
			// FIXME Cambiar esto por un mecanismo de eventos,
343
			// de forma que la tarea lo que tenga sea un escuchador
344
			// que cambie el mensaje de estado segun los eventos
345
			// de tareas que se est?n realizando
346
			return "Union Geoprocess...";
347
		}
348

  
349
		public String getNote() {
350
			// FIXME Cambiar esto por un mecanismo de eventos,
351
			// de forma que la tarea lo que tenga sea un escuchador
352
			// que cambie el mensaje de estado segun los eventos
353
			// de tareas que se est?n realizando
354
			return currentMessage + getCurrentStep() + " of " + getFinishStep();
355
		}
356

  
357
		public void cancel() {
358
			((DefaultCancellableMonitorable) cancelMonitor).setCanceled(true);
359
		}
360

  
361
		public void run() throws GeoprocessException {
362

  
363
			try {
364
				//FIXME Esto lo tenemos que hacer FUERA (en la GUI)
365
				schemaManager.createOrAlterSchema(createLayerDefinition());
366
				writer.preProcess();
367
				
368
				Strategy strategy = StrategyManager.getStrategy(firstLayer);
369
				Strategy strategy2 = StrategyManager.getStrategy(overlayLayer);
370
				DeferredFeaturePersisterProcessor featureProcessor =
371
					new DeferredFeaturePersisterProcessor(writer);
372
				
373
				IntersectVisitor visitor = new IntersectVisitor(overlayLayer, 
374
															featureProcessor,
375
															strategy2, 
376
															onlyClipLayerSelection);
377
				//FIXME Meter las selecciones
378
				currentMessage = FIRST_PASS_MESSAGE;
379
				if(onlyFirstLayerSelection){
380
					FBitSet selection = firstLayer.getRecordset().getSelection();
381
					strategy.process(visitor, selection, cancelMonitor);
382
				}else{
383
					strategy.process(visitor, cancelMonitor);
384
				}
385
				
386
				currentMessage = SECOND_PASS_MESSAGE;
387
				DifferenceVisitor visitor2 = new DifferenceVisitor(overlayLayer,
388
						featureProcessor, strategy2, onlyClipLayerSelection);
389
				if(onlyFirstLayerSelection){
390
					FBitSet selection = firstLayer.getRecordset().getSelection();
391
					strategy.process(visitor2, selection, cancelMonitor);
392
				}else{
393
					strategy.process(visitor2, cancelMonitor);
394
				}
395
				currentMessage = THIRD_PASS_MESSAGE;
396
				DifferenceVisitor visitor3 = new DifferenceVisitor(firstLayer,
397
						featureProcessor, strategy, onlyFirstLayerSelection);
398
				if(onlyClipLayerSelection){
399
					FBitSet selection = overlayLayer.getRecordset().getSelection();
400
					strategy2.process(visitor3, selection, cancelMonitor);
401
				}else{
402
					strategy2.process(visitor3, cancelMonitor);
403
				}
404
				writer.postProcess();
405
				
406
			} catch (EditionException e) {
407
				throw new GeoprocessException("Error al crear el esquema/fichero de la nueva capa");
408
			} catch (DriverException e) {
409
				throw new GeoprocessException("Error de driver al calcular el geoproceso interseccion");
410
			} catch (VisitException e) {
411
				throw new GeoprocessException("Error al procesar el feature de una capa durante el geoproceso interseccion");
412
			} catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
413
				// TODO Auto-generated catch block
414
				e.printStackTrace();
415
			}finally{
416
				finished = true;
417
			}
418
		}
419

  
420
		public boolean isDefined() {
421
			return cancelMonitor.isDeterminatedProcess();
422
		}
423

  
424
		public boolean isCanceled() {
425
			return cancelMonitor.isCanceled();
426
		}
427

  
428
		public boolean isFinished() {
429
			return finished;
430
		}
431
	}
432

  
278 433
}
279 434

  

Also available in: Unified diff