Revision 4447 trunk/extensions/extGeoProcessing/src/com/iver/gvsig/geoprocessing/impl/union/UnionGeoprocess.java
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