Revision 1334

View differences:

org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.137/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/pom.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3
  <modelVersion>4.0.0</modelVersion>
4
  <artifactId>org.gvsig.geoprocess.algorithm.fusespatially</artifactId>
5
  <packaging>jar</packaging>
6
  <name>org.gvsig.geoprocess.algorithm.fusespatially</name>
7
	
8
	<parent>
9
		<groupId>org.gvsig</groupId>
10
		<artifactId>org.gvsig.geoprocess.algorithm</artifactId>
11
		<version>2.2.137</version>
12
	</parent>
13
	
14
	<dependencies>
15
		<dependency>
16
		    <groupId>org.gvsig</groupId>
17
   			<artifactId>org.gvsig.geoprocess.algorithm.base</artifactId>
18
            <scope>compile</scope>
19
   		</dependency>
20
   		<dependency>
21
		    <groupId>org.gvsig</groupId>
22
   			<artifactId>org.gvsig.geoprocess.algorithm.dissolve</artifactId>
23
            <scope>compile</scope>
24
   		</dependency>
25
	</dependencies>
26
	
27
</project>
0 28

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.137/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyOperationFast.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25

  
26
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
27
 *
28
 * Copyright (C) 2010 Generalitat Valenciana.
29
 *
30
 * This program is free software; you can redistribute it and/or
31
 * modify it under the terms of the GNU General Public License
32
 * as published by the Free Software Foundation; either version 2
33
 * of the License, or (at your option) any later version.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
 * GNU General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU General Public License
41
 * along with this program; if not, write to the Free Software
42
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
43
 */
44

  
45
package org.gvsig.geoprocess.algorithm.fusespatially;
46

  
47
import java.util.ArrayList;
48
import java.util.List;
49

  
50
import org.gvsig.fmap.dal.exception.DataException;
51
import org.gvsig.fmap.dal.feature.EditableFeature;
52
import org.gvsig.fmap.dal.feature.Feature;
53
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
54
import org.gvsig.fmap.dal.feature.FeatureSelection;
55
import org.gvsig.fmap.dal.feature.FeatureSet;
56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.geom.exception.CreateGeometryException;
58
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
59
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
60
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
61
import org.slf4j.Logger;
62
import org.slf4j.LoggerFactory;
63

  
64
import com.vividsolutions.jts.geom.Geometry;
65
import java.util.Iterator;
66
/**
67
 * Fuse spatially operation
68
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
69
 */
70
public class FuseSpatiallyOperationFast extends GeometryOperation {
71
	private static Logger 			         logger    		    = LoggerFactory.getLogger(FuseSpatiallyOperationFast.class.getName());
72
	private ArrayList<Element>               featureList        = null; 
73
	private String                           nameIdField        = null;
74
	private FeatureStore                     outFeatStoreTable  = null;
75
	
76
	class Element {
77
		public int                 id              = -1;
78
		public Feature             feat            = null;
79
		public List<Element>       overlapList     = new ArrayList<Element>();
80
		public boolean             insertedToJoin  = false;
81
		public Geometry            jtsGeom         = null;
82
	}
83
	
84
	public FuseSpatiallyOperationFast(AbstractSextanteGeoProcess process) {
85
		super(process);
86
		featureList = new ArrayList<Element>();
87
	}
88

  
89
	@Override
90
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g,
91
			Feature featureInput) {
92
		// TODO Auto-generated method stub
93
		return null;
94
	}
95

  
96
	@Override
97
	public void invoke(org.gvsig.fmap.geom.Geometry g,
98
			EditableFeature featureInput) {
99
		// TODO Auto-generated method stub
100
		
101
	}
102
	
103
	/**
104
	 * Computes a complete operation over the input FeatureStore. The result of this operation
105
	 * is stored in the output FeatureStore. This method will call once for each geometry.
106
	 * @param inFeatStore
107
	 *        Input FeatureStore
108
	 * @param outFeatStore
109
	 *        Output FeatureStore
110
	 * @param attrNames
111
	 *        List of attributes to build the output feature store
112
	 * @param selectedGeom
113
	 *        If it is true only the selected geometries will be processed
114
	 * @throws DataException
115
	 */
116
	@SuppressWarnings("deprecation")
117
	public void computesGeometryOperation(FeatureStore inFeatStore,
118
									FeatureStore outFeatStore,
119
									FeatureStore outFeatStoreTable,
120
									String[] attrNames,
121
									String[] attrNamesTable,
122
									boolean selectedGeomInput,
123
									boolean selectedGeomOutput,
124
									String idField) throws DataException {
125
		this.outFeatStoreTable = outFeatStoreTable;
126
		this.nameIdField = idField;
127
		this.inFeatureStore = inFeatStore;
128
		this.selectedGeomInput = selectedGeomInput;
129
		this.selectedGeomOverlay = selectedGeomOutput;
130
		FeatureSet featuresSet = null;
131
		featuresSet = inFeatStore.getFeatureSet();
132
		
133
		setFeatureStore(outFeatStore, attrNames);
134
		Iterator it = null;
135

  
136
		if(selectedGeomInput) {
137
            FeatureSelection ds = inFeatStore.getFeatureSelection();
138
            it = ds.iterator();
139
            numberOfFeatures = (int) ds.getSelectedCount();
140
		} else {
141
			it = featuresSet.iterator();
142
			numberOfFeatures = (int)featuresSet.getSize();
143
		}
144
		
145
        if (status != null) 
146
            status.setRangeOfValues(0, numberOfFeatures);
147
        if(process != null) 
148
            process.setProgress(0, numberOfFeatures);
149
		
150
        //Crear lista de elementos
151
		int iCount = 0;
152
		while( it.hasNext() && !process.getTaskMonitor().isCanceled()) {
153
			Feature feat = (Feature)it.next();
154
			Element el = new Element();
155
			el.feat = feat;
156
			el.id = iCount;
157
			featureList.add(el);
158
            if (status != null && process != null) 
159
                status.setCurValue(iCount);
160
            if(process != null) 
161
                process.setProgress(iCount, numberOfFeatures);
162
			iCount ++;
163
		}
164
//		it.dispose();
165
		
166
		//Crear listas de solapes para cada feature
167
		iCount = 0;
168
		while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
169
			Element elem1 = featureList.get(iCount);
170
			org.gvsig.fmap.geom.Geometry geom1 = elem1.feat.getDefaultGeometry();
171
			if (status != null)  
172
                status.setCurValue(iCount);
173
            if(process != null)
174
                process.setProgress(iCount, numberOfFeatures);
175
            
176
			for (int i = iCount + 1; i < featureList.size(); i++) {
177
				Element elem2 = featureList.get(i);
178
				org.gvsig.fmap.geom.Geometry geom2 = elem2.feat.getDefaultGeometry();
179
				if(areBBoxesOverlaping(geom1, geom2)) {
180
					if(elem1.jtsGeom == null)
181
						elem1.jtsGeom = GeometryUtil.geomToJTS(geom1);
182
					elem2.jtsGeom = GeometryUtil.geomToJTS(geom2);
183
					if(elem1.jtsGeom.intersects(elem2.jtsGeom))	{
184
						elem1.overlapList.add(elem2);
185
						elem2.overlapList.add(elem1);
186
					}
187
				}
188
			}
189
			iCount ++;
190
		}
191
		
192
		//Se calculan las listas de geometrias a unir
193
		//Para cada feature se obtiene su lista de elementos que solapan y para 
194
		//cada elemento que solapa se obtiene su lista. Finalmente todas se unen y 
195
		//y se hace un insert de una feature nueva
196
		List<Geometry> listResult = new ArrayList<Geometry>();
197
		iCount = 0;
198
		int iFeat = 0;
199
		while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
200
			Element elem1 = featureList.get(iCount);
201
			if (status != null) 
202
                status.setCurValue(iCount);
203
            if(process != null) 
204
                process.setProgress(iCount, numberOfFeatures);
205
      
206
			if(!elem1.insertedToJoin) {
207
				elem1.insertedToJoin = true;
208
				listResult.clear();
209
				try {
210
					insertInTable(outFeatStoreTable, elem1.feat, iFeat);
211
				} catch (DataException e) {
212
					logger.info("Imposible insertar en la tabla", e);
213
				}
214
				listResult.add(elem1.jtsGeom);
215
				
216
				buildListToJoin(listResult, elem1.overlapList, iFeat);
217
				
218
				Geometry newGeom = computesUnion(listResult, elem1);
219
				
220
				try {
221
					addFeatureToOutput(newGeom, elem1.feat, iFeat);
222
				} catch (CreateGeometryException e) {
223
					logger.info("Error a?adiendo geometr?a", e);
224
				} catch (DataException e) {
225
					logger.info("Error a?adiendo geometr?a", e);
226
				}
227
				iFeat ++;
228
			}
229
			iCount ++;
230
		}
231

  
232
		if(persister != null)
233
			persister.end();
234
		
235
	}
236
	
237
	private boolean areBBoxesOverlaping(org.gvsig.fmap.geom.Geometry g1, org.gvsig.fmap.geom.Geometry g2) {
238
		if(g1.getEnvelope().getMaximum(0) < g2.getEnvelope().getMinimum(0))
239
			return false;
240
		if(g1.getEnvelope().getMinimum(0) > g2.getEnvelope().getMaximum(0))
241
			return false;
242
		if(g1.getEnvelope().getMaximum(1) < g2.getEnvelope().getMinimum(1))
243
			return false;
244
		if(g1.getEnvelope().getMinimum(1) > g2.getEnvelope().getMaximum(1))
245
			return false;
246
		return true;
247
	}
248
	
249
	/**
250
	 * Computes the union of the list of geometries
251
	 * @param listResult
252
	 * @param elem1
253
	 * @return
254
	 */
255
	private Geometry computesUnion(List<Geometry> listResult, Element elem1) {
256
		int splitValue = 500;
257
		Geometry newGeom = null;
258
		if(listResult.size() > splitValue) {
259
			List<List<Geometry>> list = splitList(listResult, splitValue);
260
			List<Geometry> result = new ArrayList<Geometry>();
261
			for (int i = 0; i < list.size(); i++) {
262
				Geometry aux = GeometryUtil.geometryUnion(list.get(i), elem1.feat.getDefaultGeometry().getGeometryType().getType());
263
				result.add(aux);
264
			}
265
			for (int i = 0; i < result.size(); i++) {
266
				newGeom = GeometryUtil.geometryUnion(result, elem1.feat.getDefaultGeometry().getGeometryType().getType());
267
			}
268
		} else {
269
			newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType());	
270
		}
271
		return newGeom;
272
	}
273
	
274
	/**
275
	 * Splits the array of geometries to compute its union because JTS cannot support
276
	 * a lot of geometries
277
	 * @param list
278
	 * @param n
279
	 * @return
280
	 */
281
	private List<List<Geometry>> splitList(List<Geometry> list, int n) {
282
		int elements = (int)(list.size() / n);
283
		List<List<Geometry>> l = new ArrayList<List<Geometry>>();
284
		for (int i = 0; i < elements; i++) {
285
			l.add(list.subList((i * n), (i * n) + n));
286
		}
287
		if(elements * n < list.size()) {
288
			l.add(list.subList((elements * n), list.size()));
289
		}
290
		return l;
291
	}
292
	
293
	/**
294
	 * Builds the union of all lists 
295
	 * @param listResult
296
	 * @param listToJoin
297
	 */
298
	private void buildListToJoin(List<Geometry> listResult, List<Element> listToJoin, int reference) {
299
		for (int i = 0; i < listToJoin.size(); i++) {
300
			Element elem = listToJoin.get(i);
301
			if(!elem.insertedToJoin) {
302
				elem.insertedToJoin = true;
303
				buildListToJoin(listResult, elem.overlapList, reference);
304
				try {
305
					insertInTable(outFeatStoreTable, elem.feat, reference);
306
				} catch (DataException e) {
307
					logger.info("Imposible insertar en la tabla", e);
308
				}
309
				listResult.add(elem.jtsGeom);
310
			}
311
		}
312
	}
313
	
314
	/**
315
	 * Adds a feature to the output
316
	 * @param newGeom
317
	 * @param feat
318
	 * @param newFeatID
319
	 * @throws DataException
320
	 * @throws CreateGeometryException
321
	 */
322
	private void addFeatureToOutput(Geometry newGeom, 
323
			Feature feat, 
324
			int newFeatID) throws DataException, CreateGeometryException {
325
		//Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
326
		if(outFeatStoreTable != null) { 
327
			lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
328
		} else {
329
			//Si no hay tabla se ponen todos los campos de la tabla de entrada
330
			String[] fieldNames = persister.getFieldNamesWithoutGeom();
331
			ArrayList<String> fields = new ArrayList<String>();
332
			ArrayList<Object> values = new ArrayList<Object>();
333
			fields.add(nameIdField);
334
			values.add(newFeatID);
335
			for (int j = 0; j < fieldNames.length; j++) {
336
				Object obj = feat.get(fieldNames[j]);
337
				if(obj != null && fieldNames[j].compareTo(nameIdField) != 0) {
338
					fields.add(fieldNames[j]);
339
					values.add(obj);
340
				}
341
			}
342
			lastEditFeature = persister.addFeature(newGeom, fields, values);
343
		}
344
	}
345
	
346
	/**
347
	 * Insert in the output table a new feature with the fields of the input feature. Moreover 
348
	 * exists a field that is an identifier which is a reference to the fusion layer.
349
	 * @param outFeatureStoreTable
350
	 * @param f
351
	 * @throws DataException
352
	 */
353
	private void insertInTable(FeatureStore outFeatureStoreTable, Feature f, int reference) throws DataException {
354
		if(outFeatureStoreTable == null)
355
			return;
356
		EditableFeature edFeat = outFeatureStoreTable.createNewFeature();
357
		edFeat.set(nameIdField, reference);
358
		FeatureAttributeDescriptor[] attrList = f.getType().getAttributeDescriptors();
359
		for (int j = 0; j < attrList.length; j++) {
360
			if(attrList[j].getName().compareTo("GEOMETRY") != 0) {
361
				edFeat.set(attrList[j].getName(), f.get(attrList[j].getName()));
362
			}
363
		}
364
		outFeatureStoreTable.insert(edFeat);
365
	}
366
	
367
}
368

  
0 369

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.137/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyOperation_Old.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25

  
26
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
27
 *
28
 * Copyright (C) 2010 Generalitat Valenciana.
29
 *
30
 * This program is free software; you can redistribute it and/or
31
 * modify it under the terms of the GNU General Public License
32
 * as published by the Free Software Foundation; either version 2
33
 * of the License, or (at your option) any later version.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
 * GNU General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU General Public License
41
 * along with this program; if not, write to the Free Software
42
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
43
 */
44

  
45
package org.gvsig.geoprocess.algorithm.fusespatially;
46

  
47
import java.util.ArrayList;
48
import java.util.Iterator;
49
import java.util.List;
50

  
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.feature.EditableFeature;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureSet;
55
import org.gvsig.fmap.dal.feature.FeatureStore;
56
import org.gvsig.fmap.geom.GeometryLocator;
57
import org.gvsig.fmap.geom.GeometryManager;
58
import org.gvsig.fmap.geom.exception.CreateGeometryException;
59
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
60
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
61
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
62

  
63
import com.vividsolutions.jts.geom.Geometry;
64
/**
65
 * Fuse spatially operation
66
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
67
 */
68
public class FuseSpatiallyOperation_Old extends GeometryOperation {
69
	private FeatureStore                     inFeatStore      = null;
70
	protected GeometryManager                geomManager      = GeometryLocator.getGeometryManager();
71
	private FeatureSet                       featureSet       = null;
72
	private int                              id               = 0;
73
	private long                             nFeatures        = 0;
74
	private boolean[]                        featProcessed    = null;
75

  
76
	public FuseSpatiallyOperation_Old(FeatureStore inFeatStore, boolean selectedGeom, AbstractSextanteGeoProcess p) throws DataException {
77
		super(p);
78
		this.inFeatStore = inFeatStore;
79
		
80
		if(selectedGeom) {
81
			featureSet = (FeatureSet)inFeatStore.getSelection();
82
		} else
83
			featureSet = inFeatStore.getFeatureSet();
84
		nFeatures = featureSet.getSize();
85
		featProcessed = new boolean[(int)nFeatures];
86
	}
87

  
88
	/*
89
	 * (non-Javadoc)
90
	 * @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
91
	 */
92
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
93
		if(g == null)
94
			return lastEditFeature;
95
		
96
		try {
97
			Geometry inputJTSGeom = GeometryUtil.geomToJTS(g);
98
			Geometry union = null; 
99
			
100
			Iterator it = featureSet.fastIterator();
101
			int index = 0;
102
			while(it.hasNext()) {
103
				Feature f = (Feature)it.next();
104
				if(featProcessed[index])
105
					continue;
106
				org.gvsig.fmap.geom.Geometry geom = feature.getDefaultGeometry();
107
				Geometry jtsGeom = GeometryUtil.geomToJTS(geom); //Multigeometry support
108
				if(inputJTSGeom.intersects(jtsGeom)) {
109
					inputJTSGeom = inputJTSGeom.union(jtsGeom);
110
					featProcessed[index] = true;
111
				}
112
				index ++;
113
				continue;
114
			}
115

  
116
			lastEditFeature = persister.addFeature(inputJTSGeom, "FID", id);
117
		} catch (DataException e) {
118
			return null;
119
		} catch (CreateGeometryException e) {
120
			return null;
121
		}
122
		id++;
123
		return lastEditFeature;
124
	}
125
	
126
	/*
127
	 * (non-Javadoc)
128
	 * @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
129
	 */
130
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
131
		if(g == null)
132
			return;
133
	}
134
	
135
	/*
136
	 * (non-Javadoc)
137
	 * @see org.gvsig.geoprocess.algorithm.base.core.IOperation#getResult()
138
	 */
139
	public Object getResult() {
140
		return lastEditFeature;
141
	}
142
	
143
}
144

  
0 145

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.137/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyOperation.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25

  
26
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
27
 *
28
 * Copyright (C) 2010 Generalitat Valenciana.
29
 *
30
 * This program is free software; you can redistribute it and/or
31
 * modify it under the terms of the GNU General Public License
32
 * as published by the Free Software Foundation; either version 2
33
 * of the License, or (at your option) any later version.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
 * GNU General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU General Public License
41
 * along with this program; if not, write to the Free Software
42
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
43
 */
44

  
45
package org.gvsig.geoprocess.algorithm.fusespatially;
46

  
47
import java.util.ArrayList;
48
import java.util.List;
49
import java.util.Stack;
50

  
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.feature.EditableFeature;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
55
import org.gvsig.fmap.dal.feature.FeatureStore;
56
import org.gvsig.fmap.geom.GeometryLocator;
57
import org.gvsig.fmap.geom.GeometryManager;
58
import org.gvsig.fmap.geom.exception.CreateGeometryException;
59
import org.gvsig.geoprocess.algorithm.base.core.DALFeaturePersister;
60
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
61
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
62
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
63

  
64
import com.vividsolutions.jts.geom.Geometry;
65
/**
66
 * Fuse spatially operation
67
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
68
 * @deprecated Uses FuseSpatiallyOperationFast
69
 */
70
public class FuseSpatiallyOperation extends GeometryOperation {
71
	protected GeometryManager                geomManager           = GeometryLocator.getGeometryManager();
72
	private int                              id                    = 0;
73
	private List<Feature>                    featList              = null;
74
	private FeatureStore                     outFeatureStoreTable  = null;
75
	private String                           idField               = "FID";
76
	
77
	public FuseSpatiallyOperation(List<Feature> f, 
78
			FeatureStore outFeatStoreTable, 
79
			String[] fieldNames, 
80
			String idField, 
81
			AbstractSextanteGeoProcess p) throws DataException {
82
		super(p);
83
		this.featList = f;
84
		this.outFeatureStoreTable = outFeatStoreTable;
85
		this.idField = idField;
86
	}
87
	
88
	public FuseSpatiallyOperation(Stack<Feature> f, 
89
			FeatureStore outFeatStoreTable, 
90
			String[] fieldNames, 
91
			AbstractSextanteGeoProcess p) throws DataException {
92
		super(p);
93
		this.featList = f;
94
		this.outFeatureStoreTable = outFeatStoreTable;
95
	}
96
	
97
	/*
98
	 * (non-Javadoc)
99
	 * @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
100
	 */
101
        @Override
102
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
103
		try {
104
			Geometry jtsInputGeom = GeometryUtil.geomToJTS(g);
105
			insertInTable(feature);
106
			
107
			int cont = featList.size() - 1;
108
			while(cont >= 0 && !process.getTaskMonitor().isCanceled()) {
109
				Feature f = featList.get(cont);
110
				g = f.getDefaultGeometry();
111
				Geometry jtsGeom = GeometryUtil.geomToJTS(g); //Multigeometry support
112
				if(jtsGeom.intersects(jtsInputGeom)) {
113
					jtsInputGeom = jtsInputGeom.union(jtsGeom);
114
					featList.remove(cont);
115
					process.setProgress(procesSize - featList.size(), procesSize);
116
					cont = featList.size();
117
					insertInTable(f);
118
				}
119
				cont --;
120
			}
121

  
122
			//Cuando no genera dos capas mete los campos de la feature de entrada en la de salida perdiendose el resto
123
			if(outFeatureStoreTable == null) { 
124
				String[] fieldNames = persister.getFieldNamesWithoutGeom();
125
				ArrayList<String> fields = new ArrayList<String>();
126
				ArrayList<Object> values = new ArrayList<Object>();
127
				fields.add(idField);
128
				values.add(id);
129
				for (int j = 0; j < fieldNames.length; j++) {
130
					Object obj = feature.get(fieldNames[j]);
131
					if(obj != null && fieldNames[j].compareTo(idField) != 0) {
132
						fields.add(fieldNames[j]);
133
						values.add(obj);
134
					}
135
				}
136
				lastEditFeature = persister.addFeature(jtsInputGeom, fields, values);
137
			} else
138
				lastEditFeature = persister.addFeature(jtsInputGeom, idField, id);
139
		} catch (DataException e) {
140
			return null;
141
		} catch (CreateGeometryException e) {
142
			return null;
143
		}
144
		id++;
145
		return lastEditFeature;
146
	}
147
	
148
	private void insertInTable(Feature f) throws DataException {
149
		if(outFeatureStoreTable == null)
150
			return;
151
		EditableFeature edFeat = outFeatureStoreTable.createNewFeature();
152
		edFeat.set(idField, id);
153
		FeatureAttributeDescriptor[] attrList = f.getType().getAttributeDescriptors();
154
		for (int j = 0; j < attrList.length; j++) {
155
			if(attrList[j].getName().compareTo("GEOMETRY") != 0) {
156
				edFeat.set(attrList[j].getName(), f.get(attrList[j].getName()));
157
			}
158
		}
159
		outFeatureStoreTable.insert(edFeat);
160
	}
161
	
162
	/**
163
	 * Removes duplicate fields
164
	 * @param names
165
	 * @return
166
	 */
167
	public static String[] checkFields(String[] names) {
168
		if(names.length <= 1)
169
			return names;
170
		int cont = 0;
171

  
172
		int i = 1;
173
		while(i < names.length) {
174
			if(names[0].compareTo(names[i]) == 0) {
175
				names[0] = "FID_" + cont;
176
				i = 0;
177
				cont ++;
178
			}
179
			i ++;
180
		}
181
		return names;
182
	}
183
	
184
	/*
185
	 * (non-Javadoc)
186
	 * @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
187
	 */
188
        @Override
189
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) {
190
		if(g == null)
191
			return;
192
	}
193
	
194
	/*
195
	 * (non-Javadoc)
196
	 * @see org.gvsig.geoprocess.algorithm.base.core.IOperation#getResult()
197
	 */
198
	public Object getResult() {
199
		return lastEditFeature;
200
	}
201
	
202
	public DALFeaturePersister getWriter() {
203
		return persister;
204
	}
205
	
206
}
207

  
0 208

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.137/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyOperationFast2.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25

  
26
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
27
 *
28
 * Copyright (C) 2010 Generalitat Valenciana.
29
 *
30
 * This program is free software; you can redistribute it and/or
31
 * modify it under the terms of the GNU General Public License
32
 * as published by the Free Software Foundation; either version 2
33
 * of the License, or (at your option) any later version.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
 * GNU General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU General Public License
41
 * along with this program; if not, write to the Free Software
42
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
43
 */
44
package org.gvsig.geoprocess.algorithm.fusespatially;
45

  
46
import java.util.ArrayList;
47
import java.util.List;
48

  
49
import org.gvsig.fmap.dal.exception.DataException;
50
import org.gvsig.fmap.dal.feature.EditableFeature;
51
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53
import org.gvsig.fmap.dal.feature.FeatureSelection;
54
import org.gvsig.fmap.dal.feature.FeatureSet;
55
import org.gvsig.fmap.dal.feature.FeatureStore;
56
import org.gvsig.fmap.geom.exception.CreateGeometryException;
57
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
58
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
59
import org.gvsig.geoprocess.algorithm.base.util.JTSFacade;
60
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
61
import org.slf4j.Logger;
62
import org.slf4j.LoggerFactory;
63

  
64
import com.vividsolutions.jts.geom.Geometry;
65
import java.util.Iterator;
66

  
67
/**
68
 * Fuse spatially operation
69
 *
70
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
71
 */
72
public class FuseSpatiallyOperationFast2 extends GeometryOperation {
73

  
74
    private static Logger logger = LoggerFactory.getLogger(FuseSpatiallyOperationFast2.class.getName());
75
    private ArrayList<Element> featureList = null;
76
    private String nameIdField = null;
77
    private FeatureStore outFeatStoreTable = null;
78
    private NodeTree baseTree = null;
79

  
80
    class Element {
81

  
82
        public int id = -1;
83
        public Feature feat = null;
84
        public List<Element> overlapList = new ArrayList<Element>();
85
        public boolean insertedToJoin = false;
86
        public Geometry jtsGeom = null;
87
    }
88

  
89
    class NodeTree {
90

  
91
        public Element element = null;
92
        public int pos = 0;
93
        public NodeTree parent = null;
94

  
95
        public NodeTree(Element node, NodeTree parent) {
96
            this.element = node;
97
            this.parent = parent;
98
        }
99

  
100
        public Element getNext() {
101
            if (pos < element.overlapList.size()) {
102
                return element.overlapList.get(pos++);
103
            }
104
            return null;
105
        }
106
    }
107

  
108
    public FuseSpatiallyOperationFast2(AbstractSextanteGeoProcess process) {
109
        super(process);
110
        featureList = new ArrayList<Element>();
111
    }
112

  
113
    @Override
114
    public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g,
115
            Feature featureInput) {
116
        // TODO Auto-generated method stub
117
        return null;
118
    }
119

  
120
    @Override
121
    public void invoke(org.gvsig.fmap.geom.Geometry g,
122
            EditableFeature featureInput) {
123
        // TODO Auto-generated method stub
124

  
125
    }
126

  
127
    /**
128
     * Computes a complete operation over the input FeatureStore. The result of
129
     * this operation is stored in the output FeatureStore. This method will
130
     * call once for each geometry.
131
     *
132
     * @param inFeatStore Input FeatureStore
133
     * @param outFeatStore Output FeatureStore
134
     * @param outFeatStoreTable
135
     * @param attrNames List of attributes to build the output feature store
136
     * @param attrNamesTable
137
     * @param selectedGeomInput
138
     * @param selectedGeomOutput
139
     * @param idField
140
     * @param selectedGeom If it is true only the selected geometries will be
141
     * processed
142
     * @throws DataException
143
     */
144
    @SuppressWarnings("deprecation")
145
    public void computesGeometryOperation(FeatureStore inFeatStore,
146
            FeatureStore outFeatStore,
147
            FeatureStore outFeatStoreTable,
148
            String[] attrNames,
149
            String[] attrNamesTable,
150
            boolean selectedGeomInput,
151
            boolean selectedGeomOutput,
152
            String idField) throws DataException {
153
        this.outFeatStoreTable = outFeatStoreTable;
154
        this.nameIdField = idField;
155
        this.inFeatureStore = inFeatStore;
156
        this.selectedGeomInput = selectedGeomInput;
157
        this.selectedGeomOverlay = selectedGeomOutput;
158
        FeatureSet featuresSet = null;
159
        featuresSet = inFeatStore.getFeatureSet();
160

  
161
        setFeatureStore(outFeatStore, attrNames);
162
        Iterator it = null;
163

  
164
        if (selectedGeomInput) {
165
            FeatureSelection ds = inFeatStore.getFeatureSelection();
166
            it = ds.iterator();
167
            numberOfFeatures = (int) ds.getSelectedCount();
168
        } else {
169
            it = featuresSet.iterator();
170
            numberOfFeatures = (int) featuresSet.getSize();
171
        }
172

  
173
        if (status != null) {
174
            status.setRangeOfValues(0, numberOfFeatures);
175
        }
176
        if (process != null) {
177
            process.setProgress(0, numberOfFeatures);
178
        }
179

  
180
        //Crear lista de elementos
181
        int iCount = 0;
182
        while (it.hasNext() && !process.getTaskMonitor().isCanceled()) {
183
            Feature feat = ((Feature) it.next()).getCopy();
184
            Element el = new Element();
185
            el.feat = feat;
186
            el.id = iCount;
187
            featureList.add(el);
188
            if (status != null && process != null) {
189
                status.setCurValue(iCount);
190
            }
191
            if (process != null) {
192
                process.setProgress(iCount, numberOfFeatures);
193
            }
194
            iCount++;
195
        }
196
//		it.dispose();
197

  
198
        //Crear listas de solapes para cada feature
199
        iCount = 0;
200
        while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
201
            Element elem1 = featureList.get(iCount);
202
            org.gvsig.fmap.geom.Geometry geom1 = elem1.feat.getDefaultGeometry();
203
            if (status != null) {
204
                status.setCurValue(iCount);
205
            }
206
            if (process != null) {
207
                process.setProgress(iCount, numberOfFeatures);
208
            }
209

  
210
            for (int i = iCount + 1; i < featureList.size(); i++) {
211
                Element elem2 = featureList.get(i);
212
                org.gvsig.fmap.geom.Geometry geom2 = elem2.feat.getDefaultGeometry();
213
                if (areBBoxesOverlaping(geom1, geom2)) {
214
                    if (elem1.jtsGeom == null) {
215
                        elem1.jtsGeom = GeometryUtil.geomToJTS(geom1);
216
                    }
217
                    elem2.jtsGeom = GeometryUtil.geomToJTS(geom2);
218
                    if (elem1.jtsGeom.intersects(elem2.jtsGeom)) {
219
                        elem1.overlapList.add(elem2);
220
                        elem2.overlapList.add(elem1);
221
                    }
222
                }
223
            }
224
            iCount++;
225
        }
226

  
227
        iCount = 0;
228
        int iFeat = 0;
229
        while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
230
            Element elem1 = featureList.get(iCount);
231
            if (status != null) {
232
                status.setCurValue(iCount);
233
            }
234
            if (process != null) {
235
                process.setProgress(iCount, numberOfFeatures);
236
            }
237

  
238
            if (!elem1.insertedToJoin) {
239
                buildListToJoin(elem1, iFeat);
240
                iFeat++;
241
            }
242

  
243
            iCount++;
244
        }
245

  
246
        if (persister != null) {
247
            persister.end();
248
        }
249

  
250
    }
251

  
252
    private boolean areBBoxesOverlaping(org.gvsig.fmap.geom.Geometry g1, org.gvsig.fmap.geom.Geometry g2) {
253
        if (g1.getEnvelope().getMaximum(0) < g2.getEnvelope().getMinimum(0)) {
254
            return false;
255
        }
256
        if (g1.getEnvelope().getMinimum(0) > g2.getEnvelope().getMaximum(0)) {
257
            return false;
258
        }
259
        if (g1.getEnvelope().getMaximum(1) < g2.getEnvelope().getMinimum(1)) {
260
            return false;
261
        }
262
        if (g1.getEnvelope().getMinimum(1) > g2.getEnvelope().getMaximum(1)) {
263
            return false;
264
        }
265
        return true;
266
    }
267

  
268
    /**
269
     * Computes the union of the list of geometries
270
     *
271
     * @param listResult
272
     * @param elem1
273
     * @return
274
     */
275
    private Geometry computesUnion(List<Geometry> listResult, Element elem1) {
276
        int splitValue = 500;
277
        Geometry newGeom = null;
278
        if (listResult.size() > splitValue) {
279
            List<List<Geometry>> list = splitList(listResult, splitValue);
280
            List<Geometry> result = new ArrayList<Geometry>();
281
            for (int i = 0; i < list.size(); i++) {
282
                Geometry aux = GeometryUtil.geometryUnion(list.get(i), elem1.feat.getDefaultGeometry().getGeometryType().getType());
283
                result.add(aux);
284
            }
285
            for (int i = 0; i < result.size(); i++) {
286
                newGeom = GeometryUtil.geometryUnion(result, elem1.feat.getDefaultGeometry().getGeometryType().getType());
287
            }
288
        } else {
289
            newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType());
290
        }
291
        return newGeom;
292
    }
293

  
294
    private Geometry computesUnion2(List<Geometry> listResult, Element elem1) {
295
        Geometry newGeom = null;
296
        for (int i = 1; i < listResult.size(); i++) {
297
            if (i == 1) {
298
                newGeom = JTSFacade.union(listResult.get(0), listResult.get(1));
299
            } else {
300
                newGeom = JTSFacade.union(newGeom, listResult.get(i));
301
            }
302
        }
303
        return newGeom;
304
    }
305

  
306
    private Geometry computesUnion3(List<Geometry> listResult) {
307
        Geometry newGeom = null;
308
        int iCount = 0;
309
        int max = listResult.size();
310
        if (process != null) {
311
            process.setName("Generating union");
312
        }
313
        while (listResult.size() > 1) {
314
            List<Geometry> list = new ArrayList<Geometry>();
315
            if (status != null) {
316
                status.setCurValue(iCount);
317
            }
318
            if (process != null) {
319
                process.setProgress(iCount, max);
320
            }
321
            for (int i = 0; i < listResult.size(); i = i + 2) {
322
                if (i == (listResult.size() - 1)) {
323
                    list.add(listResult.get(i));
324
                } else {
325
                    newGeom = JTSFacade.union(listResult.get(i), listResult.get(i + 1));
326
                    list.add(newGeom);
327
                }
328
            }
329
            listResult = list;
330
        }
331
        return newGeom;
332
    }
333

  
334
    /**
335
     * Splits the array of geometries to compute its union because JTS cannot
336
     * support a lot of geometries
337
     *
338
     * @param list
339
     * @param n
340
     * @return
341
     */
342
    private List<List<Geometry>> splitList(List<Geometry> list, int n) {
343
        int elements = (int) (list.size() / n);
344
        List<List<Geometry>> l = new ArrayList<List<Geometry>>();
345
        for (int i = 0; i < elements; i++) {
346
            l.add(list.subList((i * n), (i * n) + n));
347
        }
348
        if (elements * n < list.size()) {
349
            l.add(list.subList((elements * n), list.size()));
350
        }
351
        return l;
352
    }
353

  
354
    /**
355
     * Builds the union of all lists
356
     *
357
     * @param listResult
358
     * @param listToJoin
359
     */
360
    private void buildListToJoin(Element elem, int iFeat) {
361
        Geometry newGeom = null;
362

  
363
        if (elem.overlapList.size() == 0) {
364
            if (!elem.insertedToJoin) {
365
                elem.insertedToJoin = true;
366
            }
367
            try {
368
                insertInTable(outFeatStoreTable, elem.feat, iFeat);
369
                addFeatureToOutput(elem.feat.getDefaultGeometry(), elem.feat, iFeat);
370
            } catch (DataException e) {
371
                logger.info("Imposible insertar en la tabla", e);
372
            } catch (CreateGeometryException e) {
373
                logger.info("Error a?adiendo geometr?a", e);
374
            }
375
        } else {
376
            List<Geometry> listResult = new ArrayList<Geometry>();
377
            NodeTree subtree = new NodeTree(elem, null);
378
            //Hacemos un recorrido en profundidad del ?rbol para a?adir
379
            //todos los elementos a la lista de geometrias a unir sin
380
            //repetir ninguna.
381
            while (subtree != null) {
382
                if (!subtree.element.insertedToJoin) {
383
                    listResult.add(subtree.element.jtsGeom);
384
                    try {
385
                        insertInTable(outFeatStoreTable, subtree.element.feat, iFeat);
386
                    } catch (DataException e) {
387
                        logger.info("Imposible insertar en la tabla", e);
388
                    }
389
                    subtree.element.insertedToJoin = true;
390
                }
391

  
392
                boolean back = false;
393

  
394
                Element l = subtree.getNext();
395
                if (l == null) {
396
                    back = true;
397
                }
398

  
399
                while (!back && l.insertedToJoin) {
400
                    l = subtree.getNext();
401
                    if (l == null) {
402
                        back = true;
403
                    }
404
                }
405

  
406
                if (back) {
407
                    subtree = subtree.parent;
408
                    continue;
409
                }
410
                subtree = new NodeTree(l, subtree);
411
            }
412
            newGeom = computesUnion3(listResult);
413

  
414
            try {
415
                addFeatureToOutput(newGeom, elem.feat, iFeat);
416
            } catch (DataException e) {
417
                logger.info("Imposible insertar en la tabla", e);
418
            } catch (CreateGeometryException e) {
419
                logger.info("Error a?adiendo geometr?a", e);
420
            }
421
        }
422

  
423
    }
424

  
425
    /**
426
     * Adds a feature to the output
427
     *
428
     * @param newGeom
429
     * @param feat
430
     * @param newFeatID
431
     * @throws DataException
432
     * @throws CreateGeometryException
433
     */
434
    private void addFeatureToOutput(org.gvsig.fmap.geom.Geometry newGeom,
435
            Feature feat,
436
            int newFeatID) throws DataException, CreateGeometryException {
437
        //Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
438
        if (outFeatStoreTable != null) {
439
            lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
440
        } else {
441
            //Si no hay tabla se ponen todos los campos de la tabla de entrada
442
            String[] fieldNames = persister.getFieldNamesWithoutGeom();
443
            ArrayList<String> fields = new ArrayList<String>();
444
            ArrayList<Object> values = new ArrayList<Object>();
445
            fields.add(nameIdField);
446
            values.add(newFeatID);
447
            
448
            for (int j = 0; j < fieldNames.length; j++) {
449
                //Not add idfield, is not in the feature
450
                if (fieldNames[j].compareTo(nameIdField)==0) { 
451
                    continue;
452
                }
453
                Object obj = feat.get(fieldNames[j]);
454
                if (obj != null && fieldNames[j].compareTo(nameIdField) != 0) {
455
                    fields.add(fieldNames[j]);
456
                    values.add(obj);
457
                }
458
            }
459
            lastEditFeature = persister.addFeature(newGeom, fields, values);
460
        }
461
    }
462

  
463
    /**
464
     * Adds a feature to the output
465
     *
466
     * @param newGeom
467
     * @param feat
468
     * @param newFeatID
469
     * @throws DataException
470
     * @throws CreateGeometryException
471
     */
472
    private void addFeatureToOutput(Geometry newGeom,
473
            Feature feat,
474
            int newFeatID) throws DataException, CreateGeometryException {
475
        //Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
476
        if (outFeatStoreTable != null) {
477
            lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
478
        } else {
479
            //Si no hay tabla se ponen todos los campos de la tabla de entrada
480
            String[] fieldNames = persister.getFieldNamesWithoutGeom();
481
            ArrayList<String> fields = new ArrayList<String>();
482
            ArrayList<Object> values = new ArrayList<Object>();
483
            fields.add(nameIdField);
484
            values.add(newFeatID);
485
            for (int j = 0; j < fieldNames.length; j++) {
486
                if (fieldNames[j].compareTo(nameIdField) != 0) {
487
                    Object obj = feat.get(fieldNames[j]);
488
                    if (obj != null) {
489
                        fields.add(fieldNames[j]);
490
                        values.add(obj);
491
                    }
492
                }
493
            }
494

  
495
            lastEditFeature = persister.addFeature(newGeom, fields, values);
496
        }
497
    }
498

  
499
    /**
500
     * Insert in the output table a new feature with the fields of the input
501
     * feature. Moreover exists a field that is an identifier which is a
502
     * reference to the fusion layer.
503
     *
504
     * @param outFeatureStoreTable
505
     * @param f
506
     * @throws DataException
507
     */
508
    private void insertInTable(FeatureStore outFeatureStoreTable, Feature f, int reference) throws DataException {
509
        if (outFeatureStoreTable == null) {
510
            return;
511
        }
512
        EditableFeature edFeat = outFeatureStoreTable.createNewFeature();
513
        edFeat.set(nameIdField, reference);
514
        FeatureAttributeDescriptor[] attrList = f.getType().getAttributeDescriptors();
515
        for (int j = 0; j < attrList.length; j++) {
516
            if (attrList[j].getName().compareTo("GEOMETRY") != 0) {
517
                edFeat.set(attrList[j].getName(), f.get(attrList[j].getName()));
518
            }
519
        }
520
        outFeatureStoreTable.insert(edFeat);
521
    }
522

  
523
}
0 524

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.137/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyOperationFast3.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25

  
26
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
27
 *
28
 * Copyright (C) 2010 Generalitat Valenciana.
29
 *
30
 * This program is free software; you can redistribute it and/or
31
 * modify it under the terms of the GNU General Public License
32
 * as published by the Free Software Foundation; either version 2
33
 * of the License, or (at your option) any later version.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
 * GNU General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU General Public License
41
 * along with this program; if not, write to the Free Software
42
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
43
 */
44

  
45
package org.gvsig.geoprocess.algorithm.fusespatially;
46

  
47
import java.util.ArrayList;
48
import java.util.List;
49

  
50
import org.gvsig.fmap.dal.exception.DataException;
51
import org.gvsig.fmap.dal.feature.EditableFeature;
52
import org.gvsig.fmap.dal.feature.Feature;
53
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
54
import org.gvsig.fmap.dal.feature.FeatureSelection;
55
import org.gvsig.fmap.dal.feature.FeatureSet;
56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.geom.exception.CreateGeometryException;
58
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
59
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
60
import org.gvsig.geoprocess.algorithm.base.util.JTSFacade;
61
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

  
65
import com.vividsolutions.jts.geom.Geometry;
66
import java.util.Iterator;
67
/**
68
 * Fuse spatially operation
69
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
70
 */
71
public class FuseSpatiallyOperationFast3 extends GeometryOperation {
72
	private static Logger 			         logger    		    = LoggerFactory.getLogger(FuseSpatiallyOperationFast3.class.getName());
73
	private ArrayList<Element>               featureList        = null; 
74
	private String                           nameIdField        = null;
75
	private FeatureStore                     outFeatStoreTable  = null;
76
	private NodeTree                         baseTree           = null;
77
	
78
	class Element {
79
		public int                 id              = -1;
80
		public Feature             feat            = null;
81
		public List<Element>       overlapList     = new ArrayList<Element>();
82
		public boolean             insertedToJoin  = false;
83
		public Geometry            jtsGeom         = null;
84
	}
85
	
86
	class NodeTree {
87
		public Element       element     = null;
88
		public int           pos         = 0;
89
		public NodeTree       parent      = null;
90
		
91
		public NodeTree(Element node, NodeTree parent) {
92
			this.element = node;
93
			this.parent = parent;
94
		}
95
		
96
		public Element getNext() {
97
			if(pos < element.overlapList.size())
98
				return element.overlapList.get(pos++);
99
			return null;
100
		}
101
	}
102
	
103
	public FuseSpatiallyOperationFast3(AbstractSextanteGeoProcess process) {
104
		super(process);
105
		featureList = new ArrayList<Element>();
106
	}
107

  
108
	@Override
109
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g,
110
			Feature featureInput) {
111
		// TODO Auto-generated method stub
112
		return null;
113
	}
114

  
115
	@Override
116
	public void invoke(org.gvsig.fmap.geom.Geometry g,
117
			EditableFeature featureInput) {
118
		// TODO Auto-generated method stub
119
		
120
	}
121
	
122
	/**
123
	 * Computes a complete operation over the input FeatureStore. The result of this operation
124
	 * is stored in the output FeatureStore. This method will call once for each geometry.
125
	 * @param inFeatStore
126
	 *        Input FeatureStore
127
	 * @param outFeatStore
128
	 *        Output FeatureStore
129
	 * @param attrNames
130
	 *        List of attributes to build the output feature store
131
	 * @param selectedGeom
132
	 *        If it is true only the selected geometries will be processed
133
	 * @throws DataException
134
	 */
135
	@SuppressWarnings("deprecation")
136
	public void computesGeometryOperation(FeatureStore inFeatStore,
137
									FeatureStore outFeatStore,
138
									FeatureStore outFeatStoreTable,
139
									String[] attrNames,
140
									String[] attrNamesTable,
141
									boolean selectedGeomInput,
142
									boolean selectedGeomOutput,
143
									String idField) throws DataException {
144
		this.outFeatStoreTable = outFeatStoreTable;
145
		this.nameIdField = idField;
146
		this.inFeatureStore = inFeatStore;
147
		this.selectedGeomInput = selectedGeomInput;
148
		this.selectedGeomOverlay = selectedGeomOutput;
149
		FeatureSet featuresSet = null;
150
		featuresSet = inFeatStore.getFeatureSet();
151
		
152
		setFeatureStore(outFeatStore, attrNames);
153
		Iterator it = null;
154

  
155
		if(selectedGeomInput) {
156
            FeatureSelection ds = inFeatStore.getFeatureSelection();
157
            it = ds.iterator();
158
            numberOfFeatures = (int) ds.getSelectedCount();
159
		} else {
160
			it = featuresSet.iterator();
161
			numberOfFeatures = (int)featuresSet.getSize();
162
		}
163
		
164
        if (status != null) 
165
            status.setRangeOfValues(0, numberOfFeatures);
166
        if(process != null) 
167
            process.setProgress(0, numberOfFeatures);
168
		
169
        //Crear lista de elementos
170
		int iCount = 0;
171
		while( it.hasNext() && !process.getTaskMonitor().isCanceled()) {
172
			Feature feat = (Feature)it.next();
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff