Revision 9182

View differences:

trunk/extensions/extGeoprocessingExtensions/.classpath
10 10
	<classpathentry combineaccessrules="false" kind="src" path="/_fwAndami"/>
11 11
	<classpathentry combineaccessrules="false" kind="src" path="/appgvSIG"/>
12 12
	<classpathentry combineaccessrules="false" kind="src" path="/libUI"/>
13
	<classpathentry combineaccessrules="false" kind="src" path="/libDriverManager"/>
14
	<classpathentry sourcepath="D:/eclipse_3_1/workspace_pruebas/jts/src" kind="lib" path="/libFMap/lib/jts-1.7.jar"/>
13 15
	<classpathentry kind="output" path="bin"/>
14 16
</classpath>
trunk/extensions/extGeoprocessingExtensions/src/com/iver/cit/gvsig/geoprocess/impl/xyshift/resources/description_es.html
21 21
<P>
22 22
Este geoproceso puede ser de gran utilidad para hacer concordar
23 23
cartograf&iacute;as procedentes de fuentes distintas, en lo que se
24
viene a denominar por el t&eacute;rmino ingl&eacute;s &ldquo;conflation&rdquo;.
24
viene a denominar por el t&eacute;rmino ingl&eacute;s conflation.
25 25
</P>
26 26
</BODY>
27 27
</HTML>
trunk/extensions/extGeoprocessingExtensions/src/com/iver/cit/gvsig/topology/lineclean/RegisterGeoprocessPlugin.java
1
/*
2
 * Created on 16-oct-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id$
47
* $Log$
48
* Revision 1.1  2006-12-04 19:42:23  azabala
49
* *** empty log message ***
50
*
51
* Revision 1.1  2006/10/17 18:25:53  azabala
52
* *** empty log message ***
53
*
54
*
55
*/
56
package com.iver.cit.gvsig.topology.lineclean;
57

  
58
import com.iver.andami.plugins.Extension;
59
import com.iver.utiles.extensionPoints.ExtensionPoints;
60
import com.iver.utiles.extensionPoints.ExtensionPointsSingleton;
61

  
62
public class RegisterGeoprocessPlugin extends Extension{
63

  
64
	public void initialize() {
65
		ExtensionPoints extensionPoints = 
66
			ExtensionPointsSingleton.getInstance();
67
		extensionPoints.add("GeoprocessManager",
68
				"LINECLEAN", 
69
				LineCleanGeoprocessPlugin.class);
70
	}
71

  
72
	public void execute(String actionCommand) {
73
	}
74

  
75
	public boolean isEnabled() {
76
		return true;
77
	}
78

  
79
	public boolean isVisible() {
80
		return true;
81
	}
82

  
83
}
84

  
0 85

  
trunk/extensions/extGeoprocessingExtensions/src/com/iver/cit/gvsig/topology/lineclean/LineCleanGeoprocessPlugin.java
1
/*
2
 * Created on 10-oct-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id$
47
* $Log$
48
* Revision 1.1  2006-12-04 19:42:23  azabala
49
* *** empty log message ***
50
*
51
* Revision 1.2  2006/10/17 18:25:53  azabala
52
* *** empty log message ***
53
*
54
* Revision 1.1  2006/10/10 18:50:17  azabala
55
* First version in CVS
56
*
57
*
58
*/
59
package com.iver.cit.gvsig.topology.lineclean;
60

  
61
import java.net.URL;
62
import java.util.Locale;
63

  
64
import com.iver.andami.PluginServices;
65
import com.iver.cit.gvsig.fmap.layers.FLayers;
66
import com.iver.cit.gvsig.geoprocess.core.IGeoprocessController;
67
import com.iver.cit.gvsig.geoprocess.core.IGeoprocessPlugin;
68
import com.iver.cit.gvsig.geoprocess.core.gui.IGeoprocessPanel;
69
import com.iver.cit.gvsig.project.documents.view.gui.View;
70
import com.iver.cit.gvsig.topology.lineclean.gui.LineCleanGeoprocessPanel;
71

  
72
public class LineCleanGeoprocessPlugin implements IGeoprocessPlugin {
73

  
74
	private static String dataConvertPkg;
75
	private static String geoprocessName;
76
	
77
	static{
78
		dataConvertPkg = 
79
			PluginServices.getText(null, "Conversion_de_datos");
80
		geoprocessName =
81
			PluginServices.getText(null, "LineClean");
82
	}
83
	
84
	
85
	
86
	public IGeoprocessPanel getGeoprocessPanel() {
87
		View vista = (View)PluginServices.
88
		getMDIManager().
89
		getActiveWindow();
90
		FLayers layers = vista.getModel().
91
			getMapContext().
92
			getLayers();
93
		
94
		return new LineCleanGeoprocessPanel(layers);
95
	}
96

  
97
	public URL getHtmlDescription() {
98
		Locale locale = Locale.getDefault();
99
		String localeStr = locale.getLanguage();
100
		String urlStr = "resources/description_" +
101
										localeStr +
102
											".html";
103
		URL url = LineCleanGeoprocessPlugin.class.
104
		getResource(urlStr);
105
		return url;
106
	}
107

  
108
	public URL getImgDescription() {
109
		URL url = LineCleanGeoprocessPlugin.class.
110
			getResource("resources/linecleandesc.png");
111
		return url;
112
	}
113

  
114
	public IGeoprocessController getGpController() {
115
		return new LineCleanGeoprocessController();
116
	}
117

  
118
	public String getNamespace() {
119
		return dataConvertPkg + "/" + geoprocessName;
120
	}
121
	
122
	public String toString(){
123
		return geoprocessName;
124
	}
125

  
126
}
127

  
0 128

  
trunk/extensions/extGeoprocessingExtensions/src/com/iver/cit/gvsig/topology/lineclean/fmap/LineCleanGeoprocess.java
1
/*
2
 * Created on 10-oct-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id$
47
* $Log$
48
* Revision 1.1  2006-12-04 19:42:23  azabala
49
* *** empty log message ***
50
*
51
* Revision 1.8  2006/11/14 18:34:16  azabala
52
* *** empty log message ***
53
*
54
* Revision 1.7  2006/11/14 18:00:57  azabala
55
* internationalized texts
56
*
57
* Revision 1.6  2006/11/13 20:41:08  azabala
58
* *** empty log message ***
59
*
60
* Revision 1.5  2006/11/10 13:22:57  azabala
61
* better syncronization of clean and build network (use of pipetask)
62
*
63
* Revision 1.4  2006/11/09 21:08:32  azabala
64
* *** empty log message ***
65
*
66
* Revision 1.3  2006/10/19 16:06:48  azabala
67
* *** empty log message ***
68
*
69
* Revision 1.2  2006/10/17 18:25:53  azabala
70
* *** empty log message ***
71
*
72
* Revision 1.1  2006/10/10 18:50:17  azabala
73
* First version in CVS
74
*
75
*
76
*/
77
package com.iver.cit.gvsig.topology.lineclean.fmap;
78

  
79
import java.io.File;
80
import java.io.IOException;
81
import java.util.Map;
82

  
83
import com.iver.andami.PluginServices;
84
import com.iver.cit.gvsig.fmap.DriverException;
85
import com.iver.cit.gvsig.fmap.MapContext;
86
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
87
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
88
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
89
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
90
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
91
import com.iver.cit.gvsig.fmap.edition.EditionException;
92
import com.iver.cit.gvsig.fmap.edition.IWriter;
93
import com.iver.cit.gvsig.fmap.edition.ShpSchemaManager;
94
import com.iver.cit.gvsig.fmap.edition.writers.shp.MultiShpWriter;
95
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
96
import com.iver.cit.gvsig.fmap.layers.FBitSet;
97
import com.iver.cit.gvsig.fmap.layers.FLayer;
98
import com.iver.cit.gvsig.fmap.layers.FLayers;
99
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
100
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
101
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
102
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
103
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
104
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
105
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
106
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess;
107
import com.iver.cit.gvsig.geoprocess.core.fmap.DefinitionUtils;
108
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
109
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
110
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
111
import com.iver.cit.gvsig.project.documents.view.gui.View;
112
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
113
import com.iver.utiles.swing.threads.AbstractMonitorableTask;
114
import com.iver.utiles.swing.threads.Cancellable;
115
import com.iver.utiles.swing.threads.IMonitorableTask;
116
import com.iver.utiles.swing.threads.IPipedTask;
117

  
118
public class LineCleanGeoprocess extends AbstractGeoprocess {
119

  
120
	/**
121
	 * Schema of the result layer
122
	 */
123
	private ILayerDefinition resultLayerDefinition;
124

  
125
	
126
	/**
127
	 * flag to only clip selection of input layer
128
	 */
129
	private boolean onlyFirstLayerSelection = false;
130
	
131
	/**
132
	 * Processes features (writing them)
133
	 */
134
	FeaturePersisterProcessor2 processor;
135

  
136
	/**
137
	 * Writer to save in a temporal layer intersections
138
	 */
139
	private IWriter intersectionsWriter;
140
	FeaturePersisterProcessor2 intersectsProcessor;
141
	
142
	
143
	public LineCleanGeoprocess(FLyrVect inputLayer){
144
		this.firstLayer = inputLayer;
145
	}
146
	
147
	
148
	public void setParameters(Map params) throws GeoprocessException {
149
		Boolean firstLayerSelection = (Boolean) params.get("firstlayerselection");
150
		if (firstLayerSelection != null)
151
			this.onlyFirstLayerSelection = 
152
				firstLayerSelection.booleanValue();
153

  
154
	}
155

  
156
	public void checkPreconditions() throws GeoprocessException {
157
		if (firstLayer == null)
158
			throw new GeoprocessException("CLEAN: capa de entrada a null");
159
		if (this.writer == null || this.schemaManager == null) {
160
			throw new GeoprocessException(
161
					"Operacion de CLEAN sin especificar capa de resultados");
162
		}
163
		try {
164
			if(firstLayer.getSource().getShapeCount() == 0){
165
				throw new GeoprocessException(
166
				"Capa de entrada vacia");
167
			}
168
		} catch (DriverIOException e) {
169
			throw new GeoprocessException(
170
			"Error al verificar si la capa est? vac?a");
171
		} 
172
	}
173

  
174
	public void process() throws GeoprocessException {
175
		try {
176
			createTask().run();
177
		} catch (Exception e) {
178
			throw new GeoprocessException("Error al ejecutar el geoproceso");
179
		}
180
	}
181

  
182
	public ILayerDefinition createLayerDefinition() {
183
		if (resultLayerDefinition == null) {
184
			try {
185
				resultLayerDefinition = DefinitionUtils.
186
							createLayerDefinition(firstLayer);
187
			} catch (Exception e) {
188
				e.printStackTrace();
189
			}
190
		}
191
		return resultLayerDefinition;
192
	}
193
	
194
	
195
	class LineCleanTask extends AbstractMonitorableTask implements IPipedTask{
196

  
197
		private LineCleanTask() {
198
			setInitialStep(0);
199
			try {
200
				if (onlyFirstLayerSelection) {
201
					int numSelected = firstLayer.getRecordset().getSelection()
202
							.cardinality();
203
					setFinalStep(numSelected);
204
				} else {
205
					int numShapes = firstLayer.getSource().getShapeCount();
206
					setFinalStep(numShapes);
207
				}// else
208
			} catch (com.iver.cit.gvsig.fmap.DriverException e) {
209
				// TODO Auto-generated catch block
210
				e.printStackTrace();
211
			} catch (DriverIOException e) {
212
				// TODO Auto-generated catch block
213
				e.printStackTrace();
214
			}
215
			setDeterminatedProcess(true);
216
			setStatusMessage(PluginServices.getText(this,
217
					"LineClean._Progress_Message"));
218

  
219
		}
220
	
221
		/**
222
		 * Verifies cancelation events, and return a boolean flag if processes must
223
		 * be stopped for this cancelations events.
224
		 * 
225
		 * @param cancel
226
		 * @param va
227
		 * @param visitor
228
		 * @return
229
		 * @throws DriverIOException
230
		 */
231
		protected boolean verifyCancelation(ReadableVectorial va) {
232
			if (isCanceled()) {
233
				try {
234
					va.stop();
235
				} finally {
236
					return true;
237
				}
238
			}
239
			return false;
240
		}
241
		
242
		
243
		public void run() throws Exception {
244
			processor =
245
				new FeaturePersisterProcessor2(writer);
246
			
247
			intersectionsWriter = new ShpWriter();
248
			String temp = System.getProperty("java.io.tmpdir") + 
249
					"/intersections_" + 
250
					System.currentTimeMillis() +
251
					".shp";
252
			File newFile = new File(temp);
253
			((ShpWriter) intersectionsWriter).setFile(newFile);
254
			
255
			ILayerDefinition intersectDefinition = new SHPLayerDefinition();
256
			intersectDefinition.setShapeType(XTypes.POINT);
257
			FieldDescription[] intersectFields = new FieldDescription[2];
258
			intersectFields[0] = new FieldDescription();
259
			intersectFields[0].setFieldLength(10);
260
			intersectFields[0].setFieldDecimalCount(0);
261
			intersectFields[0].setFieldName("FID1");
262
			intersectFields[0].setFieldType(XTypes.INTEGER);
263
			intersectFields[1] = new FieldDescription();
264
			intersectFields[1].setFieldLength(10);
265
			intersectFields[1].setFieldDecimalCount(0);
266
			intersectFields[1].setFieldName("FID2");
267
			intersectFields[1].setFieldType(XTypes.INTEGER);
268
			intersectDefinition.setFieldsDesc(intersectFields);
269
			
270
			((ShpWriter) intersectionsWriter).initialize(
271
					(LayerDefinition) intersectDefinition);
272
			((SHPLayerDefinition) intersectDefinition).setFile(newFile);
273
			
274
			ShpSchemaManager interSchMg = 
275
				new ShpSchemaManager(newFile.getAbsolutePath());
276
			interSchMg.createSchema(intersectDefinition);
277
			
278
			intersectsProcessor = new 
279
				FeaturePersisterProcessor2(intersectionsWriter);
280
			
281
			FBitSet selection = null;
282
			SnappingCoordinateMap coordMap = 
283
				new SnappingCoordinateMap(LineCleanVisitor.DEFAULT_SNAP);
284
			LineCleanVisitor visitor = 
285
				new LineCleanVisitor(processor,
286
						             intersectsProcessor,
287
						onlyFirstLayerSelection, 
288
						resultLayerDefinition,
289
						intersectDefinition,
290
						firstLayer,
291
						firstLayer.getRecordset(), coordMap);
292
			
293
			try {
294
				processor.start();
295
				intersectsProcessor.start();
296
				
297
				ReadableVectorial va = firstLayer.getSource();
298
				va.start();
299
				for (int i = 0; i < va.getShapeCount(); i++) {// for each geometry
300
					if (verifyCancelation(va)) {
301
						intersectsProcessor.finish();
302
						return;
303
					}
304
					if(selection != null){
305
						if (selection.get(i)) {
306
								reportStep();
307
								visitor.visit(va.getShape(i), i);
308
						}
309
							
310
					}else{
311
						reportStep();
312
						visitor.visit(va.getShape(i), i);
313
					}
314
				}// for
315
				va.stop();
316
				processor.finish();
317
				intersectsProcessor.finish();
318
				
319
				
320
			} catch (DriverIOException e) {
321
				e.printStackTrace();
322
			}
323
		}
324

  
325
		// TODO INTERNACIONALIZAR LOS MENSAJES
326
		public String getNote() {
327
			String cleaningText = PluginServices.getText(this, "Limpiando_lineas");
328
			String of = PluginServices.getText(this, "de");
329
			return cleaningText + " " + getCurrentStep() + " "
330
					+ of + " " + getFinishStep();
331
		}
332

  
333
		public void cancel() {
334
			setCanceled(true);
335
			LineCleanGeoprocess.this.cancel();
336
		}
337

  
338
		/* (non-Javadoc)
339
		 * @see com.iver.utiles.swing.threads.IPipedTask#getResult()
340
		 */
341
		public Object getResult() {
342
			try {
343
				return LineCleanGeoprocess.this.getResult();
344
			} catch (GeoprocessException e) {
345
				return null;
346
			}
347
		}
348

  
349
		/* (non-Javadoc)
350
		 * @see com.iver.utiles.swing.threads.IPipedTask#setEntry(java.lang.Object)
351
		 */
352
		public void setEntry(Object object) {
353
			// TODO Auto-generated method stub
354
			
355
		}
356
	}
357

  
358
	
359
	public IMonitorableTask createTask() {
360
		return new LineCleanTask();
361
	}
362
	
363
	
364
	public FLayer getResult() throws GeoprocessException {
365
		
366
		FLyrVect cleanedLayer = (FLyrVect) createLayerFrom(this.writer);
367
		FLyrVect pseudoNodes = (FLyrVect) createLayerFrom(this.intersectionsWriter);
368
		try {
369
			if(pseudoNodes.getSource().getShapeCount() == 0){
370
				return cleanedLayer;
371
			}else{
372
				MapContext map = ((View)PluginServices.
373
						getMDIManager().
374
						getActiveWindow()).
375
						getModel().
376
						getMapContext();
377
				FLayers solution = new FLayers(map, null);
378
				solution.setName(this.firstLayer.getName()+"_cleaned");
379
				solution.addLayer(cleanedLayer);
380
				solution.addLayer(pseudoNodes);
381
				return solution;
382
			}
383
		} catch (DriverIOException e) {
384
			throw new GeoprocessException("Error de lectura de datos");
385
		}
386
		
387
		
388
		
389
			
390
	}
391

  
392
}
393

  
0 394

  
trunk/extensions/extGeoprocessingExtensions/src/com/iver/cit/gvsig/topology/lineclean/fmap/LineCleanVisitor.java
1
/*
2
 * Created on 10-oct-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
 *
46
 * $Id$
47
 * $Log$
48
 * Revision 1.1  2006-12-04 19:42:23  azabala
49
 * *** empty log message ***
50
 *
51
 * Revision 1.7  2006/11/14 18:34:16  azabala
52
 * *** empty log message ***
53
 *
54
 * Revision 1.6  2006/11/14 18:01:09  azabala
55
 * removed system.out.println
56
 *
57
 * Revision 1.5  2006/11/13 20:41:08  azabala
58
 * *** empty log message ***
59
 *
60
 * Revision 1.4  2006/10/19 16:06:48  azabala
61
 * *** empty log message ***
62
 *
63
 * Revision 1.3  2006/10/17 18:27:24  azabala
64
 * *** empty log message ***
65
 *
66
 * Revision 1.1  2006/10/10 18:50:17  azabala
67
 * First version in CVS
68
 *
69
 *
70
 */
71
package com.iver.cit.gvsig.topology.lineclean.fmap;
72

  
73
import java.util.ArrayList;
74
import java.util.Arrays;
75
import java.util.Collections;
76
import java.util.Comparator;
77
import java.util.Iterator;
78

  
79
import com.hardcode.gdbms.engine.data.driver.DriverException;
80
import com.hardcode.gdbms.engine.values.Value;
81
import com.hardcode.gdbms.engine.values.ValueFactory;
82
import com.iver.cit.gvsig.fmap.core.IFeature;
83
import com.iver.cit.gvsig.fmap.core.IGeometry;
84
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
85
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
86
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
87
import com.iver.cit.gvsig.fmap.edition.EditionException;
88
import com.iver.cit.gvsig.fmap.layers.FBitSet;
89
import com.iver.cit.gvsig.fmap.layers.FLayer;
90
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
91
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
92
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
93
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
94
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
95
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
96
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
97
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
98
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureFactory;
99
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
100
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureProcessor;
101
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
102
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
103
import com.vividsolutions.jts.geom.Coordinate;
104
import com.vividsolutions.jts.geom.Geometry;
105
import com.vividsolutions.jts.geom.GeometryCollection;
106
import com.vividsolutions.jts.geom.GeometryFactory;
107
import com.vividsolutions.jts.geom.LineString;
108
import com.vividsolutions.jts.geom.MultiLineString;
109
import com.vividsolutions.jts.geom.MultiPoint;
110
import com.vividsolutions.jts.geom.Point;
111
import com.vividsolutions.jts.geom.Polygon;
112
import com.vividsolutions.jts.geomgraph.Node;
113
import com.vividsolutions.jts.geomgraph.NodeFactory;
114
import com.vividsolutions.jts.geomgraph.SnappingNodeMap;
115
import com.vividsolutions.jts.linearref.LengthIndexedLine;
116
import com.vividsolutions.jts.linearref.LinearLocation;
117
import com.vividsolutions.jts.linearref.LocationIndexedLine;
118
import com.vividsolutions.jts.operation.overlay.SnappingOverlayOperation;
119

  
120
/**
121
 * <p>
122
 * This visitor operates with features whose geometries are lines. <br>
123
 * For each visited feature, it looks for features in its proximity (spatial
124
 * query). If these features hasnt been processed, it intersects the visited
125
 * feature with all of the neighbour features. If intersection points are not
126
 * nodes (end points), it ignores them. split the
127
 * </p>
128
 * 
129
 * @author azabala
130
 */
131
public class LineCleanVisitor implements FeatureVisitor {
132

  
133
	/**
134
	 * Recordset of the layer we are working with
135
	 */
136
	protected SelectableDataSource recordset;
137

  
138
	/**
139
	 * Layer which we are cleaning
140
	 */
141
	protected FLyrVect layerToClean;
142

  
143
	/**
144
	 * marks if we are going to clean only layer selection
145
	 */
146
	protected boolean cleanOnlySelection;
147

  
148
	/*
149
	 * TODO Meter esto en preferencias
150
	 */
151
	public final static double DEFAULT_SNAP = 0.1;
152

  
153
	protected double snapTolerance = DEFAULT_SNAP;
154

  
155
	/**
156
	 * It marks all processed features (to ignore them in future intersections)
157
	 */
158
	protected FBitSet processedFeatures;
159

  
160
	/**
161
	 * Strategy of the layer we are working with.
162
	 */
163
	protected Strategy strategy;
164

  
165
	/**
166
	 * Saves features resulting of cleaning process
167
	 */
168
	protected FeatureProcessor featureProcessor;
169

  
170
	protected ILayerDefinition layerDefinition;
171
	
172
	
173
	/**
174
	 * Saves pseudonodes found
175
	 * */
176
	protected FeatureProcessor intersectProcessor;
177
	protected ILayerDefinition intersectDefinition;
178
	
179
	
180
	/**
181
	 * Counter of new features
182
	 */
183
	int fid = 0;
184
	
185
	/**
186
	 * It caches all written pseudonodes, to avoid 
187
	 * writing the same pseudonode twice.
188
	 * 
189
	 * */
190
	SnappingCoordinateMap snapCoordMap;
191
	
192
	/**
193
	 * Constructor.
194
	 * @param processor
195
	 * @param intersectsProcessor
196
	 * @param cleanOnlySelection
197
	 * @param layerDefinition
198
	 * @param intersectDefinition
199
	 * @param firstLayer
200
	 * @param source
201
	 * @param snapCoordMap
202
	 */
203
	public LineCleanVisitor(FeatureProcessor processor,
204
			FeaturePersisterProcessor2 intersectsProcessor, 
205
									boolean cleanOnlySelection, 
206
									ILayerDefinition layerDefinition, 
207
									ILayerDefinition intersectDefinition, 
208
									FLyrVect firstLayer, 
209
									SelectableDataSource source,
210
									SnappingCoordinateMap snapCoordMap) {
211
		this.featureProcessor = processor;
212
		this.cleanOnlySelection = cleanOnlySelection;
213
		processedFeatures = new FBitSet();
214
		this.layerDefinition = layerDefinition;
215
		this.intersectProcessor = intersectsProcessor;
216
		this.intersectDefinition = intersectDefinition;
217
		this.layerToClean = firstLayer;
218
		this.recordset = source;
219
		this.strategy = StrategyManager.getStrategy(layerToClean);
220
		this.snapCoordMap = snapCoordMap;
221
	}
222

  
223
	public void setLayerDefinition(ILayerDefinition layerDefinition) {
224
		this.layerDefinition = layerDefinition;
225
	}
226

  
227
	private boolean checkForLineGeometry(Geometry geometry) {
228
		if (geometry instanceof LineString)
229
			return true;
230
		if (geometry instanceof MultiLineString)
231
			return true;
232
		if (geometry instanceof GeometryCollection) {
233
			GeometryCollection col = (GeometryCollection) geometry;
234
			for (int i = 0; i < col.getNumGeometries(); i++) {
235
				if (!checkForLineGeometry(col.getGeometryN(i)))
236
					return false;
237
			}
238
			return true;
239
		}
240
		return false;
241
	}
242

  
243
	public void visit(IGeometry g, final int index) throws VisitException {
244
		// first, we check it isnt a null geometry and the geometry type
245
		// is correct
246
		if (g == null)
247
			return;
248
		int geometryType = g.getGeometryType();
249
		if (geometryType != XTypes.ARC && geometryType != XTypes.LINE
250
				&& geometryType != XTypes.MULTI)
251
			return;
252

  
253
		// after that, if we are going to clean only selected features, we
254
		// check if this feature is selected
255
		if (cleanOnlySelection) {
256
			try {
257
				if (!layerToClean.getRecordset().getSelection().get(index))
258
					return;
259
			} catch (com.iver.cit.gvsig.fmap.DriverException e) {
260
				throw new VisitException(
261
						"Error verificando seleccion en CLEAN", e);
262
			}
263
		}// if cleanOnly
264

  
265
		final Geometry jtsGeo = g.toJTSGeometry();
266

  
267
		
268
		// we check if jts geometry is a line (or a line collection)
269
		if (!checkForLineGeometry(jtsGeo))
270
			return;
271

  
272
		final SnappingNodeMap nodes = new SnappingNodeMap(new NodeFactory(),
273
				snapTolerance);
274
		/*
275
		 * Se nos plantea una problematica. Tenemos dos features: A y B, y he
276
		 * calculado la interseccion de A y B. Ahora, hay dos alternativas: -a)
277
		 * nunca mas calcular esta intersecci?n, pero almacenar su resultado en
278
		 * SnappingNodeMap. As?, en una segunda pasada, con todos los "Nodos"
279
		 * calculados, podr?amos fragmentar las lineas de forma individual.
280
		 * PROBLEMA: SnappingNodeMap ir?a creciendo, almacenando todos los nodos
281
		 * de una capa....(si se apoya sobre un IndexedShpDriver, no tendr?a por
282
		 * qu?)
283
		 * 
284
		 * 
285
		 * -b) Calcular la intersecci?n en los dos sentidos: A int B, y luego al
286
		 * procesar B, B int A. En este caso, pasamos ol?mpicamente del bitset
287
		 * 
288
		 * De momento, por simplicidad, seguimos la alternativa -b)
289
		 */
290

  
291
		final boolean onlySelection = cleanOnlySelection;
292
		try {
293
			strategy.process(new FeatureVisitor() {
294
				
295
				
296
				SnappingOverlayOperation overlayOp = null;
297

  
298
				/**
299
				 * From a given geometry, it returns its nodes (coordinate for a
300
				 * point, extreme coordinates for a line, first coordinate for a
301
				 * polygon)
302
				 */
303
				private Coordinate[] getNodesFor(Geometry processedGeometry) {
304
					Coordinate[] geomNodes = null;
305
					if (processedGeometry instanceof LineString) {
306
						LineString line = (LineString) processedGeometry;
307
						geomNodes = new Coordinate[2];
308
						geomNodes[0] = line.getCoordinateN(0);
309
						geomNodes[1] = line
310
								.getCoordinateN(line.getNumPoints() - 1);
311
					} else if (processedGeometry instanceof MultiLineString) {
312
						MultiLineString lines = (MultiLineString) processedGeometry;
313
						int numLines = lines.getNumGeometries();
314
						geomNodes = new Coordinate[2 * numLines];
315
						int index = 0;
316
						for (int i = 0; i < numLines; i++) {
317
							LineString line = (LineString) lines
318
									.getGeometryN(i);
319
							geomNodes[index] = line.getCoordinateN(0);
320
							index++;
321
							geomNodes[index] = line.getCoordinateN(line
322
									.getNumPoints() - 1);
323
							index++;
324
						}
325
					} else if (processedGeometry instanceof GeometryCollection) {
326
						GeometryCollection col = (GeometryCollection) processedGeometry;
327
						ArrayList coordinates = new ArrayList();
328
						for (int i = 0; i < col.getNumGeometries(); i++) {
329
							Geometry geom = col.getGeometryN(i);
330
							Coordinate[] newNodes = getNodesFor(geom);
331
							coordinates.addAll(Arrays.asList(newNodes));
332
						}
333
					}
334
//					else {
335
//						System.out
336
//								.println("Este proceso solo debe trabajar con lineas");
337
//						System.out.println(processedGeometry.getGeometryType());
338
//					}
339
					return geomNodes;
340
				}
341

  
342
				/**
343
				 * Checks if a coordinate is on a node of a given set of nodes
344
				 * 
345
				 * @param coord
346
				 * @param nodes
347
				 * @return
348
				 */
349
				private boolean checkIsNode(Coordinate coord, Coordinate[] nodes) {
350
					for (int i = 0; i < nodes.length; i++) {
351
						if (coord.distance(nodes[i]) <= snapTolerance)
352
							return true;
353
					}
354
					return false;
355
				}
356

  
357
				/**
358
				 * From a given geometry, and the intersection of this geometry
359
				 * with another geometry, it creates a new node with these
360
				 * intersections if its points are not coincident with the nodes
361
				 * of the original goemetry.
362
				 * 
363
				 */
364
				private void processIntersections(com.vividsolutions.jts.geomgraph.SnappingNodeMap nodes,
365
						Geometry processedGeometry, Geometry intersections, int fid1, int fid2) {
366

  
367
					Coordinate[] geomNodes = getNodesFor(processedGeometry);
368
					if (intersections instanceof Point) {
369
						Point p = (Point) intersections;
370
						Coordinate coord = p.getCoordinate();
371
						if (!checkIsNode(coord, geomNodes)){
372
							nodes.addNode(coord);
373
							
374
							/*
375
							 * We are computing intersections twice: A intersection B
376
							 * and B intersection A. This is simpler than manage caches.
377
							 * With this logic, we avoid to write the same pseudonode twice
378
							 * 
379
							 * */
380
							if(snapCoordMap.containsKey(coord))
381
								return;
382
							else{
383
								snapCoordMap.put(coord, coord);
384
								IFeature feature = createIntersectFeature(coord, fid1, fid2);
385
								intersectProcessor.processFeature(feature);
386
							}
387
						} 	
388
					} else if (intersections instanceof MultiPoint) {
389
						MultiPoint points = (MultiPoint) intersections;
390
						for (int i = 0; i < points.getNumGeometries(); i++) {
391
							Coordinate coord = ((Point) points.getGeometryN(i))
392
									.getCoordinate();
393
							if (!checkIsNode(coord, geomNodes)){
394
								nodes.addNode(coord);
395
								if(snapCoordMap.containsKey(coord))
396
									return;
397
								else{
398
									snapCoordMap.put(coord, coord);
399
									IFeature feature = createIntersectFeature(coord, fid1, fid2);
400
									intersectProcessor.processFeature(feature);
401
								}
402
							}	
403
						}
404
					} else if (intersections instanceof LineString) {
405
						LineString line = (LineString) intersections;
406
						int numPoints = line.getCoordinates().length;
407
						Coordinate coord1 = line.getCoordinateN(0);
408
						Coordinate coord2 = line.getCoordinateN(numPoints - 1);
409
						if (!checkIsNode(coord1, geomNodes)){
410
							nodes.addNode(coord1);
411
							if(snapCoordMap.containsKey(coord1))
412
								return;
413
							else{
414
								snapCoordMap.put(coord1, coord1);
415
								IFeature feature = createIntersectFeature(coord1, fid1, fid2);
416
								intersectProcessor.processFeature(feature);
417
							}
418
						}	
419
						if (!checkIsNode(coord2, geomNodes)){
420
							nodes.addNode(coord2);
421
							if(snapCoordMap.containsKey(coord2))
422
								return;
423
							else{
424
								snapCoordMap.put(coord2, coord2);
425
								IFeature feature = createIntersectFeature(coord2, fid1, fid2);
426
								intersectProcessor.processFeature(feature);
427
							}
428
						}	
429
					} else if (intersections instanceof GeometryCollection) {
430
						GeometryCollection col = (GeometryCollection) intersections;
431
						for (int i = 0; i < col.getNumGeometries(); i++) {
432

  
433
							// El tema est? en que aqu? el calculo de los nodos
434
							// de la geometria intersectada se repite cada vez
435
							// revisar, pues MultiLineString puede ser un
436
							// resultado habitual
437
							processIntersections(nodes, processedGeometry, col
438
									.getGeometryN(i), fid1, fid2);
439
						}
440
					}
441
//					else if (intersections instanceof Polygon) {
442
//						System.out
443
//								.println("Un poligono interseccion de 2 lineas???");
444
//					}// else
445

  
446
				}
447

  
448
				public void visit(IGeometry g2, int indexOverlay)
449
						throws VisitException {
450

  
451
					if (g2 == null)
452
						return;
453

  
454
					if (index == indexOverlay)
455
						return;
456

  
457
					if (onlySelection) {
458
						try {
459
							if (!layerToClean.getRecordset().getSelection()
460
									.get(indexOverlay))
461
								return;
462
						} catch (com.iver.cit.gvsig.fmap.DriverException e) {
463
							throw new VisitException(
464
									"Error verificando seleccion en clean", e);
465
						}// geometry g is not selected
466
					}// if onlySelection
467

  
468
					int geometryType = g2.getGeometryType();
469
					if (geometryType != XTypes.ARC
470
							&& geometryType != XTypes.LINE
471
							&& geometryType != XTypes.MULTI)
472
						return;
473

  
474
					/*
475
					 * TODO De momento no vamos a tener en cuenta que la
476
					 * interseccion ya ha sido calculada... (Ver comentario al
477
					 * instanciar SnappingNodeMap) // ya ha sido tratado
478
					 * if(processedFeatures.get(indexOverlay)) return;
479
					 */
480
					Geometry jtsGeo2 = g2.toJTSGeometry();
481
					if (!checkForLineGeometry(jtsGeo2))
482
						return;
483

  
484
					if(overlayOp == null)
485
						overlayOp = new SnappingOverlayOperation(jtsGeo, jtsGeo2, snapTolerance);	
486
					else{
487
						overlayOp.setSecondGeometry(jtsGeo2);
488
					}
489
					
490
					Geometry intersections = overlayOp.
491
						getResultGeometry(SnappingOverlayOperation.INTERSECTION);
492
						
493
					processIntersections(nodes, jtsGeo, intersections, index, indexOverlay);
494

  
495
					// IFeature cleanedFeature;
496
					// try {
497
					// cleanedFeature = createFeature(newGeoJts,
498
					// index, indexOverlay);
499
					// } catch (DriverException e) {
500
					// throw new VisitException(
501
					// "Error al crear el feature resultante del CLEAN");
502
					// }
503
					// featureProcessor.processFeature(cleanedFeature);
504

  
505
				}
506

  
507
				public String getProcessDescription() {
508
					return "Computing intersections of a polygon with its adjacents";
509
				}
510

  
511
				public void stop(FLayer layer) {
512
				}
513

  
514
				public boolean start(FLayer layer) {
515
					return true;
516
				}
517
			}, g.getBounds2D());
518

  
519
			// At this point, nodes variable (SnappingNodeMap)
520
			// has all intersections of the visited feature with the rest of
521
			// features of the layer
522

  
523
			// It computes linear distance of a point on the given jtsGeo linear
524
			// geometry
525
			LengthIndexedLine lengthLine = new LengthIndexedLine(jtsGeo);
526
			Iterator nodesIt = nodes.iterator();
527
			ArrayList nodeIntersections = new ArrayList();
528
			while (nodesIt.hasNext()) {
529
				Node node = (Node) nodesIt.next();
530
				Coordinate coord = node.getCoordinate();
531
				double lengthOfNode = lengthLine.indexOf(coord);
532
				LineIntersection inters = new LineIntersection();
533
				inters.coordinate = coord;
534
				inters.lenght = lengthOfNode;
535
				nodeIntersections.add(inters);
536
			}
537

  
538
			if (nodeIntersections.size() > 0) {
539
				//	We sort the intersections by distance along the line (dynamic
540
				// segmentation)
541
				Collections.sort(nodeIntersections, new Comparator() {
542
					public int compare(Object arg0, Object arg1) {
543
						LineIntersection l1 = (LineIntersection) arg0;
544
						LineIntersection l2 = (LineIntersection) arg1;
545
						if (l1.lenght > l2.lenght)
546
							return 1;
547
						else if (l1.lenght < l2.lenght)
548
							return -1;
549
						else
550
							return 0;
551
					}
552
				});
553

  
554
				LinearLocation lastLocation = null;
555
				LineIntersection lastIntersection = null;
556
				LocationIndexedLine indexedLine = new LocationIndexedLine(
557
						jtsGeo);
558
				for (int i = 0; i < nodeIntersections.size(); i++) {
559
					Geometry solution = null;
560
					LineIntersection li = (LineIntersection) nodeIntersections
561
							.get(i);
562
					
563
					LinearLocation location = indexedLine
564
							.indexOf(li.coordinate);
565
					if (lastLocation == null) {
566
						LinearLocation from = new LinearLocation(0, 0d);
567
						solution = splitLineString(jtsGeo, from, location,
568
								null, li);
569
						lastLocation = location;
570
						lastIntersection = li;
571
						/*
572
						 * Construimos una linea desde el primer punto hasta el
573
						 * punto contenido en LineIntersection, con todos los
574
						 * puntos intermedios de la linea.
575
						 * 
576
						 * 
577
						 * 
578
						 */
579
					} else {
580
						// Construimos una linea entre lastIntersection y la
581
						// intersection
582
						// actual
583
						LinearLocation locationFrom = lastLocation;
584
						solution = splitLineString(jtsGeo, locationFrom,
585
								location, lastIntersection, li);
586
						lastLocation = location;
587
						lastIntersection = li;
588

  
589
					}
590

  
591
					
592
						IFeature feature = createFeature(solution, index);
593
						featureProcessor.processFeature(feature);
594
						// TODO Podriamos guardar los puntos de interseccion
595
						// para
596
						// mostrar al usuario que puntos eran pseudonodos
597
				}// for
598
				
599
				//a?adimos el ultimo segmento
600
				Coordinate[] geomCoords = jtsGeo.getCoordinates();
601
				ArrayList coordinates = new ArrayList();
602
				coordinates.add(lastIntersection.coordinate);
603
				int startIndex = lastLocation.getSegmentIndex() + 1;
604
				for (int i = startIndex; i < geomCoords.length; i++) {
605
					coordinates.add(geomCoords[i]);
606
				}
607
				Coordinate[] solutionCoords = new Coordinate[coordinates.size()];
608
				coordinates.toArray(solutionCoords);
609
				IFeature lastFeature = createFeature(new GeometryFactory().
610
										 createLineString(solutionCoords), 
611
										 index);
612
				featureProcessor.processFeature(lastFeature);
613
				
614
				
615
			} else {
616
				IFeature feature = createFeature(g, index);
617
				featureProcessor.processFeature(feature);
618
			}
619

  
620
		} catch (com.iver.cit.gvsig.fmap.DriverException e) {
621
			throw new VisitException(
622
					"Error buscando los overlays que intersectan con un feature");
623
		} catch (DriverException e) {
624
			// TODO Auto-generated catch block
625
			e.printStackTrace();
626
		}
627
	}
628

  
629
	private Geometry splitLineString(Geometry linearGeometry,
630
			LinearLocation from, LinearLocation to, LineIntersection fromInt,
631
			LineIntersection toInt) {
632
		Coordinate[] geomCoords = linearGeometry.getCoordinates();
633
		ArrayList coordinates = new ArrayList();
634
		if (fromInt != null)
635
			coordinates.add(fromInt.coordinate);
636
		int startIndex = from.getSegmentIndex();
637
		/*
638
		 * segmentIndex siempre referencia al punto inmediatamente anterior del
639
		 * lineString. Nos interesa sumar 1, a no ser que sea el primer punto
640
		 * del linestring
641
		 */
642
		if (startIndex != 0)
643
			startIndex++;
644
		
645
		for (int i = startIndex; i <= to.getSegmentIndex(); i++) {
646
			coordinates.add(geomCoords[i]);
647
		}
648
		coordinates.add(toInt.coordinate);
649
		Coordinate[] solutionCoords = new Coordinate[coordinates.size()];
650
		coordinates.toArray(solutionCoords);
651
		return new GeometryFactory().createLineString(solutionCoords);
652

  
653
	}
654

  
655
	class LineIntersection {
656
		Coordinate coordinate;
657

  
658
		double lenght;
659
	}
660

  
661
	public String getProcessDescription() {
662
		return "Cleaning lines of a vectorial line layer";
663
	}
664

  
665
	public void stop(FLayer layer) {
666
		this.featureProcessor.finish();
667
		this.intersectProcessor.finish();
668
	}
669

  
670
	public boolean start(FLayer layer) {
671
		if (layer instanceof AlphanumericData && layer instanceof VectorialData) {
672
			try {
673
				layerToClean = (FLyrVect) layer;
674
				recordset = ((AlphanumericData) layer).getRecordset();
675
				strategy = StrategyManager.getStrategy(layerToClean);
676
				featureProcessor.start();
677
				intersectProcessor.start();
678
			} catch (com.iver.cit.gvsig.fmap.DriverException e) {
679
				return false;
680
			} catch (EditionException e) {
681
				return false;
682
			}
683
			return true;
684
		}
685
		return false;
686
	}
687

  
688
	private IFeature createFeature(Geometry jtsGeometry, int firstLayerIndex)
689
			throws DriverException {
690
		IFeature solution = null;
691
		IGeometry cleanedGeometry = FConverter.jts_to_igeometry(jtsGeometry);
692
		FieldDescription[] fields = layerDefinition.getFieldsDesc();
693
		int numFields = fields.length;
694
		Value[] featureAttr = new Value[fields.length];
695
		for (int indexField = 0; indexField < numFields; indexField++) {
696
			// for each field of firstRs
697
			String fieldName = recordset.getFieldName(indexField);
698
			for (int j = 0; j < fields.length; j++) {
699
				if (fieldName.equalsIgnoreCase(fields[j].getFieldName())) {
700
					featureAttr[j] = recordset.getFieldValue(firstLayerIndex,
701
							indexField);
702
					break;
703
				}// if
704
			}// for
705
		}// for
706
		// now we put null values
707
		for (int i = 0; i < featureAttr.length; i++) {
708
			if (featureAttr[i] == null)
709
				featureAttr[i] = ValueFactory.createNullValue();
710
		}
711
		solution = FeatureFactory.createFeature(featureAttr, cleanedGeometry);
712
		return solution;
713
	}
714
	
715
	
716
	
717
	private IFeature createIntersectFeature(Coordinate coord,  int fid1, int fid2){
718
		IFeature solution = null;
719
		Point point = FConverter.geomFactory.createPoint(coord);
720
		IGeometry cleanedGeometry = FConverter.jts_to_igeometry(point);
721
		Value[] values = new Value[2];
722
		values[0] = ValueFactory.createValue(fid1);
723
		values[1] = ValueFactory.createValue(fid2);
724
		solution = FeatureFactory.createFeature(values, cleanedGeometry);
725
		return solution;
726
	}
727

  
728
	private IFeature createFeature(IGeometry g, int firstLayerIndex)
729
			throws DriverException {
730
		IFeature solution = null;
731
		FieldDescription[] fields = layerDefinition.getFieldsDesc();
732
		int numFields = fields.length;
733
		Value[] featureAttr = new Value[fields.length];
734
		for (int indexField = 0; indexField < numFields; indexField++) {
735
			// for each field of firstRs
736
			String fieldName = recordset.getFieldName(indexField);
737
			for (int j = 0; j < fields.length; j++) {
738
				if (fieldName.equalsIgnoreCase(fields[j].getFieldName())) {
739
					featureAttr[j] = recordset.getFieldValue(firstLayerIndex,
740
							indexField);
741
					break;
742
				}// if
743
			}// for
744
		}// for
745
		// now we put null values
746
		for (int i = 0; i < featureAttr.length; i++) {
747
			if (featureAttr[i] == null)
748
				featureAttr[i] = ValueFactory.createNullValue();
749
		}
750
		solution = FeatureFactory.createFeature(featureAttr, g);
751
		return solution;
752
	}
753

  
754
//	public static void main(String[] args) {
755
//		DriverManager dm = new DriverManager();
756
//		dm.setValidation(new DriverValidation() {
757
//			public boolean validate(Driver d) {
758
//				return ((d instanceof ObjectDriver)
759
//						|| (d instanceof FileDriver) || (d instanceof DBDriver));
760
//			}
761
//		});
762
//		dm.loadDrivers(new File(
763
//				"../_fwAndami/gvSIG/extensiones/com.iver.cit.gvsig/drivers"));
764
//		LayerFactory
765
//				.setDriversPath("../_fwAndami/gvSIG/extensiones/com.iver.cit.gvsig/drivers");
766
//
767
//		// Setup del factory de DataSources
768
//		DataSourceFactory dsf = LayerFactory.getDataSourceFactory();
769
//		dsf.setDriverManager(dm);
770
//
771
//		// Setup de las tablas
772
//		// dsf.addFileDataSource("gdbms dbf driver", "nodes", "c:/nodes.dbf");
773
//		// dsf.addFileDataSource("gdbms dbf driver", "edges", "c:/edges.dbf");
774
//
775
//		IProjection prj = CRSFactory.getCRS("EPSG:23030");
776
//		File shpFile = new File("C:/JUMP/datos/cauces_gv.shp");
777
//		try {
778
//			FLyrVect lyr = (FLyrVect) LayerFactory.createLayer("Ejes",
779
//					"gvSIG shp driver", shpFile, prj);
780
//			System.out.println(lyr.getSource().getShapeCount());
781
//
782
//			LayerDefinition definition = new LayerDefinition();
783
//			FieldDescription cauNom = new FieldDescription();
784
//			cauNom.setFieldName("CAUNOM");
785
//			cauNom.setFieldType(XTypes.CHAR);
786
//			cauNom.setFieldLength(10);
787
//			cauNom.setFieldDecimalCount(0);
788
//			definition.setFieldsDesc(new FieldDescription[]{cauNom});
789
//			definition.setShapeType(XTypes.LINE);
790
//			
791
//			
792
//			
793
//			
794
////			LineCleanVisitor visitor = new LineCleanVisitor(
795
////					new FeatureProcessor() {
796
////
797
////						public void processFeature(IRow feature) {
798
////							// TODO Auto-generated method stub
799
////
800
////						}
801
////
802
////						public void finish() {
803
////							// TODO Auto-generated method stub
804
////
805
////						}
806
////
807
////						public void start() throws EditionException {
808
////							// TODO Auto-generated method stub
809
////
810
////						}
811
////					}, false, definition);
812
//			Strategy str = StrategyManager.getStrategy(lyr);
813
////			str.process(visitor);
814
//
815
////		} catch (com.iver.cit.gvsig.fmap.DriverException e) {
816
////			// TODO Auto-generated catch block
817
////			e.printStackTrace();
818
////		} catch (DriverIOException e) {
819
////			// TODO Auto-generated catch block
820
////			e.printStackTrace();
821
////		} catch (VisitException e) {
822
////			// TODO Auto-generated catch block
823
////			e.printStackTrace();
824
////		}
825
//	}
826

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

Also available in: Unified diff