Revision 897

View differences:

org.gvsig.geoprocess/trunk/org.gvsig.geoprocess/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyAlgorithm.java
74 74
			Sextante.addErrorToLog(e);
75 75
		}
76 76
	}
77
	
77

  
78 78
	public void setParentProcess(AbstractSextanteGeoProcess process) {
79 79
		this.process = process;
80 80
	}
81
	
81

  
82 82
	/*
83 83
	 * (non-Javadoc)
84 84
	 * @see es.unex.sextante.core.GeoAlgorithm#processAlgorithm()
85 85
	 */
86
	@SuppressWarnings("unchecked")
87 86
	public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
88 87
		if(existsOutPutFile(DissolveAlgorithm.RESULT, 0)) {
89 88
    		throw new GeoAlgorithmExecutionException(getTranslation("file_exists"));
90 89
    	}
91 90
		IVectorLayer layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
92 91
		boolean selectedGeom = m_Parameters.getParameterValueAsBoolean(SELECTED_GEOM);
93
		
92

  
94 93
		FeatureStore storeLayer = null;
95 94
		if(layer instanceof FlyrVectIVectorLayer)
96 95
			storeLayer = ((FlyrVectIVectorLayer)layer).getFeatureStore();
97 96
		else
98 97
			return false;
99
		
98

  
100 99
		try {
101 100
			String[] attrNames = new String[]{"FID"};
102 101
			Class[] types = new Class[] {Integer.class};
103 102

  
104 103
			FeatureStore outFeatStore = buildFuseSpatiallyOutPutStore(attrNames, types,
105 104
					layer.getShapeType(), getTranslation("fusespatially"), RESULT);
106
			
105

  
107 106
			return execute(storeLayer, outFeatStore, layer.getShapeType(), selectedGeom, getStatus(), "FID", true);
108 107
		} catch (DataException e) {
109 108
			Sextante.addErrorToLog(e);
110 109
			return false;
111 110
		}
112 111
	}
113
	
114
	public boolean execute(FeatureStore inputStoreLayer, 
112

  
113
	/**
114
	 * @param inputStoreLayer
115
	 * @param outFeatStore
116
	 * @param shapeType
117
	 * @param selectedGeom
118
	 * @param status
119
	 * @param idField
120
	 * @param createTable
121
	 * @return boolean
122
	 * @throws DataException
123
	 */
124
	public boolean execute(FeatureStore inputStoreLayer,
115 125
			FeatureStore outFeatStore,
116
			int shapeType, 
117
			boolean selectedGeom, 
118
			SimpleTaskStatus status, 
126
			int shapeType,
127
			boolean selectedGeom,
128
			SimpleTaskStatus status,
119 129
			String idField,
120 130
			boolean createTable) throws DataException {
121 131
		FeatureStore outFeatStoreTable = null;
......
130 140
				attrNamesTable[i + 1] = attrDesc.getName();
131 141
				typesTable[i + 1] = attrDesc.getDataType().getDefaultClass();
132 142
			}
133
			
143

  
134 144
			attrNamesTable = checkFields(attrNamesTable);
135 145
			outFeatStoreTable = buildFuseSpatiallyOutPutStore(attrNamesTable, typesTable,
136 146
				shapeType, getTranslation("fusespatially") + "_Table", RESULT_TABLE);
......
138 148

  
139 149
		FuseSpatiallyOperationFast2 operation = new FuseSpatiallyOperationFast2(this);
140 150
		operation.setTaskStatus(getStatus());
141
		operation.computesGeometryOperation(inputStoreLayer, 
142
				outFeatStore, 
151
		operation.computesGeometryOperation(inputStoreLayer,
152
				outFeatStore,
143 153
				outFeatStoreTable,
144
				new String[]{fid}, 
154
				new String[]{fid},
145 155
				attrNamesTable,
146 156
				selectedGeom,
147 157
				false,
148 158
				idField);
149
		
159

  
150 160
		if(getTaskMonitor().isCanceled())
151 161
			return false;
152
		/*computesGeometryOperation(inputStoreLayer, outFeatStore, outFeatStoreTable, 
162
		/*computesGeometryOperation(inputStoreLayer, outFeatStore, outFeatStoreTable,
153 163
				attrNames, attrNamesTable, selectedGeom, status, idField);*/
154 164
		return true;
155 165
	}
156
	
166

  
157 167
	/**
158 168
	 * Removes duplicate fields
159 169
	 * @param names
......
175 185
		}
176 186
		return names;
177 187
	}
178
	
179
	
188

  
189

  
180 190
	/**
181 191
	 * Computes a complete operation over the input FeatureStore. The result of this operation
182 192
	 * is stored in the output FeatureStore. This method will call once for each geometry.
......
208 218
		} else {
209 219
			featuresSet = inFeatStore.getFeatureSet();
210 220
		}
211
		
221

  
212 222
		it = featuresSet.iterator();
213 223
		int numberOfFeatures = (int)featuresSet.getSize();
214 224
        if (status != null) {
215 225
            status.setRangeOfValues(0, numberOfFeatures);
216 226
        }
217
		
227

  
218 228
        //Stack<Feature> featList = new Stack<Feature>();
219 229
        List<Feature> featList = new ArrayList<Feature>();
220 230
		while( it.hasNext() ) {
......
222 232
			featList.add(feature);
223 233
		}
224 234

  
225
		
226
		FuseSpatiallyOperation operation = new FuseSpatiallyOperation(featList, 
227
				outFeatStoreTable, 
228
				attrNamesTable, 
229
				idField, 
235

  
236
		FuseSpatiallyOperation operation = new FuseSpatiallyOperation(featList,
237
				outFeatStoreTable,
238
				attrNamesTable,
239
				idField,
230 240
				this);
231 241
		operation.setFeatureStore(outFeatStore, attrNames);
232 242
		int size = featList.size();
233 243
		operation.setGeoProcess(this, size);
234
		
244

  
235 245
		while (featList.size() > 0 && !m_Task.isCanceled()) {
236
			Feature f = featList.remove(featList.size() - 1);	
246
			Feature f = featList.remove(featList.size() - 1);
237 247
			operation.invoke(f.getDefaultGeometry(), f);
238 248
			setProgress(size - featList.size(), size);
239 249
		}
......
241 251
		if(operation.getWriter() != null)
242 252
			operation.getWriter().end();
243 253
	}
244
	
254

  
245 255
	public boolean setProgress(int step, int size) {
246 256
		if(process != null)
247 257
			return process.setProgress(step, size);
248 258
		else
249 259
			return super.setProgress(step, size);
250 260
	}
251
	
261

  
252 262
	/**
253
	 * Builds the output FeatureStore 
263
	 * Builds the output FeatureStore
254 264
	 * @param featureType
255 265
	 * @return FeatureStore
256 266
	 */
......
258 268
	protected FeatureStore buildFuseSpatiallyOutPutStore(String[] attrNames,
259 269
											Class[] types,
260 270
											int shapeType,
261
											String sextanteLayerName, 
271
											String sextanteLayerName,
262 272
											String sextanteLayerLabel) {
263 273

  
264
		
274

  
265 275
		try {
266 276
			IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
267 277
													sextanteLayerName,
org.gvsig.geoprocess/trunk/org.gvsig.geoprocess/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyOperationFast2.java
70 70
 */
71 71
public class FuseSpatiallyOperationFast2 extends GeometryOperation {
72 72
	private static Logger 			         logger    		    = LoggerFactory.getLogger(FuseSpatiallyOperationFast2.class.getName());
73
	private ArrayList<Element>               featureList        = null; 
73
	private ArrayList<Element>               featureList        = null;
74 74
	private String                           nameIdField        = null;
75 75
	private FeatureStore                     outFeatStoreTable  = null;
76 76
	private NodeTree                         baseTree           = null;
77
	
77

  
78 78
	class Element {
79 79
		public int                 id              = -1;
80 80
		public Feature             feat            = null;
......
82 82
		public boolean             insertedToJoin  = false;
83 83
		public Geometry            jtsGeom         = null;
84 84
	}
85
	
85

  
86 86
	class NodeTree {
87 87
		public Element       element     = null;
88 88
		public int           pos         = 0;
89 89
		public NodeTree       parent      = null;
90
		
90

  
91 91
		public NodeTree(Element node, NodeTree parent) {
92 92
			this.element = node;
93 93
			this.parent = parent;
94 94
		}
95
		
95

  
96 96
		public Element getNext() {
97 97
			if(pos < element.overlapList.size())
98 98
				return element.overlapList.get(pos++);
99 99
			return null;
100 100
		}
101 101
	}
102
	
102

  
103 103
	public FuseSpatiallyOperationFast2(AbstractSextanteGeoProcess process) {
104 104
		super(process);
105 105
		featureList = new ArrayList<Element>();
......
116 116
	public void invoke(org.gvsig.fmap.geom.Geometry g,
117 117
			EditableFeature featureInput) {
118 118
		// TODO Auto-generated method stub
119
		
119

  
120 120
	}
121
	
121

  
122 122
	/**
123 123
	 * Computes a complete operation over the input FeatureStore. The result of this operation
124 124
	 * is stored in the output FeatureStore. This method will call once for each geometry.
......
126 126
	 *        Input FeatureStore
127 127
	 * @param outFeatStore
128 128
	 *        Output FeatureStore
129
	 * @param outFeatStoreTable
129 130
	 * @param attrNames
130 131
	 *        List of attributes to build the output feature store
132
	 * @param attrNamesTable
133
	 * @param selectedGeomInput
134
	 * @param selectedGeomOutput
135
	 * @param idField
131 136
	 * @param selectedGeom
132 137
	 *        If it is true only the selected geometries will be processed
133 138
	 * @throws DataException
......
148 153
		this.selectedGeomOverlay = selectedGeomOutput;
149 154
		FeatureSet featuresSet = null;
150 155
		featuresSet = inFeatStore.getFeatureSet();
151
		
156

  
152 157
		setFeatureStore(outFeatStore, attrNames);
153 158
		Iterator it = null;
154 159

  
......
160 165
			it = featuresSet.iterator();
161 166
			numberOfFeatures = (int)featuresSet.getSize();
162 167
		}
163
		
164
        if (status != null) 
168

  
169
        if (status != null)
165 170
            status.setRangeOfValues(0, numberOfFeatures);
166
        if(process != null) 
171
        if(process != null)
167 172
            process.setProgress(0, numberOfFeatures);
168
		
173

  
169 174
        //Crear lista de elementos
170 175
		int iCount = 0;
171 176
		while( it.hasNext() && !process.getTaskMonitor().isCanceled()) {
172
			Feature feat = (Feature)it.next();
177
			Feature feat = ((Feature)it.next()).getCopy();
173 178
			Element el = new Element();
174 179
			el.feat = feat;
175 180
			el.id = iCount;
176 181
			featureList.add(el);
177
            if (status != null && process != null) 
182
            if (status != null && process != null)
178 183
                status.setCurValue(iCount);
179
            if(process != null) 
184
            if(process != null)
180 185
                process.setProgress(iCount, numberOfFeatures);
181 186
			iCount ++;
182 187
		}
183 188
//		it.dispose();
184
		
189

  
185 190
		//Crear listas de solapes para cada feature
186 191
		iCount = 0;
187 192
		while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
188 193
			Element elem1 = featureList.get(iCount);
189 194
			org.gvsig.fmap.geom.Geometry geom1 = elem1.feat.getDefaultGeometry();
190
			if (status != null)  
195
			if (status != null)
191 196
                status.setCurValue(iCount);
192 197
            if(process != null)
193 198
                process.setProgress(iCount, numberOfFeatures);
194
            
199

  
195 200
			for (int i = iCount + 1; i < featureList.size(); i++) {
196 201
				Element elem2 = featureList.get(i);
197 202
				org.gvsig.fmap.geom.Geometry geom2 = elem2.feat.getDefaultGeometry();
198 203
				if(areBBoxesOverlaping(geom1, geom2)) {
199
					if(elem1.jtsGeom == null)
204
					if(elem1.jtsGeom == null) {
200 205
						elem1.jtsGeom = GeometryUtil.geomToJTS(geom1);
206
					}
201 207
					elem2.jtsGeom = GeometryUtil.geomToJTS(geom2);
202 208
					if(elem1.jtsGeom.intersects(elem2.jtsGeom))	{
203 209
						elem1.overlapList.add(elem2);
......
207 213
			}
208 214
			iCount ++;
209 215
		}
210
		
216

  
211 217
		iCount = 0;
212 218
		int iFeat = 0;
213 219
		while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
214 220
			Element elem1 = featureList.get(iCount);
215
			if (status != null) 
221
			if (status != null)
216 222
                status.setCurValue(iCount);
217
            if(process != null) 
223
            if(process != null)
218 224
                process.setProgress(iCount, numberOfFeatures);
219
      
225

  
220 226
			if(!elem1.insertedToJoin) {
221 227
				buildListToJoin(elem1, iFeat);
222 228
				iFeat ++;
223 229
			}
224
			
230

  
225 231
			iCount ++;
226 232
		}
227 233

  
228 234
		if(persister != null)
229 235
			persister.end();
230
		
236

  
231 237
	}
232
	
238

  
233 239
	private boolean areBBoxesOverlaping(org.gvsig.fmap.geom.Geometry g1, org.gvsig.fmap.geom.Geometry g2) {
234 240
		if(g1.getEnvelope().getMaximum(0) < g2.getEnvelope().getMinimum(0))
235 241
			return false;
......
241 247
			return false;
242 248
		return true;
243 249
	}
244
	
250

  
245 251
	/**
246 252
	 * Computes the union of the list of geometries
247 253
	 * @param listResult
......
262 268
				newGeom = GeometryUtil.geometryUnion(result, elem1.feat.getDefaultGeometry().getGeometryType().getType());
263 269
			}
264 270
		} else {
265
			newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType());	
271
			newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType());
266 272
		}
267 273
		return newGeom;
268 274
	}
269
	
275

  
270 276
	private Geometry computesUnion2(List<Geometry> listResult, Element elem1) {
271 277
		Geometry newGeom = null;
272 278
		for (int i = 1; i < listResult.size(); i++) {
......
277 283
		}
278 284
		return newGeom;
279 285
	}
280
	
286

  
281 287
	private Geometry computesUnion3(List<Geometry> listResult) {
282 288
		Geometry newGeom = null;
283 289
		int iCount = 0;
......
286 292
			process.setName("Generating union");
287 293
		while(listResult.size() > 1) {
288 294
			List<Geometry> list = new ArrayList<Geometry>();
289
			if (status != null)  
295
			if (status != null)
290 296
                status.setCurValue(iCount);
291 297
            if(process != null)
292 298
                process.setProgress(iCount, max);
......
302 308
		}
303 309
		return newGeom;
304 310
	}
305
	
311

  
306 312
	/**
307 313
	 * Splits the array of geometries to compute its union because JTS cannot support
308 314
	 * a lot of geometries
......
321 327
		}
322 328
		return l;
323 329
	}
324
	
330

  
325 331
	/**
326
	 * Builds the union of all lists 
332
	 * Builds the union of all lists
327 333
	 * @param listResult
328 334
	 * @param listToJoin
329 335
	 */
330 336
	private void buildListToJoin(Element elem, int iFeat) {
331 337
		Geometry newGeom = null;
332
		
338

  
333 339
		if(elem.overlapList.size() == 0) {
334 340
			if(!elem.insertedToJoin)
335 341
				elem.insertedToJoin = true;
......
357 363
					}
358 364
					subtree.element.insertedToJoin = true;
359 365
				}
360
				
366

  
361 367
				boolean back = false;
362
				
368

  
363 369
				Element l = subtree.getNext();
364
				if(l == null) 
370
				if(l == null)
365 371
					back = true;
366
				
372

  
367 373
				while(!back && l.insertedToJoin) {
368 374
					l = subtree.getNext();
369
					if(l == null) 
375
					if(l == null)
370 376
						back = true;
371 377
				}
372
				
378

  
373 379
				if(back) {
374 380
					subtree = subtree.parent;
375 381
					continue;
......
377 383
				subtree = new NodeTree(l, subtree);
378 384
			}
379 385
			newGeom = computesUnion3(listResult);
380
			
386

  
381 387
			try {
382 388
				addFeatureToOutput(newGeom, elem.feat, iFeat);
383 389
			} catch (DataException e) {
......
386 392
				logger.info("Error a?adiendo geometr?a", e);
387 393
			}
388 394
		}
389
		
395

  
390 396
	}
391
	
397

  
392 398
	/**
393 399
	 * Adds a feature to the output
394 400
	 * @param newGeom
......
397 403
	 * @throws DataException
398 404
	 * @throws CreateGeometryException
399 405
	 */
400
	private void addFeatureToOutput(org.gvsig.fmap.geom.Geometry newGeom, 
401
			Feature feat, 
406
	private void addFeatureToOutput(org.gvsig.fmap.geom.Geometry newGeom,
407
			Feature feat,
402 408
			int newFeatID) throws DataException, CreateGeometryException {
403 409
		//Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
404
		if(outFeatStoreTable != null) { 
410
		if(outFeatStoreTable != null) {
405 411
			lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
406 412
		} else {
407 413
			//Si no hay tabla se ponen todos los campos de la tabla de entrada
......
420 426
			lastEditFeature = persister.addFeature(newGeom, fields, values);
421 427
		}
422 428
	}
423
	
429

  
424 430
	/**
425 431
	 * Adds a feature to the output
426 432
	 * @param newGeom
......
429 435
	 * @throws DataException
430 436
	 * @throws CreateGeometryException
431 437
	 */
432
	private void addFeatureToOutput(Geometry newGeom, 
433
			Feature feat, 
438
	private void addFeatureToOutput(Geometry newGeom,
439
			Feature feat,
434 440
			int newFeatID) throws DataException, CreateGeometryException {
435 441
		//Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
436
		if(outFeatStoreTable != null) { 
442
		if(outFeatStoreTable != null) {
437 443
			lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
438 444
		} else {
439 445
			//Si no hay tabla se ponen todos los campos de la tabla de entrada
......
452 458
			lastEditFeature = persister.addFeature(newGeom, fields, values);
453 459
		}
454 460
	}
455
	
461

  
456 462
	/**
457
	 * Insert in the output table a new feature with the fields of the input feature. Moreover 
463
	 * Insert in the output table a new feature with the fields of the input feature. Moreover
458 464
	 * exists a field that is an identifier which is a reference to the fusion layer.
459 465
	 * @param outFeatureStoreTable
460 466
	 * @param f
......
473 479
		}
474 480
		outFeatureStoreTable.insert(edFeat);
475 481
	}
476
	
482

  
477 483
}
478 484

  

Also available in: Unified diff