Revision 1206

View differences:

org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.115/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/resources/help/FuseSpatiallyAlgorithm.xml
1
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
2
<!--
3

  
4
    gvSIG. Desktop Geographic Information System.
5

  
6
    Copyright (C) 2007-2012 gvSIG Association.
7

  
8
    This program is free software; you can redistribute it and/or
9
    modify it under the terms of the GNU General Public License
10
    as published by the Free Software Foundation; either version 2
11
    of the License, or (at your option) any later version.
12

  
13
    This program is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
    GNU General Public License for more details.
17

  
18
    You should have received a copy of the GNU General Public License
19
    along with this program; if not, write to the Free Software
20
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21
    MA  02110-1301, USA.
22

  
23
    For any additional information, do not hesitate to contact us
24
    at info AT gvsig.com, or visit our website www.gvsig.com.
25

  
26
-->
27
	<help>
28
		<element name="DESCRIPTION" text="Este geoproceso act&#250;a sobre una sola capa de entrada, cuyo tipo de geometr&#237;a ha de ser forzosamente de pol&#237;gonos. El proceso analiza cada pol&#237;gono de la capa de entrada, de tal forma que fusionar&#225; en un solo pol&#237;gono aquellos pol&#237;gonos que coincidan espacialmente, es decir que intersequen entre ellos. La tabla de atributos de los pol?gonos resultantes estar? formada por un campo ID que ser? el identificador del fen?meno. <BR> Adicionalmente se crear? otra capa que contendr? ?nicamente informaci?n alfanum?rica con la tabla de datos de la capa de origen. Adem?s incluir? un campo ID en el que tendr? la referencia al ID de la capa de pol?gonos creada. De esta forma, cada pol?gono har? referencia con su ID a una o varias entradas de la capa unicamente alfanum?rica para identificar la informaci?n asociada originalmente a cada pol?gono de la capa." description="Descripci&#243;n" type="0">
29
			<image description="" file="fusespatiallydesc.png">
30
			</image>
31
		</element>
32
		<element name="ADDITIONAL_INFO" text="" description="Informaci&#243;n adicional" type="0">
33
		</element>
34
		<element name="EXTENSION_AUTHOR" text="Nacho Brodin" description="Algoritmo creado por" type="0">
35
		</element>
36
		<element name="HELP_AUTHOR" text="" description="Ayuda creada por" type="0">
37
		</element>
38
		<element name="USER_NOTES" text="" description="Notas de usuario" type="0">
39
		</element>
40
		<element name="LAYER" text="" description="Capa de entrada" type="3">
41
		</element>
42
		<element name="SELECTED_GEOM" text="" description="Geometrias seleccionadas" type="3">
43
		</element>
44
		<element name="DISSOLV_ADJ" text="" description="Geometrias seleccionadas" type="3">
45
		</element>
46
		<element name="FIELD" text="" description="Campo" type="3">
47
		</element>
48
		<element name="FUNCTION_LIST" text="" description="Lista de funciones" type="3">
49
		</element>
50
		<element name="OUTPUT_DESCRIPTION" text="" description="Descripci&#243;n" type="2">
51
		</element>
52
		<element name="RESULT" text="" description="Disolver" type="2">
53
		</element>
54
	</help>
55
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
0 56

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.115/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/resources/help/FuseSpatiallyAlgorithm_en.xml
1
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
2
<!--
3

  
4
    gvSIG. Desktop Geographic Information System.
5

  
6
    Copyright (C) 2007-2012 gvSIG Association.
7

  
8
    This program is free software; you can redistribute it and/or
9
    modify it under the terms of the GNU General Public License
10
    as published by the Free Software Foundation; either version 2
11
    of the License, or (at your option) any later version.
12

  
13
    This program is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
    GNU General Public License for more details.
17

  
18
    You should have received a copy of the GNU General Public License
19
    along with this program; if not, write to the Free Software
20
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21
    MA  02110-1301, USA.
22

  
23
    For any additional information, do not hesitate to contact us
24
    at info AT gvsig.com, or visit our website www.gvsig.com.
25

  
26
-->
27
	<help>
28
		<element name="DESCRIPTION" text="This geoprocess works with one only input layer, whose geometry type must be polygon. This process analize each input geometry and builds a unique polygon with all geometries which intersects each other. The attribute table will have an identifier field of each feature. <BR> Furthermore, other layer with only alphanumeric data will be created. This alphanumeric table will contain the table of the input layer and it will include a identifier field with a reference to the polygon in the first layer. In this way, each polygon in the first layer will have a reference to each feature in the second layer." description="Descripci&#243;n" type="0">
29
			<image description="" file="fusespatiallydesc.png">
30
			</image>
31
		</element>
32
		<element name="ADDITIONAL_INFO" text="" description="Informaci&#243;n adicional" type="0">
33
		</element>
34
		<element name="EXTENSION_AUTHOR" text="Nacho Brodin" description="Algoritmo creado por" type="0">
35
		</element>
36
		<element name="HELP_AUTHOR" text="" description="Ayuda creada por" type="0">
37
		</element>
38
		<element name="USER_NOTES" text="" description="Notas de usuario" type="0">
39
		</element>
40
		<element name="LAYER" text="" description="Capa de entrada" type="3">
41
		</element>
42
		<element name="SELECTED_GEOM" text="" description="Geometrias seleccionadas" type="3">
43
		</element>
44
		<element name="DISSOLV_ADJ" text="" description="Geometrias seleccionadas" type="3">
45
		</element>
46
		<element name="FIELD" text="" description="Campo" type="3">
47
		</element>
48
		<element name="FUNCTION_LIST" text="" description="Lista de funciones" type="3">
49
		</element>
50
		<element name="OUTPUT_DESCRIPTION" text="" description="Descripci&#243;n" type="2">
51
		</element>
52
		<element name="RESULT" text="" description="Disolver" type="2">
53
		</element>
54
	</help>
55
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
0 56

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.115/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/resources/META-INF/services/org.gvsig.tools.library.Library
1
org.gvsig.geoprocess.algorithm.fusespatially.FuseSpatiallyLibrary
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.115/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/resources/org/gvsig/geoprocess/algorithm/fusespatially/fusespatially.properties
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
basic_vect_algorithms=Capas vectoriales
26
Input_layer=Capa de entrada
27
Selected_geometries_fuse=Geom. seleccionadas (Capa entrada)
28
Field=Campo
29
Function_list=Lista de funciones
30
fusespatially=Fusionar espacialmente
31
fuse_spatially=Fusionar espacialmente
32
summary_function=Funci?n resumen
33
adjacent_geometries_only=Solo geometrias adyacentes
0 34

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.115/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/resources/org/gvsig/geoprocess/algorithm/fusespatially/fusespatially_en.properties
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
basic_vect_algorithms=Vector layers tools
26
Input_layer=Input cover
27
Selected_geometries_fuse=Selected geometries (Input cover)
28
Field=Field
29
Function_list=Function list
30
fusespatially=Fuse spatially
31
fuse_spatially=Fuse spatially
32
summary_function=Summary function
33
adjacent_geometries_only=Only dissolve adjacent
34
groupby=Group by a field
0 35

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.115/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.115/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.115/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.115/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
     *
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff