Revision 639 org.gvsig.geoprocess/trunk/org.gvsig.geoprocess/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.fusespatially/src/main/java/org/gvsig/geoprocess/algorithm/fusespatially/FuseSpatiallyAlgorithm.java

View differences:

FuseSpatiallyAlgorithm.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 java.util.ArrayList;
27
import java.util.List;
28

  
29
import org.gvsig.fmap.dal.exception.DataException;
30
import org.gvsig.fmap.dal.feature.Feature;
31
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
32
import org.gvsig.fmap.dal.feature.FeatureSet;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.geoprocess.algorithm.dissolve.DissolveAlgorithm;
35
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
36
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
37
import org.gvsig.tools.dispose.DisposableIterator;
38
import org.gvsig.tools.task.SimpleTaskStatus;
39

  
40
import es.unex.sextante.core.Sextante;
41
import es.unex.sextante.dataObjects.IVectorLayer;
42
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
43
import es.unex.sextante.exceptions.RepeatedParameterNameException;
44
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
45
import es.unex.sextante.outputs.OutputVectorLayer;
46

  
47
/**
48
 * Fuse spatially algorithm
49
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
50
 */
51
public class FuseSpatiallyAlgorithm extends AbstractSextanteGeoProcess {
52

  
53
	public static final String         RESULT            = "RESULT";
54
	public static final String         RESULT_TABLE      = "RESULT_TABLE";
55
	public static final String         LAYER             = "LAYER";
56
	public static final String         SELECTED_GEOM     = "SELECTED_GEOM";
57
	private AbstractSextanteGeoProcess process           = null;
58
	private String                     fid               = "FID";
59

  
60
	/*
61
	 * (non-Javadoc)
62
	 * @see es.unex.sextante.core.GeoAlgorithm#defineCharacteristics()
63
	 */
64
	public void defineCharacteristics(){
65
        setName(getTranslation("fusespatially"));
66
        setGroup(getTranslation("basic_vect_algorithms"));
67
        // setGeneratesUserDefinedRasterOutput(false);
68
		try {
69
			m_Parameters.addInputVectorLayer(LAYER, getTranslation("Input_layer"), IVectorLayer.SHAPE_TYPE_WRONG, true);
70
			m_Parameters.addBoolean(SELECTED_GEOM, getTranslation("Selected_geometries_fuse"), false);
71
			addOutputVectorLayer(RESULT, getTranslation("fuse_spatially"), OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
72
			addOutputVectorLayer(RESULT_TABLE, getTranslation("fuse_spatially") + "_Table", OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
73
		} catch (RepeatedParameterNameException e) {
74
			Sextante.addErrorToLog(e);
75
		}
76
	}
77
	
78
	public void setParentProcess(AbstractSextanteGeoProcess process) {
79
		this.process = process;
80
	}
81
	
82
	/*
83
	 * (non-Javadoc)
84
	 * @see es.unex.sextante.core.GeoAlgorithm#processAlgorithm()
85
	 */
86
	@SuppressWarnings("unchecked")
87
	public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
88
		if(existsOutPutFile(DissolveAlgorithm.RESULT, 0)) {
89
    		throw new GeoAlgorithmExecutionException(getTranslation("file_exists"));
90
    	}
91
		IVectorLayer layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
92
		boolean selectedGeom = m_Parameters.getParameterValueAsBoolean(SELECTED_GEOM);
93
		
94
		FeatureStore storeLayer = null;
95
		if(layer instanceof FlyrVectIVectorLayer)
96
			storeLayer = ((FlyrVectIVectorLayer)layer).getFeatureStore();
97
		else
98
			return false;
99
		
100
		try {
101
			String[] attrNames = new String[]{"FID"};
102
			Class[] types = new Class[] {Integer.class};
103

  
104
			FeatureStore outFeatStore = buildFuseSpatiallyOutPutStore(attrNames, types,
105
					layer.getShapeType(), getTranslation("fusespatially"), RESULT);
106
			
107
			return execute(storeLayer, outFeatStore, layer.getShapeType(), selectedGeom, getStatus(), "FID", true);
108
		} catch (DataException e) {
109
			Sextante.addErrorToLog(e);
110
			return false;
111
		}
112
	}
113
	
114
	public boolean execute(FeatureStore inputStoreLayer, 
115
			FeatureStore outFeatStore,
116
			int shapeType, 
117
			boolean selectedGeom, 
118
			SimpleTaskStatus status, 
119
			String idField,
120
			boolean createTable) throws DataException {
121
		FeatureStore outFeatStoreTable = null;
122
		String[] attrNamesTable = null;
123
		if(createTable) {
124
			attrNamesTable = new String[inputStoreLayer.getDefaultFeatureType().size() + 1];
125
			Class[] typesTable = new Class[inputStoreLayer.getDefaultFeatureType().size() + 1];
126
			attrNamesTable[0] = fid;
127
			typesTable[0] = Integer.class;
128
			for (int i = 0; i < inputStoreLayer.getDefaultFeatureType().size(); i++) {
129
				FeatureAttributeDescriptor attrDesc = inputStoreLayer.getDefaultFeatureType().getAttributeDescriptor(i);
130
				attrNamesTable[i + 1] = attrDesc.getName();
131
				typesTable[i + 1] = attrDesc.getDataType().getDefaultClass();
132
			}
133
			
134
			attrNamesTable = checkFields(attrNamesTable);
135
			outFeatStoreTable = buildFuseSpatiallyOutPutStore(attrNamesTable, typesTable,
136
				shapeType, getTranslation("fusespatially") + "_Table", RESULT_TABLE);
137
		}
138

  
139
		FuseSpatiallyOperationFast2 operation = new FuseSpatiallyOperationFast2(this);
140
		operation.setTaskStatus(getStatus());
141
		operation.computesGeometryOperation(inputStoreLayer, 
142
				outFeatStore, 
143
				outFeatStoreTable,
144
				new String[]{fid}, 
145
				attrNamesTable,
146
				selectedGeom,
147
				false,
148
				idField);
149
		
150
		if(getTaskMonitor().isCanceled())
151
			return false;
152
		/*computesGeometryOperation(inputStoreLayer, outFeatStore, outFeatStoreTable, 
153
				attrNames, attrNamesTable, selectedGeom, status, idField);*/
154
		return true;
155
	}
156
	
157
	/**
158
	 * Removes duplicate fields
159
	 * @param names
160
	 * @return
161
	 */
162
	public String[] checkFields(String[] names) {
163
		if(names.length <= 1)
164
			return names;
165
		int cont = 0;
166

  
167
		int i = 1;
168
		while(i < names.length) {
169
			if(names[0].compareTo(names[i]) == 0) {
170
				names[0] = "FID_" + cont;
171
				i = 0;
172
				cont ++;
173
			}
174
			i ++;
175
		}
176
		return names;
177
	}
178
	
179
	
180
	/**
181
	 * Computes a complete operation over the input FeatureStore. The result of this operation
182
	 * is stored in the output FeatureStore. This method will call once for each geometry.
183
	 * @param inFeatStore
184
	 *        Input FeatureStore
185
	 * @param outFeatStore
186
	 *        Output FeatureStore
187
	 * @param attrNames
188
	 *        List of attributes to build the output feature store
189
	 * @param selectedGeom
190
	 *        If it is true only the selected geometries will be processed
191
	 * @deprecated This method uses FuseSpatiallyOperation which is deprecated
192
	 * @throws DataException
193
	 */
194
	@SuppressWarnings("deprecation")
195
	public void computesGeometryOperation(FeatureStore inFeatStore,
196
									FeatureStore outFeatStore,
197
									FeatureStore outFeatStoreTable,
198
									String[] attrNames,
199
									String[] attrNamesTable,
200
									boolean selectedGeom,
201
									SimpleTaskStatus status,
202
									String idField) throws DataException {
203
		FeatureSet featuresSet = null;
204
		DisposableIterator it = null;
205

  
206
		if(selectedGeom) {
207
			featuresSet = (FeatureSet)inFeatStore.getSelection();
208
		} else {
209
			featuresSet = inFeatStore.getFeatureSet();
210
		}
211
		
212
		it = featuresSet.iterator();
213
		int numberOfFeatures = (int)featuresSet.getSize();
214
        if (status != null) {
215
            status.setRangeOfValues(0, numberOfFeatures);
216
        }
217
		
218
        //Stack<Feature> featList = new Stack<Feature>();
219
        List<Feature> featList = new ArrayList<Feature>();
220
		while( it.hasNext() ) {
221
			Feature feature = (Feature)it.next();
222
			featList.add(feature);
223
		}
224

  
225
		
226
		FuseSpatiallyOperation operation = new FuseSpatiallyOperation(featList, 
227
				outFeatStoreTable, 
228
				attrNamesTable, 
229
				idField, 
230
				this);
231
		operation.setFeatureStore(outFeatStore, attrNames);
232
		int size = featList.size();
233
		operation.setGeoProcess(this, size);
234
		
235
		while (featList.size() > 0 && !m_Task.isCanceled()) {
236
			Feature f = featList.remove(featList.size() - 1);	
237
			operation.invoke(f.getDefaultGeometry(), f);
238
			setProgress(size - featList.size(), size);
239
		}
240

  
241
		if(operation.getWriter() != null)
242
			operation.getWriter().end();
243
	}
244
	
245
	public boolean setProgress(int step, int size) {
246
		if(process != null)
247
			return process.setProgress(step, size);
248
		else
249
			return super.setProgress(step, size);
250
	}
251
	
252
	/**
253
	 * Builds the output FeatureStore 
254
	 * @param featureType
255
	 * @return FeatureStore
256
	 */
257
	@SuppressWarnings("unchecked")
258
	protected FeatureStore buildFuseSpatiallyOutPutStore(String[] attrNames,
259
											Class[] types,
260
											int shapeType,
261
											String sextanteLayerName, 
262
											String sextanteLayerLabel) {
263

  
264
		
265
		try {
266
			IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
267
													sextanteLayerName,
268
													shapeType, types, attrNames);
269
			return ((FlyrVectIVectorLayer)output).getFeatureStore();
270
		} catch (UnsupportedOutputChannelException e) {
271
			Sextante.addErrorToLog(e);
272
        } catch (GeoAlgorithmExecutionException e) {
273
            Sextante.addErrorToLog(e);
274
        }
275
		return null;
276
	}
277

  
278
}
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 java.util.ArrayList;
27
import java.util.List;
28

  
29
import org.gvsig.fmap.dal.exception.DataException;
30
import org.gvsig.fmap.dal.feature.Feature;
31
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
32
import org.gvsig.fmap.dal.feature.FeatureSet;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.geoprocess.algorithm.dissolve.DissolveAlgorithm;
35
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
36
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
37
import org.gvsig.tools.dispose.DisposableIterator;
38
import org.gvsig.tools.task.SimpleTaskStatus;
39

  
40
import es.unex.sextante.core.Sextante;
41
import es.unex.sextante.dataObjects.IVectorLayer;
42
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
43
import es.unex.sextante.exceptions.RepeatedParameterNameException;
44
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
45
import es.unex.sextante.outputs.OutputVectorLayer;
46

  
47
/**
48
 * Fuse spatially algorithm
49
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
50
 */
51
public class FuseSpatiallyAlgorithm extends AbstractSextanteGeoProcess {
52

  
53
	public static final String         RESULT            = "RESULT";
54
	public static final String         RESULT_TABLE      = "RESULT_TABLE";
55
	public static final String         LAYER             = "LAYER";
56
	public static final String         SELECTED_GEOM     = "SELECTED_GEOM";
57
	private AbstractSextanteGeoProcess process           = null;
58
	private String                     fid               = "FID";
59

  
60
	/*
61
	 * (non-Javadoc)
62
	 * @see es.unex.sextante.core.GeoAlgorithm#defineCharacteristics()
63
	 */
64
	public void defineCharacteristics(){
65
        setName(getTranslation("fusespatially"));
66
        setGroup(getTranslation("basic_vect_algorithms"));
67
        // setGeneratesUserDefinedRasterOutput(false);
68
		try {
69
			m_Parameters.addInputVectorLayer(LAYER, getTranslation("Input_layer"), IVectorLayer.SHAPE_TYPE_WRONG, true);
70
			m_Parameters.addBoolean(SELECTED_GEOM, getTranslation("Selected_geometries_fuse"), false);
71
			addOutputVectorLayer(RESULT, getTranslation("fuse_spatially") + " ", OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
72
			addOutputVectorLayer(RESULT_TABLE, getTranslation("fuse_spatially") + "_" + getTranslation("Table") + " ", OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
73
		} catch (RepeatedParameterNameException e) {
74
			Sextante.addErrorToLog(e);
75
		}
76
	}
77
	
78
	public void setParentProcess(AbstractSextanteGeoProcess process) {
79
		this.process = process;
80
	}
81
	
82
	/*
83
	 * (non-Javadoc)
84
	 * @see es.unex.sextante.core.GeoAlgorithm#processAlgorithm()
85
	 */
86
	@SuppressWarnings("unchecked")
87
	public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
88
		if(existsOutPutFile(DissolveAlgorithm.RESULT, 0)) {
89
    		throw new GeoAlgorithmExecutionException(getTranslation("file_exists"));
90
    	}
91
		IVectorLayer layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
92
		boolean selectedGeom = m_Parameters.getParameterValueAsBoolean(SELECTED_GEOM);
93
		
94
		FeatureStore storeLayer = null;
95
		if(layer instanceof FlyrVectIVectorLayer)
96
			storeLayer = ((FlyrVectIVectorLayer)layer).getFeatureStore();
97
		else
98
			return false;
99
		
100
		try {
101
			String[] attrNames = new String[]{"FID"};
102
			Class[] types = new Class[] {Integer.class};
103

  
104
			FeatureStore outFeatStore = buildFuseSpatiallyOutPutStore(attrNames, types,
105
					layer.getShapeType(), getTranslation("fusespatially"), RESULT);
106
			
107
			return execute(storeLayer, outFeatStore, layer.getShapeType(), selectedGeom, getStatus(), "FID", true);
108
		} catch (DataException e) {
109
			Sextante.addErrorToLog(e);
110
			return false;
111
		}
112
	}
113
	
114
	public boolean execute(FeatureStore inputStoreLayer, 
115
			FeatureStore outFeatStore,
116
			int shapeType, 
117
			boolean selectedGeom, 
118
			SimpleTaskStatus status, 
119
			String idField,
120
			boolean createTable) throws DataException {
121
		FeatureStore outFeatStoreTable = null;
122
		String[] attrNamesTable = null;
123
		if(createTable) {
124
			attrNamesTable = new String[inputStoreLayer.getDefaultFeatureType().size() + 1];
125
			Class[] typesTable = new Class[inputStoreLayer.getDefaultFeatureType().size() + 1];
126
			attrNamesTable[0] = fid;
127
			typesTable[0] = Integer.class;
128
			for (int i = 0; i < inputStoreLayer.getDefaultFeatureType().size(); i++) {
129
				FeatureAttributeDescriptor attrDesc = inputStoreLayer.getDefaultFeatureType().getAttributeDescriptor(i);
130
				attrNamesTable[i + 1] = attrDesc.getName();
131
				typesTable[i + 1] = attrDesc.getDataType().getDefaultClass();
132
			}
133
			
134
			attrNamesTable = checkFields(attrNamesTable);
135
			outFeatStoreTable = buildFuseSpatiallyOutPutStore(attrNamesTable, typesTable,
136
				shapeType, getTranslation("fusespatially") + "_Table", RESULT_TABLE);
137
		}
138

  
139
		FuseSpatiallyOperationFast2 operation = new FuseSpatiallyOperationFast2(this);
140
		operation.setTaskStatus(getStatus());
141
		operation.computesGeometryOperation(inputStoreLayer, 
142
				outFeatStore, 
143
				outFeatStoreTable,
144
				new String[]{fid}, 
145
				attrNamesTable,
146
				selectedGeom,
147
				false,
148
				idField);
149
		
150
		if(getTaskMonitor().isCanceled())
151
			return false;
152
		/*computesGeometryOperation(inputStoreLayer, outFeatStore, outFeatStoreTable, 
153
				attrNames, attrNamesTable, selectedGeom, status, idField);*/
154
		return true;
155
	}
156
	
157
	/**
158
	 * Removes duplicate fields
159
	 * @param names
160
	 * @return
161
	 */
162
	public String[] checkFields(String[] names) {
163
		if(names.length <= 1)
164
			return names;
165
		int cont = 0;
166

  
167
		int i = 1;
168
		while(i < names.length) {
169
			if(names[0].compareTo(names[i]) == 0) {
170
				names[0] = "FID_" + cont;
171
				i = 0;
172
				cont ++;
173
			}
174
			i ++;
175
		}
176
		return names;
177
	}
178
	
179
	
180
	/**
181
	 * Computes a complete operation over the input FeatureStore. The result of this operation
182
	 * is stored in the output FeatureStore. This method will call once for each geometry.
183
	 * @param inFeatStore
184
	 *        Input FeatureStore
185
	 * @param outFeatStore
186
	 *        Output FeatureStore
187
	 * @param attrNames
188
	 *        List of attributes to build the output feature store
189
	 * @param selectedGeom
190
	 *        If it is true only the selected geometries will be processed
191
	 * @deprecated This method uses FuseSpatiallyOperation which is deprecated
192
	 * @throws DataException
193
	 */
194
	@SuppressWarnings("deprecation")
195
	public void computesGeometryOperation(FeatureStore inFeatStore,
196
									FeatureStore outFeatStore,
197
									FeatureStore outFeatStoreTable,
198
									String[] attrNames,
199
									String[] attrNamesTable,
200
									boolean selectedGeom,
201
									SimpleTaskStatus status,
202
									String idField) throws DataException {
203
		FeatureSet featuresSet = null;
204
		DisposableIterator it = null;
205

  
206
		if(selectedGeom) {
207
			featuresSet = (FeatureSet)inFeatStore.getSelection();
208
		} else {
209
			featuresSet = inFeatStore.getFeatureSet();
210
		}
211
		
212
		it = featuresSet.iterator();
213
		int numberOfFeatures = (int)featuresSet.getSize();
214
        if (status != null) {
215
            status.setRangeOfValues(0, numberOfFeatures);
216
        }
217
		
218
        //Stack<Feature> featList = new Stack<Feature>();
219
        List<Feature> featList = new ArrayList<Feature>();
220
		while( it.hasNext() ) {
221
			Feature feature = (Feature)it.next();
222
			featList.add(feature);
223
		}
224

  
225
		
226
		FuseSpatiallyOperation operation = new FuseSpatiallyOperation(featList, 
227
				outFeatStoreTable, 
228
				attrNamesTable, 
229
				idField, 
230
				this);
231
		operation.setFeatureStore(outFeatStore, attrNames);
232
		int size = featList.size();
233
		operation.setGeoProcess(this, size);
234
		
235
		while (featList.size() > 0 && !m_Task.isCanceled()) {
236
			Feature f = featList.remove(featList.size() - 1);	
237
			operation.invoke(f.getDefaultGeometry(), f);
238
			setProgress(size - featList.size(), size);
239
		}
240

  
241
		if(operation.getWriter() != null)
242
			operation.getWriter().end();
243
	}
244
	
245
	public boolean setProgress(int step, int size) {
246
		if(process != null)
247
			return process.setProgress(step, size);
248
		else
249
			return super.setProgress(step, size);
250
	}
251
	
252
	/**
253
	 * Builds the output FeatureStore 
254
	 * @param featureType
255
	 * @return FeatureStore
256
	 */
257
	@SuppressWarnings("unchecked")
258
	protected FeatureStore buildFuseSpatiallyOutPutStore(String[] attrNames,
259
											Class[] types,
260
											int shapeType,
261
											String sextanteLayerName, 
262
											String sextanteLayerLabel) {
263

  
264
		
265
		try {
266
			IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
267
													sextanteLayerName,
268
													shapeType, types, attrNames);
269
			return ((FlyrVectIVectorLayer)output).getFeatureStore();
270
		} catch (UnsupportedOutputChannelException e) {
271
			Sextante.addErrorToLog(e);
272
        } catch (GeoAlgorithmExecutionException e) {
273
            Sextante.addErrorToLog(e);
274
        }
275
		return null;
276
	}
277

  
278
}

Also available in: Unified diff