Revision 1137

View differences:

org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.102/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.102/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.102/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.102/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.102/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.102/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.102/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
            for (int j = 0; j < fieldNames.length; j++) {
448
                Object obj = feat.get(fieldNames[j]);
449
                if (obj != null && fieldNames[j].compareTo(nameIdField) != 0) {
450
                    fields.add(fieldNames[j]);
451
                    values.add(obj);
452
                }
453
            }
454
            lastEditFeature = persister.addFeature(newGeom, fields, values);
455
        }
456
    }
457

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

  
490
            lastEditFeature = persister.addFeature(newGeom, fields, values);
491
        }
492
    }
493

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

  
518
}
0 519

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

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

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

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

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

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

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

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

  
155
		if(selectedGeomInput) {
156
            FeatureSelection ds = inFeatStore.getFeatureSelection();
157
            it = ds.iterator();
158
            numberOfFeatures = (int) ds.getSelectedCount();
159
		} else {
160
			it = featuresSet.iterator();
161
			numberOfFeatures = (int)featuresSet.getSize();
162
		}
163
		
164
        if (status != null) 
165
            status.setRangeOfValues(0, numberOfFeatures);
166
        if(process != null) 
167
            process.setProgress(0, numberOfFeatures);
168
		
169
        //Crear lista de elementos
170
		int iCount = 0;
171
		while( it.hasNext() && !process.getTaskMonitor().isCanceled()) {
172
			Feature feat = (Feature)it.next();
173
			Element el = new Element();
174
			el.feat = feat;
175
			el.id = iCount;
176
			featureList.add(el);
177
            if (status != null && process != null) 
178
                status.setCurValue(iCount);
179
            if(process != null) 
180
                process.setProgress(iCount, numberOfFeatures);
181
			iCount ++;
182
		}
183
//		it.dispose();
184
		
185
		//Crear listas de solapes para cada feature
186
		iCount = 0;
187
		while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
188
			Element elem1 = featureList.get(iCount);
189
			org.gvsig.fmap.geom.Geometry geom1 = elem1.feat.getDefaultGeometry();
190
			if (status != null)  
191
                status.setCurValue(iCount);
192
            if(process != null)
193
                process.setProgress(iCount, numberOfFeatures);
194
            
195
			for (int i = iCount + 1; i < featureList.size(); i++) {
196
				Element elem2 = featureList.get(i);
197
				org.gvsig.fmap.geom.Geometry geom2 = elem2.feat.getDefaultGeometry();
198
				if(areBBoxesOverlaping(geom1, geom2)) {
199
					if(elem1.jtsGeom == null)
200
						elem1.jtsGeom = GeometryUtil.geomToJTS(geom1);
201
					elem2.jtsGeom = GeometryUtil.geomToJTS(geom2);
202
					if(elem1.jtsGeom.intersects(elem2.jtsGeom))	{
203
						elem1.overlapList.add(elem2);
204
						elem2.overlapList.add(elem1);
205
					}
206
				}
207
			}
208
			iCount ++;
209
		}
210
		
211
		iCount = 0;
212
		int iFeat = 0;
213
		while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) {
214
			Element elem1 = featureList.get(iCount);
215
			if (status != null) 
216
                status.setCurValue(iCount);
217
            if(process != null) 
218
                process.setProgress(iCount, numberOfFeatures);
219
      
220
			if(!elem1.insertedToJoin) {
221
				buildListToJoin(elem1, iFeat);
222
				iFeat ++;
223
			}
224
			iCount ++;
225
		}
226

  
227
		if(persister != null)
228
			persister.end();
229
		
230
	}
231
	
232
	private boolean areBBoxesOverlaping(org.gvsig.fmap.geom.Geometry g1, org.gvsig.fmap.geom.Geometry g2) {
233
		if(g1.getEnvelope().getMaximum(0) < g2.getEnvelope().getMinimum(0))
234
			return false;
235
		if(g1.getEnvelope().getMinimum(0) > g2.getEnvelope().getMaximum(0))
236
			return false;
237
		if(g1.getEnvelope().getMaximum(1) < g2.getEnvelope().getMinimum(1))
238
			return false;
239
		if(g1.getEnvelope().getMinimum(1) > g2.getEnvelope().getMaximum(1))
240
			return false;
241
		return true;
242
	}
243
	
244
	/**
245
	 * Computes the union of the list of geometries
246
	 * @param listResult
247
	 * @param elem1
248
	 * @return
249
	 */
250
	private Geometry computesUnion(List<Geometry> listResult, Element elem1) {
251
		int splitValue = 500;
252
		Geometry newGeom = null;
253
		if(listResult.size() > splitValue) {
254
			List<List<Geometry>> list = splitList(listResult, splitValue);
255
			List<Geometry> result = new ArrayList<Geometry>();
256
			for (int i = 0; i < list.size(); i++) {
257
				Geometry aux = GeometryUtil.geometryUnion(list.get(i), elem1.feat.getDefaultGeometry().getGeometryType().getType());
258
				result.add(aux);
259
			}
260
			for (int i = 0; i < result.size(); i++) {
261
				newGeom = GeometryUtil.geometryUnion(result, elem1.feat.getDefaultGeometry().getGeometryType().getType());
262
			}
263
		} else {
264
			newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType());	
265
		}
266
		return newGeom;
267
	}
268
	
269
	private Geometry computesUnion2(List<Geometry> listResult, Element elem1) {
270
		Geometry newGeom = null;
271
		for (int i = 1; i < listResult.size(); i++) {
272
			if(i == 1)
273
				newGeom = JTSFacade.union(listResult.get(0), listResult.get(1));
274
			else
275
				newGeom = JTSFacade.union(newGeom, listResult.get(i));
276
		}
277
		return newGeom;
278
	}
279
	
280
	private Geometry computesUnion3(List<Geometry> listResult) {
281
		Geometry newGeom = null;
282
		int iCount = 0;
283
		int max = listResult.size();
284
		if(process != null)
285
			process.setName("Generating union");
286
		while(listResult.size() > 1) {
287
			List<Geometry> list = new ArrayList<Geometry>();
288
			if (status != null)  
289
                status.setCurValue(iCount);
290
            if(process != null)
291
                process.setProgress(iCount, max);
292
			for (int i = 0; i < listResult.size(); i = i + 2) {
293
				if(i == (listResult.size() - 1))
294
					list.add(listResult.get(i));
295
				else {
296
					newGeom = JTSFacade.union(listResult.get(i), listResult.get(i + 1));
297
					list.add(newGeom);
298
				}
299
			}
300
			listResult = list;
301
		}
302
		return newGeom;
303
	}
304
	
305
	/**
306
	 * Splits the array of geometries to compute its union because JTS cannot support
307
	 * a lot of geometries
308
	 * @param list
309
	 * @param n
310
	 * @return
311
	 */
312
	private List<List<Geometry>> splitList(List<Geometry> list, int n) {
313
		int elements = (int)(list.size() / n);
314
		List<List<Geometry>> l = new ArrayList<List<Geometry>>();
315
		for (int i = 0; i < elements; i++) {
316
			l.add(list.subList((i * n), (i * n) + n));
317
		}
318
		if(elements * n < list.size()) {
319
			l.add(list.subList((elements * n), list.size()));
320
		}
321
		return l;
322
	}
323
	
324
	/**
325
	 * Builds the union of all lists 
326
	 * @param listResult
327
	 * @param listToJoin
328
	 */
329
	private void buildListToJoin(Element elem, int iFeat) {
330
		Geometry newGeom = null;
331
		
332
		if(elem.overlapList.size() == 0) {
333
			if(!elem.insertedToJoin)
334
				elem.insertedToJoin = true;
335
			newGeom = elem.jtsGeom;
336
		} else {
337
			List<Geometry> listResult = new ArrayList<Geometry>();
338
			NodeTree subtree = new NodeTree(elem, null);
339
			//Hacemos un recorrido en profundidad del ?rbol para a?adir
340
			//todos los elementos a la lista de geometrias a unir sin
341
			//repetir ninguna.
342
			while (subtree != null) {
343
				if(!subtree.element.insertedToJoin) {
344
					listResult.add(subtree.element.jtsGeom);
345
					subtree.element.insertedToJoin = true;
346
				}
347
				
348
				boolean back = false;
349
				
350
				Element l = subtree.getNext();
351
				if(l == null) 
352
					back = true;
353
				
354
				while(!back && l.insertedToJoin) {
355
					l = subtree.getNext();
356
					if(l == null) 
357
						back = true;
358
				}
359
				
360
				if(back) {
361
					subtree = subtree.parent;
362
					continue;
363
				}
364
				
365
				subtree = new NodeTree(l, subtree);
366
			}
367
			
368
			newGeom = computesUnion3(listResult);
369
		}
370
		
371
		try {
372
			insertInTable(outFeatStoreTable, elem.feat, iFeat);
373
			addFeatureToOutput(newGeom, elem.feat, iFeat);
374
		} catch (DataException e) {
375
			logger.info("Imposible insertar en la tabla", e);
376
		} catch (CreateGeometryException e) {
377
			logger.info("Error a?adiendo geometr?a", e);
378
		}
379
		
380
	}
381
	
382
	/**
383
	 * Adds a feature to the output
384
	 * @param newGeom
385
	 * @param feat
386
	 * @param newFeatID
387
	 * @throws DataException
388
	 * @throws CreateGeometryException
389
	 */
390
	private void addFeatureToOutput(Geometry newGeom, 
391
			Feature feat, 
392
			int newFeatID) throws DataException, CreateGeometryException {
393
		//Si hay una tabla aparte esta capa solo lleva el id como referencia a la tabla de campos
394
		if(outFeatStoreTable != null) { 
395
			lastEditFeature = persister.addFeature(newGeom, nameIdField, newFeatID);
396
		} else {
397
			//Si no hay tabla se ponen todos los campos de la tabla de entrada
398
			String[] fieldNames = persister.getFieldNamesWithoutGeom();
399
			ArrayList<String> fields = new ArrayList<String>();
400
			ArrayList<Object> values = new ArrayList<Object>();
401
			fields.add(nameIdField);
402
			values.add(newFeatID);
403
			for (int j = 0; j < fieldNames.length; j++) {
404
				Object obj = feat.get(fieldNames[j]);
405
				if(obj != null && fieldNames[j].compareTo(nameIdField) != 0) {
406
					fields.add(fieldNames[j]);
407
					values.add(obj);
408
				}
409
			}
410
			lastEditFeature = persister.addFeature(newGeom, fields, values);
411
		}
412
	}
413
	
414
	/**
415
	 * Insert in the output table a new feature with the fields of the input feature. Moreover 
416
	 * exists a field that is an identifier which is a reference to the fusion layer.
417
	 * @param outFeatureStoreTable
418
	 * @param f
419
	 * @throws DataException
420
	 */
421
	private void insertInTable(FeatureStore outFeatureStoreTable, Feature f, int reference) throws DataException {
422
		if(outFeatureStoreTable == null)
423
			return;
424
		EditableFeature edFeat = outFeatureStoreTable.createNewFeature();
425
		edFeat.set(nameIdField, reference);
426
		FeatureAttributeDescriptor[] attrList = f.getType().getAttributeDescriptors();
427
		for (int j = 0; j < attrList.length; j++) {
428
			if(attrList[j].getName().compareTo("GEOMETRY") != 0) {
429
				edFeat.set(attrList[j].getName(), f.get(attrList[j].getName()));
430
			}
431
		}
432
		outFeatureStoreTable.insert(edFeat);
433
	}
434
	
435
}
436

  
0 437

  
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.102/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyLibrary.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
package org.gvsig.geoprocess.algorithm.fusespatially;
25

  
26
import org.gvsig.geoprocess.algorithm.base.core.AlgorithmAbstractLibrary;
27
import org.gvsig.i18n.Messages;
28
import org.gvsig.tools.library.LibraryException;
29

  
30
/**
31
 * Initialization of FuseSpatiallyLibrary library.
32
 * 
33
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
34
 */
35
public class FuseSpatiallyLibrary extends AlgorithmAbstractLibrary {
36

  
37
    @Override
38
    protected void doInitialize() throws LibraryException {
39

  
40
    }
41

  
42
    @Override
43
    protected void doPostInitialize() throws LibraryException {
44
        Messages.addResourceFamily(
45
            "org.gvsig.geoprocess.algorithm.fusespatially.fusespatially",
46
            FuseSpatiallyLibrary.class.getClassLoader(), FuseSpatiallyLibrary.class
47
                .getClass().getName());
48

  
49
        registerGeoProcess(new FuseSpatiallyAlgorithm());
50
    }
51

  
52
}
0 53

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff