Revision 1035

View differences:

org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.87/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.87/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.87/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.87/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.87/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.87/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.87/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.87/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
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) {
102
		try {
103
			Geometry jtsInputGeom = GeometryUtil.geomToJTS(g);
104
			insertInTable(feature);
105
			
106
			int cont = featList.size() - 1;
107
			while(cont >= 0 && !process.getTaskMonitor().isCanceled()) {
108
				Feature f = featList.get(cont);
109
				g = f.getDefaultGeometry();
110
				Geometry jtsGeom = GeometryUtil.geomToJTS(g); //Multigeometry support
111
				if(jtsGeom.intersects(jtsInputGeom)) {
112
					jtsInputGeom = jtsInputGeom.union(jtsGeom);
113
					featList.remove(cont);
114
					process.setProgress(procesSize - featList.size(), procesSize);
115
					cont = featList.size();
116
					insertInTable(f);
117
				}
118
				cont --;
119
			}
120

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

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

  
0 206

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.87/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

  
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 FuseSpatiallyOperationFast2 extends GeometryOperation {
72
	private static Logger 			         logger    		    = LoggerFactory.getLogger(FuseSpatiallyOperationFast2.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 FuseSpatiallyOperationFast2(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 outFeatStoreTable
130
	 * @param attrNames
131
	 *        List of attributes to build the output feature store
132
	 * @param attrNamesTable
133
	 * @param selectedGeomInput
134
	 * @param selectedGeomOutput
135
	 * @param idField
136
	 * @param selectedGeom
137
	 *        If it is true only the selected geometries will be processed
138
	 * @throws DataException
139
	 */
140
	@SuppressWarnings("deprecation")
141
	public void computesGeometryOperation(FeatureStore inFeatStore,
142
									FeatureStore outFeatStore,
143
									FeatureStore outFeatStoreTable,
144
									String[] attrNames,
145
									String[] attrNamesTable,
146
									boolean selectedGeomInput,
147
									boolean selectedGeomOutput,
148
									String idField) throws DataException {
149
		this.outFeatStoreTable = outFeatStoreTable;
150
		this.nameIdField = idField;
151
		this.inFeatureStore = inFeatStore;
152
		this.selectedGeomInput = selectedGeomInput;
153
		this.selectedGeomOverlay = selectedGeomOutput;
154
		FeatureSet featuresSet = null;
155
		featuresSet = inFeatStore.getFeatureSet();
156

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

  
160
		if(selectedGeomInput) {
161
            FeatureSelection ds = inFeatStore.getFeatureSelection();
162
            it = ds.iterator();
163
            numberOfFeatures = (int) ds.getSelectedCount();
164
		} else {
165
			it = featuresSet.iterator();
166
			numberOfFeatures = (int)featuresSet.getSize();
167
		}
168

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

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

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

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

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

  
226
			if(!elem1.insertedToJoin) {
227
				buildListToJoin(elem1, iFeat);
228
				iFeat ++;
229
			}
230

  
231
			iCount ++;
232
		}
233

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

  
237
	}
238

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

  
251
	/**
252
	 * Computes the union of the list of geometries
253
	 * @param listResult
254
	 * @param elem1
255
	 * @return
256
	 */
257
	private Geometry computesUnion(List<Geometry> listResult, Element elem1) {
258
		int splitValue = 500;
259
		Geometry newGeom = null;
260
		if(listResult.size() > splitValue) {
261
			List<List<Geometry>> list = splitList(listResult, splitValue);
262
			List<Geometry> result = new ArrayList<Geometry>();
263
			for (int i = 0; i < list.size(); i++) {
264
				Geometry aux = GeometryUtil.geometryUnion(list.get(i), elem1.feat.getDefaultGeometry().getGeometryType().getType());
265
				result.add(aux);
266
			}
267
			for (int i = 0; i < result.size(); i++) {
268
				newGeom = GeometryUtil.geometryUnion(result, elem1.feat.getDefaultGeometry().getGeometryType().getType());
269
			}
270
		} else {
271
			newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType());
272
		}
273
		return newGeom;
274
	}
275

  
276
	private Geometry computesUnion2(List<Geometry> listResult, Element elem1) {
277
		Geometry newGeom = null;
278
		for (int i = 1; i < listResult.size(); i++) {
279
			if(i == 1)
280
				newGeom = JTSFacade.union(listResult.get(0), listResult.get(1));
281
			else
282
				newGeom = JTSFacade.union(newGeom, listResult.get(i));
283
		}
284
		return newGeom;
285
	}
286

  
287
	private Geometry computesUnion3(List<Geometry> listResult) {
288
		Geometry newGeom = null;
289
		int iCount = 0;
290
		int max = listResult.size();
291
		if(process != null)
292
			process.setName("Generating union");
293
		while(listResult.size() > 1) {
294
			List<Geometry> list = new ArrayList<Geometry>();
295
			if (status != null)
296
                status.setCurValue(iCount);
297
            if(process != null)
298
                process.setProgress(iCount, max);
299
			for (int i = 0; i < listResult.size(); i = i + 2) {
300
				if(i == (listResult.size() - 1))
301
					list.add(listResult.get(i));
302
				else {
303
					newGeom = JTSFacade.union(listResult.get(i), listResult.get(i + 1));
304
					list.add(newGeom);
305
				}
306
			}
307
			listResult = list;
308
		}
309
		return newGeom;
310
	}
311

  
312
	/**
313
	 * Splits the array of geometries to compute its union because JTS cannot support
314
	 * a lot of geometries
315
	 * @param list
316
	 * @param n
317
	 * @return
318
	 */
319
	private List<List<Geometry>> splitList(List<Geometry> list, int n) {
320
		int elements = (int)(list.size() / n);
321
		List<List<Geometry>> l = new ArrayList<List<Geometry>>();
322
		for (int i = 0; i < elements; i++) {
323
			l.add(list.subList((i * n), (i * n) + n));
324
		}
325
		if(elements * n < list.size()) {
326
			l.add(list.subList((elements * n), list.size()));
327
		}
328
		return l;
329
	}
330

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

  
339
		if(elem.overlapList.size() == 0) {
340
			if(!elem.insertedToJoin)
341
				elem.insertedToJoin = true;
342
			try {
343
				insertInTable(outFeatStoreTable, elem.feat, iFeat);
344
				addFeatureToOutput(elem.feat.getDefaultGeometry(), elem.feat, iFeat);
345
			} catch (DataException e) {
346
				logger.info("Imposible insertar en la tabla", e);
347
			} catch (CreateGeometryException e) {
348
				logger.info("Error a?adiendo geometr?a", e);
349
			}
350
		} else {
351
			List<Geometry> listResult = new ArrayList<Geometry>();
352
			NodeTree subtree = new NodeTree(elem, null);
353
			//Hacemos un recorrido en profundidad del ?rbol para a?adir
354
			//todos los elementos a la lista de geometrias a unir sin
355
			//repetir ninguna.
356
			while (subtree != null) {
357
				if(!subtree.element.insertedToJoin) {
358
					listResult.add(subtree.element.jtsGeom);
359
					try {
360
						insertInTable(outFeatStoreTable, subtree.element.feat, iFeat);
361
					} catch (DataException e) {
362
						logger.info("Imposible insertar en la tabla", e);
363
					}
364
					subtree.element.insertedToJoin = true;
365
				}
366

  
367
				boolean back = false;
368

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

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

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

  
387
			try {
388
				addFeatureToOutput(newGeom, elem.feat, iFeat);
389
			} catch (DataException e) {
390
				logger.info("Imposible insertar en la tabla", e);
391
			} catch (CreateGeometryException e) {
392
				logger.info("Error a?adiendo geometr?a", e);
393
			}
394
		}
395

  
396
	}
397

  
398
	/**
399
	 * Adds a feature to the output
400
	 * @param newGeom
401
	 * @param feat
402
	 * @param newFeatID
403
	 * @throws DataException
404
	 * @throws CreateGeometryException
405
	 */
406
	private void addFeatureToOutput(org.gvsig.fmap.geom.Geometry newGeom,
407
			Feature feat,
408
			int newFeatID) throws DataException, CreateGeometryException {
409
		//Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
410
		if(outFeatStoreTable != null) {
411
			lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
412
		} else {
413
			//Si no hay tabla se ponen todos los campos de la tabla de entrada
414
			String[] fieldNames = persister.getFieldNamesWithoutGeom();
415
			ArrayList<String> fields = new ArrayList<String>();
416
			ArrayList<Object> values = new ArrayList<Object>();
417
			fields.add(nameIdField);
418
			values.add(newFeatID);
419
			for (int j = 0; j < fieldNames.length; j++) {
420
				Object obj = feat.get(fieldNames[j]);
421
				if(obj != null && fieldNames[j].compareTo(nameIdField) != 0) {
422
					fields.add(fieldNames[j]);
423
					values.add(obj);
424
				}
425
			}
426
			lastEditFeature = persister.addFeature(newGeom, fields, values);
427
		}
428
	}
429

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

  
462
	/**
463
	 * Insert in the output table a new feature with the fields of the input feature. Moreover
464
	 * exists a field that is an identifier which is a reference to the fusion layer.
465
	 * @param outFeatureStoreTable
466
	 * @param f
467
	 * @throws DataException
468
	 */
469
	private void insertInTable(FeatureStore outFeatureStoreTable, Feature f, int reference) throws DataException {
470
		if(outFeatureStoreTable == null)
471
			return;
472
		EditableFeature edFeat = outFeatureStoreTable.createNewFeature();
473
		edFeat.set(nameIdField, reference);
474
		FeatureAttributeDescriptor[] attrList = f.getType().getAttributeDescriptors();
475
		for (int j = 0; j < attrList.length; j++) {
476
			if(attrList[j].getName().compareTo("GEOMETRY") != 0) {
477
				edFeat.set(attrList[j].getName(), f.get(attrList[j].getName()));
478
			}
479
		}
480
		outFeatureStoreTable.insert(edFeat);
481
	}
482

  
483
}
484

  
0 485

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

Also available in: Unified diff