svn-gvsig-desktop / tags / v1_1_Build_1012 / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / impl / buffer / fmap / BufferGeoprocess.java @ 12987
History | View | Annotate | Download (21.2 KB)
1 |
/*
|
---|---|
2 |
* Created on 01-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: BufferGeoprocess.java 12987 2007-08-08 12:33:32Z $
|
47 |
* $Log$
|
48 |
* Revision 1.3.2.1 2007-07-12 09:27:16 azabala
|
49 |
* optimizations in dissolution of buffered features (we dont use strategies to avoid reading of geometries already processed)
|
50 |
*
|
51 |
* Revision 1.3 2006/07/21 11:04:50 azabala
|
52 |
* Unified createTask and process() methods
|
53 |
*
|
54 |
* Revision 1.2 2006/06/29 07:33:57 fjp
|
55 |
* Cambios ISchemaManager y IFieldManager por terminar
|
56 |
*
|
57 |
* Revision 1.1 2006/06/20 18:20:45 azabala
|
58 |
* first version in cvs
|
59 |
*
|
60 |
* Revision 1.2 2006/06/02 18:20:58 azabala
|
61 |
* cuando el buffer es con dissolve se crea indice espacial para optimizar
|
62 |
*
|
63 |
* Revision 1.1 2006/05/24 21:14:41 azabala
|
64 |
* primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
|
65 |
*
|
66 |
* Revision 1.14 2006/05/01 19:18:09 azabala
|
67 |
* revisi?n general del buffer (a?adidos anillos concentricos, buffers interiores y exteriores, etc)
|
68 |
*
|
69 |
* Revision 1.13 2006/03/23 21:02:58 azabala
|
70 |
* *** empty log message ***
|
71 |
*
|
72 |
* Revision 1.12 2006/03/17 19:52:31 azabala
|
73 |
* *** empty log message ***
|
74 |
*
|
75 |
* Revision 1.11 2006/03/14 19:35:13 azabala
|
76 |
* *** empty log message ***
|
77 |
*
|
78 |
* Revision 1.10 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.9 2006/03/07 21:01:33 azabala
|
82 |
* *** empty log message ***
|
83 |
*
|
84 |
* Revision 1.8 2006/03/06 19:48:39 azabala
|
85 |
* *** empty log message ***
|
86 |
*
|
87 |
* Revision 1.7 2006/03/05 19:56:40 azabala
|
88 |
* *** empty log message ***
|
89 |
*
|
90 |
* Revision 1.6 2006/02/17 16:04:50 azabala
|
91 |
* *** empty log message ***
|
92 |
*
|
93 |
* Revision 1.5 2006/02/13 21:13:49 azabala
|
94 |
* *** empty log message ***
|
95 |
*
|
96 |
* Revision 1.4 2006/02/13 18:38:03 azabala
|
97 |
* *** empty log message ***
|
98 |
*
|
99 |
* Revision 1.3 2006/02/13 17:52:45 azabala
|
100 |
* *** empty log message ***
|
101 |
*
|
102 |
* Revision 1.2 2006/02/12 21:02:44 azabala
|
103 |
* *** empty log message ***
|
104 |
*
|
105 |
* Revision 1.1 2006/02/02 19:47:12 azabala
|
106 |
* many refactorings
|
107 |
*
|
108 |
* Revision 1.1 2006/02/01 19:42:04 azabala
|
109 |
* First version in CVS
|
110 |
*
|
111 |
*
|
112 |
*/
|
113 |
package com.iver.cit.gvsig.geoprocess.impl.buffer.fmap; |
114 |
|
115 |
import java.io.File; |
116 |
import java.io.IOException; |
117 |
import java.util.Map; |
118 |
|
119 |
import org.cresques.cts.ICoordTrans; |
120 |
import org.cresques.cts.IProjection; |
121 |
|
122 |
import com.iver.andami.PluginServices; |
123 |
import com.iver.cit.gvsig.fmap.DriverException; |
124 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
125 |
import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
126 |
import com.iver.cit.gvsig.fmap.drivers.FieldDescription; |
127 |
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition; |
128 |
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition; |
129 |
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition; |
130 |
import com.iver.cit.gvsig.fmap.drivers.shp.IndexedShpDriver; |
131 |
import com.iver.cit.gvsig.fmap.edition.EditionException; |
132 |
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter; |
133 |
import com.iver.cit.gvsig.fmap.layers.FBitSet; |
134 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
135 |
import com.iver.cit.gvsig.fmap.layers.LayerFactory; |
136 |
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial; |
137 |
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy; |
138 |
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager; |
139 |
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException; |
140 |
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess; |
141 |
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2; |
142 |
import com.iver.cit.gvsig.geoprocess.core.fmap.GeometryPersisterProcessor; |
143 |
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException; |
144 |
import com.iver.cit.gvsig.geoprocess.core.fmap.IOneLayerGeoprocess; |
145 |
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes; |
146 |
import com.iver.cit.gvsig.geoprocess.impl.dissolve.fmap.AdjacencyDissolveVisitor; |
147 |
import com.iver.cit.gvsig.geoprocess.impl.dissolve.fmap.DissolveVisitor; |
148 |
import com.iver.utiles.swing.threads.CancellableMonitorable; |
149 |
import com.iver.utiles.swing.threads.DefaultCancellableMonitorable; |
150 |
import com.iver.utiles.swing.threads.IMonitorableTask; |
151 |
|
152 |
/**
|
153 |
* Geoprocess that computes a buffer area around each feature's geometry of the
|
154 |
* input layer. <br>
|
155 |
* All the points interior to this buffer area has to be at a distance inferior
|
156 |
* to "buffer distance" to the original geometry. This buffer distance could be
|
157 |
* constant, or it could be a function of the value of a feature attribute.<br>
|
158 |
*
|
159 |
* @author azabala
|
160 |
*
|
161 |
*/
|
162 |
public class BufferGeoprocess extends AbstractGeoprocess implements |
163 |
IOneLayerGeoprocess { |
164 |
|
165 |
/**
|
166 |
* flag that represents buffer computing with one only buffer distance.
|
167 |
*/
|
168 |
public static final byte CONSTANT_DISTANCE_STRATEGY = 0; |
169 |
|
170 |
/**
|
171 |
* buffer computing with variable buffer distance in function of feature
|
172 |
* attribute value
|
173 |
*/
|
174 |
public static final byte ATTRIBUTE_DISTANCE_STRATEGY = 1; |
175 |
|
176 |
|
177 |
/**
|
178 |
* Schema of the result layer
|
179 |
*/
|
180 |
private ILayerDefinition resultLayerDefinition;
|
181 |
|
182 |
/**
|
183 |
* the geoprocess will operate only with selected elements of layer, or with
|
184 |
* all elements.<br>
|
185 |
* By default, it work with all elements.
|
186 |
*/
|
187 |
private boolean bufferOnlySelection = false; |
188 |
|
189 |
/**
|
190 |
* this flag makes the process to dissolve or not geometries of the result
|
191 |
* layer, to avoid intersections in a polygon layer. By default, is true.<br>
|
192 |
*/
|
193 |
private boolean dissolveBuffers = false; |
194 |
|
195 |
/**
|
196 |
* Iterates over input layer geometries to compute buffered geometries by
|
197 |
* using a distance buffer function.
|
198 |
*/
|
199 |
private BufferVisitor bufferVisitor;
|
200 |
|
201 |
/**
|
202 |
* Constructor
|
203 |
*
|
204 |
* @param bufferLayer
|
205 |
* layer to buffer
|
206 |
*/
|
207 |
public BufferGeoprocess(FLyrVect bufferLayer) {
|
208 |
setFirstOperand(bufferLayer); |
209 |
} |
210 |
|
211 |
/**
|
212 |
* Sets layer to buffer
|
213 |
*/
|
214 |
public void setFirstOperand(FLyrVect bufferLayer) { |
215 |
this.firstLayer = bufferLayer;
|
216 |
} |
217 |
|
218 |
/**
|
219 |
* Sets user entry params to this geoprocess. This params represents user
|
220 |
* preferences (FLayer are not optional params)
|
221 |
*/
|
222 |
public void setParameters(Map params) throws GeoprocessException { |
223 |
Boolean onlySelection = (Boolean) params.get("layer_selection"); |
224 |
if (onlySelection != null) |
225 |
bufferOnlySelection = onlySelection.booleanValue(); |
226 |
|
227 |
Boolean dissolve = (Boolean) params.get("dissolve_buffers"); |
228 |
if (dissolve != null) |
229 |
dissolveBuffers = dissolve.booleanValue(); |
230 |
|
231 |
Byte strategy_flat = (Byte) params.get("strategy_flag"); |
232 |
if (strategy_flat != null |
233 |
&& strategy_flat.byteValue() == ATTRIBUTE_DISTANCE_STRATEGY) { |
234 |
// must check attribute name not null
|
235 |
String attributeName = (String) params.get("attr_name"); |
236 |
if (attributeName != null) { |
237 |
bufferVisitor = new AttributeBufferVisitor(attributeName);
|
238 |
} else {
|
239 |
throw new GeoprocessException( |
240 |
"Buffer por atributo sin nombre de atributo");
|
241 |
} |
242 |
} else {
|
243 |
// default, constant strategy
|
244 |
// must check distance not null
|
245 |
Double dist = (Double) params.get("buffer_distance"); |
246 |
if (dist != null) { |
247 |
double distance = dist.doubleValue();
|
248 |
bufferVisitor = new ConstantDistanceBufferVisitor(distance);
|
249 |
} else {
|
250 |
throw new GeoprocessException( |
251 |
"Buffer por dist constante sin distancia");
|
252 |
} |
253 |
}// else
|
254 |
|
255 |
Byte capflag = (Byte) params.get("cap"); |
256 |
if(capflag != null){ |
257 |
bufferVisitor.setTypeOfCap(capflag.byteValue()); |
258 |
} |
259 |
|
260 |
Byte typePolFlag = (Byte) params.get("typePolBuffer"); |
261 |
if(typePolFlag != null){ |
262 |
bufferVisitor.setTypeOfBuffer(typePolFlag.byteValue()); |
263 |
} |
264 |
|
265 |
Integer numRingsFlag = (Integer) params.get("numRings"); |
266 |
if(numRingsFlag != null){ |
267 |
bufferVisitor.setNumberOfRadialBuffers(numRingsFlag.intValue()); |
268 |
} |
269 |
} |
270 |
|
271 |
|
272 |
/**
|
273 |
* Checks preconditions to this geoprocess (input layer mustnt be null), etc
|
274 |
*/
|
275 |
public void checkPreconditions() throws GeoprocessException { |
276 |
if (firstLayer == null) |
277 |
throw new GeoprocessException("Buffer con capa de entrada a null"); |
278 |
if (this.writer == null || this.schemaManager == null) { |
279 |
throw new GeoprocessException( |
280 |
"Operacion de buffer sin especificar capa de resultados");
|
281 |
} |
282 |
} |
283 |
|
284 |
/**
|
285 |
* Computes buffer geoprocess, and saves results in solution layer.
|
286 |
*
|
287 |
*/
|
288 |
public void process() throws GeoprocessException { |
289 |
try {
|
290 |
createTask().run(); |
291 |
} catch (Exception e) { |
292 |
throw new GeoprocessException("Error durante la ejecuci?n del buffer", e); |
293 |
} |
294 |
} |
295 |
|
296 |
/**
|
297 |
* Creates a temp layer with the file referenced by writer.
|
298 |
* It is useful when you want to dissolve buffers, to avoid working
|
299 |
* with intermediate results in memory.
|
300 |
* @return
|
301 |
* @throws IOException
|
302 |
* @throws DriverException
|
303 |
*/
|
304 |
public FLyrVect createTempLayer() throws IOException, DriverException { |
305 |
FLyrVect solution = null;
|
306 |
String fileName = ((ShpWriter) writer).getShpPath();
|
307 |
File file = new File(fileName); |
308 |
IProjection proj = firstLayer.getProjection(); |
309 |
IndexedShpDriver driver = new IndexedShpDriver();
|
310 |
driver.open(file); |
311 |
driver.initialize(); |
312 |
solution = (FLyrVect) LayerFactory.createLayer(fileName, driver, file, |
313 |
proj); |
314 |
return solution;
|
315 |
|
316 |
} |
317 |
|
318 |
private void computeAndDissolveBuffer(Strategy strategy, |
319 |
CancellableMonitorable cancel) throws EditionException,
|
320 |
DriverException, VisitException, IOException {
|
321 |
|
322 |
ShpWriter mainWriter = (ShpWriter) writer; |
323 |
writer = new ShpWriter();
|
324 |
String temp = System.getProperty("java.io.tmpdir") + "/buffer" |
325 |
+ System.currentTimeMillis() + ".shp"; |
326 |
File newFile = new File(temp); |
327 |
((ShpWriter) writer).setFile(newFile); |
328 |
((ShpWriter) writer) |
329 |
.initialize((LayerDefinition) resultLayerDefinition); |
330 |
((SHPLayerDefinition) resultLayerDefinition).setFile(newFile); |
331 |
schemaManager.createSchema(resultLayerDefinition); |
332 |
bufferVisitor.setBufferProcessor(new GeometryPersisterProcessor(
|
333 |
resultLayerDefinition, schemaManager, writer)); |
334 |
|
335 |
computeOnlyBuffers(strategy, cancel); |
336 |
FLyrVect tempLayer = createTempLayer(); |
337 |
|
338 |
writer = mainWriter; |
339 |
FeaturePersisterProcessor2 processor = new FeaturePersisterProcessor2(
|
340 |
writer); |
341 |
AdjacencyDissolveVisitor dissolveVisitor = |
342 |
new AdjacencyDissolveVisitor(null, processor); |
343 |
Strategy secondPassStrategy = StrategyManager.getStrategy(tempLayer); |
344 |
dissolveVisitor.setStrategy(secondPassStrategy); |
345 |
long t0 = System.currentTimeMillis(); |
346 |
secondPassStrategy.process(dissolveVisitor, cancel); |
347 |
long t1 = System.currentTimeMillis(); |
348 |
System.out.println((t1-t0)+" en dissolver los buffers"); |
349 |
} |
350 |
|
351 |
/**
|
352 |
* Computes buffers of input layer, and saves them with the
|
353 |
* actual writer.
|
354 |
* @param strategy
|
355 |
* @param cancel
|
356 |
* @throws EditionException
|
357 |
* @throws DriverException
|
358 |
* @throws VisitException
|
359 |
*/
|
360 |
private void computeOnlyBuffers(Strategy strategy, |
361 |
CancellableMonitorable cancel) throws EditionException,
|
362 |
DriverException, VisitException { |
363 |
|
364 |
bufferVisitor.setBufferProcessor(new GeometryPersisterProcessor(
|
365 |
this.resultLayerDefinition, this.schemaManager, this.writer)); |
366 |
|
367 |
if (bufferOnlySelection) {
|
368 |
strategy.process(bufferVisitor, firstLayer.getRecordset() |
369 |
.getSelection(), cancel); |
370 |
} else {
|
371 |
strategy.process(bufferVisitor, cancel); |
372 |
} |
373 |
} |
374 |
|
375 |
/**
|
376 |
* Creates a LayerDefinition in function of:
|
377 |
* a) input layer
|
378 |
* b) user selections
|
379 |
* c) buffer geoprocess itselt operation
|
380 |
*
|
381 |
* Users of this geoprocess may construct a Writer from this LayerDefinition
|
382 |
* (for example, to save to shp ShpWriter needs a File and a LayerDefinition
|
383 |
* -to create this file with the proper schema-)
|
384 |
*
|
385 |
* FIXME
|
386 |
* We cant call this method before setParams(Map params). Launch a exception
|
387 |
*
|
388 |
* ILayerDefinition wont be the same for dissolved buffers layers
|
389 |
*
|
390 |
*/
|
391 |
public ILayerDefinition createLayerDefinition() {
|
392 |
// In a buffer geoprocess we only well have a geometry
|
393 |
// and a FID
|
394 |
if (resultLayerDefinition == null) { |
395 |
// if(dissolveBuffers){
|
396 |
// resultLayerDefinition = createDissolvedBuffersDefinition();
|
397 |
// }else{
|
398 |
if(bufferVisitor.getTypeOfBuffer() == BufferVisitor.BUFFER_INSIDE_OUTSIDE_POLY){
|
399 |
resultLayerDefinition = createPositiveAndNegativeBufferDefinition(); |
400 |
}else{
|
401 |
resultLayerDefinition = createPositiveOrNegativeBufferDefinition(); |
402 |
} |
403 |
// }
|
404 |
} |
405 |
return resultLayerDefinition;
|
406 |
} |
407 |
|
408 |
/**
|
409 |
* Auxilar method to create a layer definition for buffer's process which
|
410 |
* needs to create only internal or external buffers.
|
411 |
* @return
|
412 |
*/
|
413 |
protected ILayerDefinition createPositiveOrNegativeBufferDefinition(){
|
414 |
ILayerDefinition resultLayerDefinition = new SHPLayerDefinition();
|
415 |
resultLayerDefinition.setShapeType(XTypes.POLYGON); |
416 |
FieldDescription[] fields = new FieldDescription[2]; |
417 |
fields[0] = new FieldDescription(); |
418 |
fields[0].setFieldLength(10); |
419 |
fields[0].setFieldName("FID"); |
420 |
fields[0].setFieldType(XTypes.BIGINT);
|
421 |
fields[1] = new FieldDescription(); |
422 |
fields[1].setFieldLength(10); |
423 |
fields[1].setFieldDecimalCount(4); |
424 |
fields[1].setFieldName("DIST"); |
425 |
fields[1].setFieldType(XTypes.DOUBLE);
|
426 |
resultLayerDefinition.setFieldsDesc(fields); |
427 |
return resultLayerDefinition;
|
428 |
} |
429 |
|
430 |
|
431 |
/**
|
432 |
* Auxilar method to create a layer definition for buffer's process which
|
433 |
* needs to create internal and external buffers.
|
434 |
* @return
|
435 |
*/
|
436 |
protected ILayerDefinition createPositiveAndNegativeBufferDefinition(){
|
437 |
ILayerDefinition resultLayerDefinition = new SHPLayerDefinition();
|
438 |
resultLayerDefinition.setShapeType(XTypes.POLYGON); |
439 |
FieldDescription[] fields = new FieldDescription[3]; |
440 |
fields[0] = new FieldDescription(); |
441 |
fields[0].setFieldLength(10); |
442 |
fields[0].setFieldName("FID"); |
443 |
fields[0].setFieldType(XTypes.BIGINT);
|
444 |
fields[1] = new FieldDescription(); |
445 |
fields[1].setFieldLength(10); |
446 |
fields[1].setFieldDecimalCount(4); |
447 |
fields[1].setFieldName("FROM"); |
448 |
fields[1].setFieldType(XTypes.DOUBLE);
|
449 |
fields[2] = new FieldDescription(); |
450 |
fields[2].setFieldLength(10); |
451 |
fields[2].setFieldDecimalCount(4); |
452 |
fields[2].setFieldName("TO"); |
453 |
fields[2].setFieldType(XTypes.DOUBLE);
|
454 |
|
455 |
resultLayerDefinition.setFieldsDesc(fields); |
456 |
return resultLayerDefinition;
|
457 |
} |
458 |
|
459 |
/**
|
460 |
* Creates a CancelableMonitorable instance to monitor and cancels
|
461 |
* ITask's buffer creation.
|
462 |
* @return
|
463 |
*/
|
464 |
private DefaultCancellableMonitorable createCancelMonitor() {
|
465 |
DefaultCancellableMonitorable monitor = new DefaultCancellableMonitorable();
|
466 |
monitor.setInitialStep(0);
|
467 |
if (this.bufferOnlySelection) { |
468 |
FBitSet selection = null;
|
469 |
try {
|
470 |
selection = firstLayer.getRecordset().getSelection(); |
471 |
} catch (DriverException e) {
|
472 |
// TODO Auto-generated catch block
|
473 |
e.printStackTrace(); |
474 |
} |
475 |
int numSelected = selection.cardinality();
|
476 |
monitor.setFinalStep(numSelected); |
477 |
} else {
|
478 |
try {
|
479 |
monitor.setFinalStep(firstLayer.getSource().getShapeCount()); |
480 |
} catch (DriverIOException e) {
|
481 |
e.printStackTrace(); |
482 |
} |
483 |
} |
484 |
if (!dissolveBuffers) {
|
485 |
// if we dont look for adjacents, is a determinated
|
486 |
// task (we know how many steps we are going to do
|
487 |
monitor.setDeterminatedProcess(true);
|
488 |
|
489 |
} else {
|
490 |
monitor.setDeterminatedProcess(false);
|
491 |
}// if dissolvebuffer
|
492 |
return monitor;
|
493 |
} |
494 |
|
495 |
public IMonitorableTask createTask() {
|
496 |
/*
|
497 |
* Allows to monitor and cancel the task
|
498 |
*/
|
499 |
final CancellableMonitorable cancelMonitor = createCancelMonitor();
|
500 |
/*
|
501 |
* Main Message for reporting buffer geoprocess
|
502 |
*/
|
503 |
final String message = PluginServices.getText(this, "Mensaje_buffer"); |
504 |
/*
|
505 |
* Message for report individual step of buffer computation
|
506 |
*/
|
507 |
final String note = PluginServices.getText(this, |
508 |
"Mensaje_procesando_buffer");
|
509 |
/*
|
510 |
* Message for report individual step of dissolving of buffers
|
511 |
*/
|
512 |
final String note2 = PluginServices.getText(this, |
513 |
"Mensaje_procesando_buffer2");
|
514 |
/*
|
515 |
* Concatenation string
|
516 |
*/
|
517 |
final String of = PluginServices.getText(this, "De"); |
518 |
|
519 |
return new IMonitorableTask() { |
520 |
DissolveVisitor dissolveVisitor; |
521 |
|
522 |
private boolean finished = false; |
523 |
String currentNote = note;
|
524 |
|
525 |
public int getInitialStep() { |
526 |
return cancelMonitor.getInitialStep();
|
527 |
} |
528 |
|
529 |
public int getFinishStep() { |
530 |
return cancelMonitor.getFinalStep();
|
531 |
} |
532 |
|
533 |
public int getCurrentStep() { |
534 |
if(currentNote == note2)
|
535 |
return dissolveVisitor.getDissolvedGeometries().cardinality();
|
536 |
else
|
537 |
return cancelMonitor.getCurrentStep();
|
538 |
} |
539 |
|
540 |
public String getStatusMessage() { |
541 |
return message;
|
542 |
} |
543 |
|
544 |
public String getNote() { |
545 |
return currentNote + ": " + getCurrentStep() + " " + of + " " |
546 |
+ getFinishStep(); |
547 |
} |
548 |
|
549 |
public void cancel() { |
550 |
((DefaultCancellableMonitorable) cancelMonitor) |
551 |
.setCanceled(true);
|
552 |
BufferGeoprocess.this.cancel(); |
553 |
} |
554 |
|
555 |
public void run() { |
556 |
|
557 |
Strategy strategy = StrategyManager.getStrategy(firstLayer); |
558 |
resultLayerDefinition = createLayerDefinition(); |
559 |
try {
|
560 |
if (dissolveBuffers) {
|
561 |
//computeAndDissolveBuffer(strategy, cancelMonitor);
|
562 |
ShpWriter mainWriter = (ShpWriter) writer; |
563 |
writer = new ShpWriter();
|
564 |
String temp = System.getProperty("java.io.tmpdir") + |
565 |
"/buffer" +
|
566 |
System.currentTimeMillis() +
|
567 |
".shp";
|
568 |
File newFile = new File(temp); |
569 |
((ShpWriter) writer).setFile(newFile); |
570 |
((ShpWriter) writer).initialize( |
571 |
(LayerDefinition) resultLayerDefinition); |
572 |
((SHPLayerDefinition) resultLayerDefinition).setFile(newFile); |
573 |
schemaManager.createSchema(resultLayerDefinition); |
574 |
bufferVisitor.setBufferProcessor(new GeometryPersisterProcessor(
|
575 |
resultLayerDefinition, schemaManager, writer)); |
576 |
computeOnlyBuffers(strategy, cancelMonitor); |
577 |
|
578 |
//dissolving buffers
|
579 |
cancelMonitor.setCurrentStep(0);
|
580 |
FLyrVect tempLayer = createTempLayer(); |
581 |
tempLayer.createSpatialIndex(); |
582 |
cancelMonitor.setFinalStep(tempLayer.getSource().getShapeCount()); |
583 |
writer = mainWriter; |
584 |
FeaturePersisterProcessor2 processor = new FeaturePersisterProcessor2(
|
585 |
writer); |
586 |
// AdjacencyDissolveVisitor dissolveVisitor =
|
587 |
// new AdjacencyDissolveVisitor(null, processor);
|
588 |
dissolveVisitor = |
589 |
createDissolveVisitor(processor); |
590 |
currentNote = note2; |
591 |
|
592 |
|
593 |
Strategy secondPassStrategy = StrategyManager.getStrategy(tempLayer); |
594 |
dissolveVisitor.setStrategy(secondPassStrategy); |
595 |
if(dissolveVisitor instanceof AdjacencyDissolveVisitor){ |
596 |
((AdjacencyDissolveVisitor)dissolveVisitor).setCancelMonitor(cancelMonitor); |
597 |
} |
598 |
// secondPassStrategy.process(dissolveVisitor, cancelMonitor);
|
599 |
|
600 |
|
601 |
ReadableVectorial source = tempLayer.getSource(); |
602 |
ICoordTrans ct = tempLayer.getCoordTrans(); |
603 |
|
604 |
if(dissolveVisitor.start(tempLayer)){
|
605 |
source.start(); |
606 |
for (int i = 0; i < source.getShapeCount(); i++) { |
607 |
if(cancelMonitor.isCanceled()){
|
608 |
source.stop(); |
609 |
return;
|
610 |
} |
611 |
if(dissolveVisitor.getDissolvedGeometries().get(i))
|
612 |
continue;
|
613 |
IGeometry geom = source.getShape(i); |
614 |
if (ct != null) { |
615 |
geom.reProject(ct); |
616 |
} |
617 |
dissolveVisitor.visit(geom, i); |
618 |
}//for
|
619 |
source.stop(); |
620 |
} |
621 |
dissolveVisitor.stop(tempLayer); |
622 |
|
623 |
} else {
|
624 |
computeOnlyBuffers(strategy, cancelMonitor); |
625 |
} |
626 |
finished = true;
|
627 |
} catch (Exception e) { |
628 |
e.printStackTrace(); |
629 |
finished = true;
|
630 |
} |
631 |
} |
632 |
|
633 |
/**
|
634 |
* Creates a DissolveVisitor to dissolve computed buffers.
|
635 |
* If we only computed a ring buffer, dissolve
|
636 |
* criteria will be adjacency.
|
637 |
* If we computed many buffers, dissolve criteria will be
|
638 |
* adjacency and alphanumeric (value of FROM-TO or DISTANCE fields of the
|
639 |
* buffer geometry)
|
640 |
* @return
|
641 |
*/
|
642 |
private DissolveVisitor createDissolveVisitor(FeaturePersisterProcessor2 processor) {
|
643 |
//int numBuffers = bufferVisitor.getNumberOfRadialBuffers();
|
644 |
//if(numBuffers == 1){
|
645 |
return new AdjacencyDissolveVisitor(null,processor); |
646 |
//}
|
647 |
/*DOCUMENTAR ESTE CASO
|
648 |
else{
|
649 |
//Esto no funciona bien. Para dissolver buffers
|
650 |
//con varios rings, da errores topol?gicos.
|
651 |
|
652 |
//La ?nica soluci?n es calcular 1? la uni?n, luego
|
653 |
//y luego los multirings
|
654 |
|
655 |
if(bufferVisitor.getTypeOfBuffer() == BufferVisitor.BUFFER_INSIDE_OUTSIDE_POLY){
|
656 |
return new DissolveVisitor("FROM", processor);
|
657 |
}else{
|
658 |
return new DissolveVisitor("DIST", processor);
|
659 |
}
|
660 |
}
|
661 |
*/
|
662 |
} |
663 |
|
664 |
public boolean isDefined() { |
665 |
return cancelMonitor.isDeterminatedProcess();
|
666 |
} |
667 |
|
668 |
public boolean isCanceled() { |
669 |
return cancelMonitor.isCanceled();
|
670 |
} |
671 |
|
672 |
public boolean isFinished() { |
673 |
return finished;
|
674 |
} |
675 |
}; |
676 |
} |
677 |
} |