svn-gvsig-desktop / trunk / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / impl / difference / fmap / DifferenceGeoprocess.java @ 10626
History | View | Annotate | Download (12.9 KB)
1 |
/*
|
---|---|
2 |
* Created on 22-feb-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: DifferenceGeoprocess.java 10626 2007-03-06 16:55:54Z caballero $
|
47 |
* $Log$
|
48 |
* Revision 1.3 2007-03-06 16:47:58 caballero
|
49 |
* Exceptions
|
50 |
*
|
51 |
* Revision 1.2 2006/06/29 07:33:57 fjp
|
52 |
* Cambios ISchemaManager y IFieldManager por terminar
|
53 |
*
|
54 |
* Revision 1.1 2006/06/20 18:20:45 azabala
|
55 |
* first version in cvs
|
56 |
*
|
57 |
* Revision 1.2 2006/06/08 18:24:23 azabala
|
58 |
* modificaciones para admitir capas de shapeType MULTI
|
59 |
*
|
60 |
* Revision 1.1 2006/05/24 21:11:38 azabala
|
61 |
* primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
|
62 |
*
|
63 |
* Revision 1.10 2006/05/01 19:15:37 azabala
|
64 |
* la cancelacion no solo para el ITask que ejecuta el geoproceso, adem?s llama al metodo cancel() del mismo (que se supone que deber?a hacer un drop() con los resultados del geoproceso inconcluso)
|
65 |
*
|
66 |
* Revision 1.9 2006/03/26 20:02:25 azabala
|
67 |
* *** empty log message ***
|
68 |
*
|
69 |
* Revision 1.8 2006/03/21 19:26:53 azabala
|
70 |
* *** empty log message ***
|
71 |
*
|
72 |
* Revision 1.7 2006/03/17 19:53:05 azabala
|
73 |
* *** empty log message ***
|
74 |
*
|
75 |
* Revision 1.6 2006/03/15 18:31:50 azabala
|
76 |
* *** empty log message ***
|
77 |
*
|
78 |
* Revision 1.5 2006/03/14 18:32:46 fjp
|
79 |
* Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
|
80 |
*
|
81 |
* Revision 1.4 2006/03/07 21:01:33 azabala
|
82 |
* *** empty log message ***
|
83 |
*
|
84 |
* Revision 1.3 2006/03/06 19:48:39 azabala
|
85 |
* *** empty log message ***
|
86 |
*
|
87 |
* Revision 1.2 2006/03/05 19:57:58 azabala
|
88 |
* *** empty log message ***
|
89 |
*
|
90 |
* Revision 1.1 2006/02/26 20:53:13 azabala
|
91 |
* *** empty log message ***
|
92 |
*
|
93 |
*
|
94 |
*/
|
95 |
package com.iver.cit.gvsig.geoprocess.impl.difference.fmap; |
96 |
|
97 |
import java.util.Map; |
98 |
|
99 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
100 |
import com.hardcode.gdbms.driver.exceptions.SchemaEditionException; |
101 |
import com.iver.andami.PluginServices; |
102 |
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException; |
103 |
import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException; |
104 |
import com.iver.cit.gvsig.exceptions.visitors.VisitorException; |
105 |
import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
106 |
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition; |
107 |
import com.iver.cit.gvsig.fmap.layers.FBitSet; |
108 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
109 |
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy; |
110 |
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager; |
111 |
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess; |
112 |
import com.iver.cit.gvsig.geoprocess.core.fmap.DefinitionUtils; |
113 |
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2; |
114 |
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException; |
115 |
import com.iver.cit.gvsig.geoprocess.core.fmap.IOverlayGeoprocess; |
116 |
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes; |
117 |
import com.iver.utiles.swing.threads.CancellableMonitorable; |
118 |
import com.iver.utiles.swing.threads.DefaultCancellableMonitorable; |
119 |
import com.iver.utiles.swing.threads.IMonitorableTask; |
120 |
|
121 |
/**
|
122 |
* This geoprocess computes diference geometries of two overlay polygon layers.
|
123 |
* Difference of two geometries is the set of point of one geometry that the
|
124 |
* other geometry doesnt have.
|
125 |
* By analogy, this geoprocess computes difference geometries between vectorial
|
126 |
* layers.
|
127 |
*
|
128 |
* @author azabala
|
129 |
*
|
130 |
*/
|
131 |
public class DifferenceGeoprocess extends AbstractGeoprocess |
132 |
implements IOverlayGeoprocess {
|
133 |
|
134 |
/**
|
135 |
* overlay layer
|
136 |
*/
|
137 |
private FLyrVect overlayLayer;
|
138 |
|
139 |
/**
|
140 |
* Schema of the result layer
|
141 |
*/
|
142 |
private ILayerDefinition resultLayerDefinition;
|
143 |
|
144 |
/**
|
145 |
* flag to only clip selection of input layer
|
146 |
*/
|
147 |
private boolean onlyFirstLayerSelection = false; |
148 |
|
149 |
/**
|
150 |
* flag to only clip with selection of clipping layer
|
151 |
*/
|
152 |
private boolean onlyClipLayerSelection = false; |
153 |
|
154 |
public DifferenceGeoprocess(FLyrVect inputLayer) {
|
155 |
setFirstOperand(inputLayer); |
156 |
} |
157 |
|
158 |
public void setSecondOperand(FLyrVect overlayLayer) { |
159 |
this.overlayLayer = overlayLayer;
|
160 |
|
161 |
} |
162 |
|
163 |
public void setFirstOperand(FLyrVect firstLayer) { |
164 |
this.firstLayer = firstLayer;
|
165 |
} |
166 |
|
167 |
public void setParameters(Map params) throws GeoprocessException { |
168 |
Boolean firstLayerSelection = (Boolean) params |
169 |
.get("firstlayerselection");
|
170 |
if (firstLayerSelection != null) |
171 |
this.onlyFirstLayerSelection = firstLayerSelection.booleanValue();
|
172 |
|
173 |
Boolean secondLayerSelection = (Boolean) params |
174 |
.get("secondlayerselection");
|
175 |
if (secondLayerSelection != null) |
176 |
this.onlyClipLayerSelection = secondLayerSelection.booleanValue();
|
177 |
|
178 |
} |
179 |
|
180 |
public void checkPreconditions() throws GeoprocessException { |
181 |
if (firstLayer == null) |
182 |
throw new GeoprocessException( |
183 |
"Interseccion: capa de entrada a null");
|
184 |
if (overlayLayer == null) |
185 |
throw new GeoprocessException("Interseccion: capa de union a null"); |
186 |
if (this.writer == null || this.schemaManager == null) { |
187 |
throw new GeoprocessException( |
188 |
"Operacion de interseccion sin especificar capa de resultados");
|
189 |
} |
190 |
try {
|
191 |
if (firstLayer.getShapeType() != XTypes.POLYGON
|
192 |
&& firstLayer.getShapeType() != XTypes.MULTI) { |
193 |
throw new GeoprocessException( |
194 |
"Primera capa de interseccion no es de pol?gonos");
|
195 |
} |
196 |
if (overlayLayer.getShapeType() != XTypes.POLYGON
|
197 |
&& overlayLayer.getShapeType() != XTypes.MULTI) { |
198 |
throw new GeoprocessException( |
199 |
"Segunda capa de interseccion no es de pol?gonos");
|
200 |
} |
201 |
} catch (ReadDriverException e) {
|
202 |
throw new GeoprocessException( |
203 |
"Error al tratar de chequear si las capas a intersectar son de pol?gonos");
|
204 |
} |
205 |
|
206 |
} |
207 |
|
208 |
|
209 |
//FIXME La unica diferencia entre este geoproceso y el intersection
|
210 |
//es que usa visitors distintos
|
211 |
//REDISE?AR TODOS LOS OVERLAYGEOPROCESS
|
212 |
public void process() throws GeoprocessException { |
213 |
|
214 |
try {
|
215 |
//FIXME Sacar esto de aqu? y ponerlo fuera. Marcaremos como precondicion
|
216 |
//que el esquema del geoproceso haya sido creado
|
217 |
// Prepare the result
|
218 |
this.schemaManager.createSchema(createLayerDefinition());
|
219 |
writer.preProcess(); |
220 |
Strategy strategy = |
221 |
StrategyManager.getStrategy(firstLayer); |
222 |
FeaturePersisterProcessor2 featureProcessor = new FeaturePersisterProcessor2(
|
223 |
writer); |
224 |
Strategy overlayStrategy = |
225 |
StrategyManager.getStrategy(overlayLayer); |
226 |
DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
|
227 |
featureProcessor, overlayStrategy, onlyClipLayerSelection); |
228 |
visitor.setLayerDefinition(resultLayerDefinition); |
229 |
if (this.onlyFirstLayerSelection) { |
230 |
strategy.process(visitor, this.firstLayer.getRecordset()
|
231 |
.getSelection()); |
232 |
} else {
|
233 |
strategy.process(visitor); |
234 |
} |
235 |
|
236 |
} catch (ProcessVisitorException e) {
|
237 |
throw new GeoprocessException( |
238 |
"Error al procesar el feature de una capa durante el geoproceso interseccion");
|
239 |
} catch (ReadDriverException e) {
|
240 |
throw new GeoprocessException( |
241 |
"Error de driver al calcular el geoproceso interseccion");
|
242 |
} catch (SchemaEditionException e) {
|
243 |
throw new GeoprocessException( |
244 |
"Error en el esquema de la nueva capa");
|
245 |
} catch (ExpansionFileReadException e) {
|
246 |
throw new GeoprocessException( |
247 |
"Error de driver al calcular el geoproceso interseccion");
|
248 |
} catch (VisitorException e) {
|
249 |
throw new GeoprocessException( |
250 |
"Error de driver al calcular el geoproceso interseccion");
|
251 |
} |
252 |
} |
253 |
|
254 |
public void cancel() { |
255 |
try {
|
256 |
schemaManager.removeSchema("");
|
257 |
} catch (SchemaEditionException e) {
|
258 |
// TODO Auto-generated catch block
|
259 |
e.printStackTrace(); |
260 |
} |
261 |
} |
262 |
|
263 |
public ILayerDefinition createLayerDefinition() {
|
264 |
if (resultLayerDefinition == null) { |
265 |
try {
|
266 |
// resultLayerDefinition = DefinitionUtils.mergeLayerDefinitions(
|
267 |
// firstLayer, overlayLayer);
|
268 |
resultLayerDefinition = DefinitionUtils.createLayerDefinition(firstLayer); |
269 |
} catch (Exception e) { |
270 |
// TODO Quizas createLayerDefinition deberia lanzar
|
271 |
// una excepcion
|
272 |
e.printStackTrace(); |
273 |
} |
274 |
} |
275 |
return resultLayerDefinition;
|
276 |
} |
277 |
|
278 |
public IMonitorableTask createTask() {
|
279 |
try {
|
280 |
return new DifferenceMonitorableTask(); |
281 |
} catch (DriverIOException e) {
|
282 |
//FIXME Debe lanzar excepcion createTask ?
|
283 |
return null; |
284 |
} |
285 |
} |
286 |
|
287 |
/**
|
288 |
* IMonitorableTask that allows to run diff geoprocess in background,
|
289 |
* with cancelation requests.
|
290 |
*
|
291 |
* @author azabala
|
292 |
*
|
293 |
*/
|
294 |
class DifferenceMonitorableTask implements IMonitorableTask { |
295 |
private CancellableMonitorable cancelMonitor = null; |
296 |
String DIFFERENCE_MESSAGE = PluginServices.getText(this, "Mensaje_difference"); |
297 |
String DIFFERENCE_NOTE = PluginServices.getText(this, "Mensaje_procesando_diferencia"); |
298 |
String OF = PluginServices.getText(this, "De"); |
299 |
private boolean finished = false; |
300 |
|
301 |
DifferenceMonitorableTask() throws DriverIOException {
|
302 |
initialize(); |
303 |
} |
304 |
void initialize() throws DriverIOException { |
305 |
cancelMonitor = createCancelMonitor(); |
306 |
} |
307 |
|
308 |
private CancellableMonitorable createCancelMonitor() {
|
309 |
DefaultCancellableMonitorable monitor = new
|
310 |
DefaultCancellableMonitorable(); |
311 |
monitor.setInitialStep(0);
|
312 |
//Really its undeterminated, but so we must to process all
|
313 |
//elements of first layer (or selection) we are going to
|
314 |
//consideer determinated
|
315 |
monitor.setDeterminatedProcess(true);
|
316 |
int numSteps = 0; |
317 |
if (onlyFirstLayerSelection) {
|
318 |
FBitSet selection = null;
|
319 |
try {
|
320 |
selection = firstLayer.getRecordset().getSelection(); |
321 |
} catch (ReadDriverException e) {
|
322 |
// TODO Auto-generated catch block
|
323 |
e.printStackTrace(); |
324 |
} |
325 |
numSteps = selection.cardinality(); |
326 |
} else {
|
327 |
try {
|
328 |
numSteps = firstLayer.getSource().getShapeCount(); |
329 |
} catch (ReadDriverException e) {
|
330 |
// TODO Auto-generated catch block
|
331 |
e.printStackTrace(); |
332 |
} |
333 |
} |
334 |
monitor.setFinalStep(numSteps); |
335 |
return monitor;
|
336 |
} |
337 |
|
338 |
public int getInitialStep() { |
339 |
return cancelMonitor.getInitialStep();
|
340 |
} |
341 |
|
342 |
public int getFinishStep() { |
343 |
return cancelMonitor.getFinalStep();
|
344 |
} |
345 |
|
346 |
public int getCurrentStep() { |
347 |
return cancelMonitor.getCurrentStep();
|
348 |
} |
349 |
|
350 |
public String getStatusMessage() { |
351 |
return DIFFERENCE_MESSAGE;
|
352 |
} |
353 |
|
354 |
public String getNote() { |
355 |
return DIFFERENCE_NOTE + " " + |
356 |
getCurrentStep() + " "+
|
357 |
OF + " "+
|
358 |
getFinishStep(); |
359 |
} |
360 |
|
361 |
public void cancel() { |
362 |
((DefaultCancellableMonitorable) cancelMonitor).setCanceled(true);
|
363 |
DifferenceGeoprocess.this.cancel(); |
364 |
} |
365 |
|
366 |
public void run() throws GeoprocessException { |
367 |
try {
|
368 |
schemaManager.createSchema(createLayerDefinition()); |
369 |
writer.preProcess(); |
370 |
Strategy strategy = |
371 |
StrategyManager.getStrategy(firstLayer); |
372 |
FeaturePersisterProcessor2 featureProcessor = |
373 |
new FeaturePersisterProcessor2(writer);
|
374 |
Strategy overlayStrategy = |
375 |
StrategyManager.getStrategy(overlayLayer); |
376 |
DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
|
377 |
featureProcessor, overlayStrategy, onlyClipLayerSelection); |
378 |
visitor.setLayerDefinition(resultLayerDefinition); |
379 |
if (onlyFirstLayerSelection) {
|
380 |
strategy.process(visitor, firstLayer.getRecordset() |
381 |
.getSelection(), cancelMonitor); |
382 |
} else {
|
383 |
strategy.process(visitor, cancelMonitor); |
384 |
} |
385 |
|
386 |
} catch (ProcessVisitorException e) {
|
387 |
throw new GeoprocessException( |
388 |
"Error al procesar el feature de una capa durante el geoproceso interseccion");
|
389 |
} catch (SchemaEditionException e) {
|
390 |
throw new GeoprocessException( |
391 |
"Error al crear el esquema/fichero de la nueva capa");
|
392 |
} catch (ReadDriverException e) {
|
393 |
throw new GeoprocessException( |
394 |
"Error de driver al calcular el geoproceso interseccion");
|
395 |
} catch (ExpansionFileReadException e) {
|
396 |
throw new GeoprocessException( |
397 |
"Error de driver al calcular el geoproceso interseccion");
|
398 |
} catch (VisitorException e) {
|
399 |
throw new GeoprocessException( |
400 |
"Error de driver al calcular el geoproceso interseccion");
|
401 |
}finally{
|
402 |
finished = true;
|
403 |
} |
404 |
} |
405 |
|
406 |
public boolean isDefined() { |
407 |
return cancelMonitor.isDeterminatedProcess();
|
408 |
} |
409 |
|
410 |
public boolean isCanceled() { |
411 |
return cancelMonitor.isCanceled();
|
412 |
} |
413 |
|
414 |
public boolean isFinished() { |
415 |
return finished;
|
416 |
} |
417 |
} |
418 |
|
419 |
} |