Revision 10626 trunk/extensions/extGeoProcessing/src/com/iver/cit/gvsig/geoprocess/impl/dissolve/fmap/FeatureDissolver.java

View differences:

FeatureDissolver.java
45 45
 *
46 46
 * $Id$
47 47
 * $Log$
48
 * Revision 1.3  2006-08-11 16:27:46  azabala
48
 * Revision 1.4  2007-03-06 16:47:58  caballero
49
 * Exceptions
50
 *
51
 * Revision 1.3  2006/08/11 16:27:46  azabala
49 52
 * *** empty log message ***
50 53
 *
51 54
 * Revision 1.2  2006/07/27 17:21:06  azabala
......
75 78

  
76 79
import org.cresques.cts.ICoordTrans;
77 80

  
78
import com.iver.cit.gvsig.fmap.DriverException;
81
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
82
import com.hardcode.gdbms.engine.data.driver.DriverException;
83
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
84
import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException;
85
import com.iver.cit.gvsig.exceptions.visitors.StartVisitorException;
86
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
87
import com.iver.cit.gvsig.exceptions.visitors.StopVisitorException;
88
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
79 89
import com.iver.cit.gvsig.fmap.core.IFeature;
80 90
import com.iver.cit.gvsig.fmap.core.IGeometry;
81 91
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
82 92
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
83
import com.iver.cit.gvsig.fmap.edition.EditionException;
84 93
import com.iver.cit.gvsig.fmap.layers.FBitSet;
85 94
import com.iver.cit.gvsig.fmap.layers.FLayer;
86 95
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
......
91 100
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
92 101
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
93 102
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
94
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
95 103
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureProcessor;
96 104
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
97 105
import com.iver.utiles.swing.threads.Cancellable;
......
105 113
 * Dissolve features in base of a given dissolve criteria.
106 114
 * </p>
107 115
 * By 'dissolving' we understand the union of the geometry of many features
108
 * 
116
 *
109 117
 * @author azabala
110
 * 
118
 *
111 119
 */
112 120
public class FeatureDissolver {
113 121

  
......
121 129
	 * Fetches attributes of disolved layer features
122 130
	 */
123 131
	protected SelectableDataSource recordset;
124
	
132

  
125 133
	protected ICoordTrans ct;
126 134

  
127 135
	/**
......
133 141
	/**
134 142
	 * It marks all features that have already been dissolved (to avoid process
135 143
	 * them in subsecuent steps)
136
	 * 
144
	 *
137 145
	 */
138 146
	protected FBitSet dissolvedGeometries;
139 147

  
......
160 168
	protected IDissolveCriteria dissolveCriteria;
161 169

  
162 170
	/**
163
	 * 
171
	 *
164 172
	 * @param processor
165 173
	 * @param layer
166 174
	 * @throws GeoprocessException
......
181 189
				recordset = ((AlphanumericData) layer).getRecordset();
182 190
				ct = dissolvedLayer.getCoordTrans();
183 191
				featureProcessor.start();
184
			} catch (com.iver.cit.gvsig.fmap.DriverException e) {
192
			} catch (ReadDriverException e) {
185 193
				throw new GeoprocessException(
186 194
						"Error al acceder al recordset de la capa "
187 195
								+ layer.getName(), e);
188
			} catch (EditionException e) {
196
			} catch (StartVisitorException e) {
189 197
				throw new GeoprocessException(
190 198
						"Error al preparar donde se van a escribir los resultados del dissolve de la capa "
191 199
								+ layer.getName(), e);
......
217 225
					this.featureProcessor.finish();
218 226
					return;
219 227
				}
220
				
228

  
221 229
				//Ver si podemos optimizar esto de forma que solo
222 230
				//se procesasen los elementos no marcados en el bitset
223 231
				//(bitset de acceso aleatorio)
224
				
232

  
225 233
				if (!dissolvedGeometries.get(i)) {
226 234
					// if we havent processed this element yet
227 235
					try {
......
229 237
							process( i, va, cancel);
230 238
						else if(dissolveType == ALPHANUMERIC_DISSOLVE)
231 239
							processAlphanumeric(i, va, cancel);
232
					} catch (DriverException e) {
240
					} catch (ReadDriverException e) {
233 241
						throw new GeoprocessException(
234 242
								"Error accediendo a datos durante dissolve", e);
235
					} catch (VisitException e) {
243
					} catch (ProcessVisitorException e) {
236 244
						throw new GeoprocessException(
237 245
								"Error procesando datos durante dissolve", e);
238
					} catch (IOException e) {
246
					} catch (ExpansionFileReadException e) {
239 247
						throw new GeoprocessException(
240
								"Error de I/O durante dissolve", e);
248
								"Error accediendo a datos durante dissolve", e);
249
					} catch (VisitorException e) {
250
						throw new GeoprocessException(
251
								"Error accediendo a datos durante dissolve", e);
241 252
					}
242 253
				}// if
243 254
			}// for
244 255
			va.stop();
245 256
			this.featureProcessor.finish();
246
		} catch (DriverIOException e) {
257
		} catch (ReadDriverException e) {
258
			// TODO Auto-generated catch block
247 259
			e.printStackTrace();
260
		} catch (StopVisitorException e) {
261
			// TODO Auto-generated catch block
262
			e.printStackTrace();
248 263
		}
249 264
	}
250 265

  
251 266
	/**
252 267
	 * Verifies cancelation events, and return a boolean flag if processes must
253 268
	 * be stopped for this cancelations events.
254
	 * 
269
	 *
255 270
	 * @param cancel
256 271
	 * @param va
257 272
	 * @param visitor
......
272 287
	}
273 288

  
274 289
	class DissolveVisitor implements FeatureVisitor {
275
		
290

  
276 291
		IDissolveCriteria criteria;
277 292
		int index1;
278 293
		Stack stack;
......
293 308
			this.cancel = cancel;
294 309
		}
295 310

  
296
		public void visit(IGeometry g, int index2) throws VisitException {
311
		public void visit(IGeometry g, int index2) throws VisitorException, ProcessVisitorException {
297 312
			if(g == null)
298 313
				return;
299 314
			if (verifyCancelation(cancel, va)) {
......
302 317
				featureProcessor.finish();
303 318
				return;
304 319
			}
305
			
320

  
306 321
			if(index1 == index2){
307 322
				//we dont want dissolve a feature with itself
308 323
				return;
......
320 335
					stack.push(new Integer(index2));
321 336
				try {
322 337
					if(criteria instanceof ISpatialDissolveCriteria){
323
						//Para ver el criterio de disolucion ya se ha 
338
						//Para ver el criterio de disolucion ya se ha
324 339
						//leido la geometria
325 340
						geometries.add(
326 341
								((ISpatialDissolveCriteria)criteria).
......
332 347
						geometries.add(g2.toJTSGeometry());
333 348
					}
334 349
					sumarizer.applySumarizeFunction(index2);
335
				} catch (DriverIOException e) {
336
					throw new VisitException(
337
							"Error durante lectura de geometria en dissolve", e);
338
				} catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
339
					throw new VisitException(
340
							"Error durante lectura de geometria en dissolve", e);
350
				} catch (ReadDriverException e) {
351
					throw new ProcessVisitorException(recordset.getName(),e,
352
							"Error durante lectura de geometria en dissolve");
353
				} catch (ExpansionFileReadException e) {
354
					throw new ProcessVisitorException(recordset.getName(),e,
355
						"Error durante lectura de geometria en dissolve");
341 356
				}
342 357
				//Esto se debe hacer externamente
343 358
				if(stack == null)
......
349 364
			return "";
350 365
		}
351 366

  
352
		public void stop(FLayer layer) {
367
		public void stop(FLayer layer) throws VisitorException {
353 368
		}
354 369

  
355
		public boolean start(FLayer layer) {
370
		public boolean start(FLayer layer) throws StartVisitorException {
356 371
			return true;
357 372
		}
358 373
	}
359
	
374

  
360 375
	/**
361 376
	 * @param index1
362 377
	 * @param va
363 378
	 * @param cancel
364 379
	 * @throws DriverException
365
	 * @throws VisitException
380
	 * @throws ExpansionFileReadException
381
	 * @throws ReadDriverException
382
	 * @throws VisitorException
383
	 * @throws ProcessWriterException
366 384
	 * @throws IOException
367 385
	 * @throws DriverIOException
368 386
	 */
369 387
	public void processAlphanumeric(int index1,
370
							ReadableVectorial va, 
388
							ReadableVectorial va,
371 389
							CancellableMonitorable cancel)
372
							throws DriverException, VisitException, IOException,
373
							DriverIOException{ 
374
		
390
							throws ReadDriverException, ExpansionFileReadException, VisitorException{
391

  
375 392
		dissolvedGeometries.set(index1);
376 393
		Strategy strategy = StrategyManager.getStrategy(dissolvedLayer);
377 394
		ArrayList geometries = new ArrayList();
......
397 414
		if(sumarizedValues != null || sumarizedValues.size() != 0){
398 415
			dissolvedFeature =  dissolveCriteria.
399 416
							getFeatureBuilder().
400
							createFeature(newGeometry, 
401
										sumarizedValues, 
402
												fid, 
417
							createFeature(newGeometry,
418
										sumarizedValues,
419
												fid,
403 420
												index1);
404 421
		}else{
405 422
			dissolvedFeature = dissolveCriteria.
406 423
								getFeatureBuilder().
407 424
								createFeature(newGeometry,
408
										index1, 
425
										index1,
409 426
										fid);
410 427
		}
411 428
		fid++;
412 429
		featureProcessor.processFeature(dissolvedFeature);
413 430
		dissolveCriteria.clear();
414 431
	}
415
	
416
	
432

  
433

  
417 434
	class SpatialDissolveVisitor implements FeatureVisitor {
418
		
435

  
419 436
		IDissolveCriteria criteria;
420 437
		Geometry geom1;
421 438
		StackEntry entry1;
......
425 442
		FunctionSummarizer sumarizer;
426 443
		CancellableMonitorable cancel;
427 444

  
428
		SpatialDissolveVisitor(IDissolveCriteria criteria, Geometry geo1, StackEntry entry1, 
445
		SpatialDissolveVisitor(IDissolveCriteria criteria, Geometry geo1, StackEntry entry1,
429 446
				Stack stack,
430 447
				List geometries, ReadableVectorial va,
431 448
				FunctionSummarizer sumarizer, CancellableMonitorable cancel) {
......
438 455
			this.sumarizer = sumarizer;
439 456
			this.cancel = cancel;
440 457
		}
441
		
458

  
442 459
		void setSeed(StackEntry entry, Geometry jtsGeo){
443 460
			this.entry1 = entry;
444 461
			this.geom1 = jtsGeo;
445 462
		}
446
		
447
		
448 463

  
449
		public void visit(IGeometry g, int index2) throws VisitException {
464

  
465

  
466
		public void visit(IGeometry g, int index2) throws VisitorException, ProcessVisitorException {
450 467
			if(g == null)
451 468
				return;
452 469
			if (verifyCancelation(cancel, va)) {
......
455 472
				featureProcessor.finish();
456 473
				return;
457 474
			}
458
			
475

  
459 476
			if(entry1.index == index2){
460 477
				//we dont want dissolve a feature with itself
461 478
				return;
......
483 500
					geometries.add(g.toJTSGeometry());
484 501
				try {
485 502
					sumarizer.applySumarizeFunction(index2);
486
				} catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
487
					throw new VisitException("Error al aplicar la funcion de sumarizacion en dissolve", e);
503
				} catch (ReadDriverException e) {
504
					throw new ProcessVisitorException(recordset.getName(),e,"Error al aplicar la funcion de sumarizacion en dissolve");
488 505
				}
489 506
				dissolvedGeometries.set(index2);
490 507
			}
......
494 511
			return "";
495 512
		}
496 513

  
497
		public void stop(FLayer layer) {
514
		public void stop(FLayer layer) throws VisitorException {
498 515
		}
499 516

  
500
		public boolean start(FLayer layer) {
517
		public boolean start(FLayer layer) throws StartVisitorException {
501 518
			return true;
502 519
		}
503 520
	}
504
	
521

  
505 522
	class StackEntry{
506 523
		public IGeometry g;
507 524
		public int index;
......
510 527
	 * Processes the given feature looking for features to dissolve with. The
511 528
	 * criteria to decide if dissolve two features is given by
512 529
	 * IDissolveCriteria.
513
	 * 
530
	 *
514 531
	 * @param criteria
515 532
	 *            decides if dissolve two features
516 533
	 * @param index1
......
519 536
	 *            it reads geometry of features
520 537
	 * @param cancel
521 538
	 *            listen cancelations
522
	 * @throws VisitException
539
	 * @throws ExpansionFileReadException
540
	 * @throws ReadDriverException
541
	 * @throws VisitorException
542
	 * @throws ProcessWriterException
523 543
	 * @throws DriverException
524 544
	 * @throws IOException
525 545
	 * @throws DriverIOException
526 546
	 */
527 547
	public void process(int index1,
528
			ReadableVectorial va, 
548
			ReadableVectorial va,
529 549
			CancellableMonitorable cancel)
530
			throws DriverException, VisitException, IOException,
531
			DriverIOException {
532
		
550
			throws ReadDriverException, ExpansionFileReadException, VisitorException {
551

  
533 552
		if(dissolvedGeometries.get(index1))
534 553
			return;
535
		Strategy strategy = StrategyManager.getStrategy(dissolvedLayer);	
554
		Strategy strategy = StrategyManager.getStrategy(dissolvedLayer);
536 555
		IGeometry g1 = va.getShape(index1);
537 556
		if(g1 == null)
538 557
			return;
......
544 563
		Stack stack = new Stack();//it saves FMap geometries
545 564
		stack.push(entry);
546 565
		ArrayList geometries = new ArrayList();
547
		
566

  
548 567
		Geometry jtsGeo = g1.toJTSGeometry();
549 568
		geometries.add(jtsGeo);//it saves jts geometries
550
		
569

  
551 570
		if(dissolveCriteria instanceof ISpatialDissolveCriteria){
552 571
			((ISpatialDissolveCriteria)dissolveCriteria).setCoordTrans(ct);
553 572
			((ISpatialDissolveCriteria)dissolveCriteria).setFirstGeometry(g1);
554 573
		}
555 574
		FunctionSummarizer sumarizer = new FunctionSummarizer(
556 575
				numericField_sumarizeFunction, recordset);
557
		SpatialDissolveVisitor visitor = new SpatialDissolveVisitor(dissolveCriteria, 
558
																			jtsGeo, 
559
																			entry, 
576
		SpatialDissolveVisitor visitor = new SpatialDissolveVisitor(dissolveCriteria,
577
																			jtsGeo,
578
																			entry,
560 579
																			stack,
561
																			geometries, 
562
																			va, 
563
																			sumarizer, 
580
																			geometries,
581
																			va,
582
																			sumarizer,
564 583
																			cancel);
565
		
584

  
566 585
		while (stack.size() != 0) {
567 586
			dumpStack(stack);
568 587
			StackEntry sEntry = (StackEntry) stack.pop();
569 588
			dissolvedGeometries.set(sEntry.index);
570
	
589

  
571 590
			/*//TODO
572 591
			 * Revisar si no deberiamos hacer
573 592
			 * ct.getInverted().convert(rect);
574
			 * 
593
			 *
575 594
			 * */
576 595
			Rectangle2D rect = sEntry.g.getBounds2D();
577 596
			if(ct != null)
......
587 606
			visitor.setSeed(sEntry, jts);
588 607
			strategy.process(visitor, query);
589 608
		}// while
590
		
591
		
609

  
610

  
592 611
		IGeometry newGeometry = FConverter.jts_to_igeometry(union2(geometries));
593 612
		List sumarizedValues = sumarizer.getValues();
594 613
		IFeature dissolvedFeature = null;
595 614
		if(sumarizedValues != null || sumarizedValues.size() != 0){
596 615
			dissolvedFeature =  dissolveCriteria.
597 616
								getFeatureBuilder().
598
								createFeature(newGeometry, 
599
											sumarizedValues, 
600
													fid, 
617
								createFeature(newGeometry,
618
											sumarizedValues,
619
													fid,
601 620
													index1);
602 621
		}else{
603 622
			dissolvedFeature = dissolveCriteria.
604 623
								getFeatureBuilder().
605 624
								createFeature(newGeometry,
606
										index1, 
625
										index1,
607 626
										fid);
608 627
		}
609 628
		fid++;
......
621 640

  
622 641
	/**
623 642
	 * Returns the union of all geometries of the list
624
	 * 
643
	 *
625 644
	 * @param geometries
626 645
	 * @return
627 646
	 */
628
	protected Geometry union(List geometries) {	
647
	protected Geometry union(List geometries) {
629 648
		Geometry union = null;
630 649
		GeometryFactory fact = ((Geometry)geometries.
631 650
									get(0)).getFactory();
......
636 655
				union = g;
637 656
			else{
638 657
				Geometry[] geomArray = {union, g};
639
				GeometryCollection gCol = 
658
				GeometryCollection gCol =
640 659
					fact.
641 660
					createGeometryCollection(geomArray);
642 661
				union = gCol.buffer(0d);
643
			}	
662
			}
644 663
		}
645 664
		return union;
646 665
	}
647
	
666

  
648 667
	protected Geometry union3(List geometries) {
649
		long t0 = System.currentTimeMillis();		
668
		long t0 = System.currentTimeMillis();
650 669
				Geometry union = null;
651 670
				Iterator geomIt = geometries.iterator();
652 671
				while(geomIt.hasNext()){
......
655 674
						union = g;
656 675
					else{
657 676
						union = union.union(g);
658
					}	
677
					}
659 678
				}
660 679
		long t1 = System.currentTimeMillis();
661 680
		System.out.println((t1-t0)+ " en procesar union 3");
662 681
				return union;
663 682
			}
664
	
665
	protected Geometry union2(List geometries){		
683

  
684
	protected Geometry union2(List geometries){
666 685
			Geometry union = null;
667 686
			Geometry[] geom = new Geometry[geometries.size()];
668 687
			geometries.toArray(geom);
......
672 691
		    union = geomColl.buffer(0);
673 692
//		    System.out.println(union.toText());
674 693
		    return union;
675
		
694

  
676 695
	}
677 696
}

Also available in: Unified diff