svn-gvsig-desktop / trunk / extensions / extGeoprocessingExtensions / src / com / iver / cit / gvsig / geoprocess / impl / topology / polygonbuild / fmap / PolygonBuildGeoprocess.java @ 10626
History | View | Annotate | Download (20.5 KB)
1 |
/*
|
---|---|
2 |
* Created on 15-dic-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: PolygonBuildGeoprocess.java 10626 2007-03-06 16:55:54Z caballero $
|
47 |
* $Log$
|
48 |
* Revision 1.3 2007-03-06 16:48:14 caballero
|
49 |
* Exceptions
|
50 |
*
|
51 |
* Revision 1.2 2006/12/21 17:43:33 azabala
|
52 |
* added filtering of dangling lines by dangle tolerance
|
53 |
*
|
54 |
* Revision 1.1 2006/12/21 17:23:27 azabala
|
55 |
* *** empty log message ***
|
56 |
*
|
57 |
* Revision 1.2 2006/12/19 19:29:50 azabala
|
58 |
* *** empty log message ***
|
59 |
*
|
60 |
* Revision 1.1 2006/12/15 19:06:29 azabala
|
61 |
* scheleton of polygon build
|
62 |
*
|
63 |
*
|
64 |
*/
|
65 |
package com.iver.cit.gvsig.geoprocess.impl.topology.polygonbuild.fmap; |
66 |
|
67 |
import java.awt.Color; |
68 |
import java.io.File; |
69 |
import java.util.ArrayList; |
70 |
import java.util.Collection; |
71 |
import java.util.HashMap; |
72 |
import java.util.Iterator; |
73 |
import java.util.List; |
74 |
import java.util.Map; |
75 |
|
76 |
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException; |
77 |
import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
78 |
import com.hardcode.gdbms.driver.exceptions.SchemaEditionException; |
79 |
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException; |
80 |
import com.hardcode.gdbms.engine.values.Value; |
81 |
import com.hardcode.gdbms.engine.values.ValueFactory; |
82 |
import com.iver.andami.PluginServices; |
83 |
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException; |
84 |
import com.iver.cit.gvsig.exceptions.visitors.StartVisitorException; |
85 |
import com.iver.cit.gvsig.exceptions.visitors.StopVisitorException; |
86 |
import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException; |
87 |
import com.iver.cit.gvsig.exceptions.visitors.VisitorException; |
88 |
import com.iver.cit.gvsig.fmap.MapContext; |
89 |
import com.iver.cit.gvsig.fmap.core.DefaultFeature; |
90 |
import com.iver.cit.gvsig.fmap.core.FPoint2D; |
91 |
import com.iver.cit.gvsig.fmap.core.FShape; |
92 |
import com.iver.cit.gvsig.fmap.core.IGeometry; |
93 |
import com.iver.cit.gvsig.fmap.core.ShapeFactory; |
94 |
import com.iver.cit.gvsig.fmap.core.v02.FConstant; |
95 |
import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
96 |
import com.iver.cit.gvsig.fmap.core.v02.FSymbol; |
97 |
import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
98 |
import com.iver.cit.gvsig.fmap.drivers.FieldDescription; |
99 |
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition; |
100 |
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition; |
101 |
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition; |
102 |
import com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend; |
103 |
import com.iver.cit.gvsig.fmap.edition.IWriter; |
104 |
import com.iver.cit.gvsig.fmap.edition.ShpSchemaManager; |
105 |
import com.iver.cit.gvsig.fmap.edition.writers.shp.MultiShpWriter; |
106 |
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter; |
107 |
import com.iver.cit.gvsig.fmap.layers.FBitSet; |
108 |
import com.iver.cit.gvsig.fmap.layers.FLayer; |
109 |
import com.iver.cit.gvsig.fmap.layers.FLayers; |
110 |
import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
111 |
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial; |
112 |
import com.iver.cit.gvsig.fmap.rendering.LegendFactory; |
113 |
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend; |
114 |
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend; |
115 |
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess; |
116 |
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2; |
117 |
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException; |
118 |
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes; |
119 |
import com.iver.cit.gvsig.geoprocess.impl.topology.lineclean.fmap.LineCleanGeoprocess; |
120 |
import com.iver.cit.gvsig.geoprocess.impl.topology.lineclean.fmap.LineCleanVisitor; |
121 |
import com.iver.cit.gvsig.project.documents.view.gui.View; |
122 |
import com.iver.cit.gvsig.topology.NodeError; |
123 |
import com.iver.cit.gvsig.topology.TopologyBuilder; |
124 |
import com.iver.cit.gvsig.util.SnappingCoordinateMap; |
125 |
import com.iver.utiles.swing.threads.AbstractMonitorableTask; |
126 |
import com.iver.utiles.swing.threads.IMonitorableTask; |
127 |
import com.iver.utiles.swing.threads.IPipedTask; |
128 |
import com.sun.corba.se.connection.GetEndPointInfoAgainException; |
129 |
import com.vividsolutions.jts.geom.Coordinate; |
130 |
import com.vividsolutions.jts.geom.CoordinateArrays; |
131 |
import com.vividsolutions.jts.geom.Geometry; |
132 |
import com.vividsolutions.jts.geom.GeometryFactory; |
133 |
import com.vividsolutions.jts.geom.util.LinearComponentExtracter; |
134 |
import com.vividsolutions.jts.operation.polygonize.Polygonizer; |
135 |
import com.vividsolutions.jts.planargraph.NodeMap; |
136 |
|
137 |
public class PolygonBuildGeoprocess extends AbstractGeoprocess { |
138 |
|
139 |
private static final FSymbol symNodeError = new FSymbol(FShape.POINT, Color.RED); |
140 |
private static final FSymbol symDangle = new FSymbol(FShape.LINE, Color.RED); |
141 |
private static final FSymbol symCutEdge = new FSymbol(FShape.LINE, Color.BLUE); |
142 |
private static final FSymbol symInvalidRing = new FSymbol(FShape.LINE, Color.YELLOW); |
143 |
static{
|
144 |
symNodeError.setSize(10);
|
145 |
symNodeError.setStyle(FConstant.SYMBOL_STYLE_MARKER_SQUARE); |
146 |
symNodeError.setFill(null);
|
147 |
symNodeError.setOutlined(true);
|
148 |
symNodeError.setOutlineColor(Color.RED);
|
149 |
} |
150 |
/**
|
151 |
* Static counter to add like a suffix to the error's layer names
|
152 |
* */
|
153 |
private static int numOcurrences = 0; |
154 |
|
155 |
// USER PARAMS
|
156 |
private boolean onlyFirstLayerSelection = false; |
157 |
|
158 |
private boolean computeCleanBefore = false; |
159 |
|
160 |
private boolean applySnapTolerance = false; |
161 |
private double snapTolerance; |
162 |
|
163 |
private boolean applyDangleTolerance = false; |
164 |
private double dangleTolerance; |
165 |
|
166 |
private boolean addGroupOfLyrs = false; |
167 |
|
168 |
private GeometryFactory fact = new GeometryFactory(); |
169 |
|
170 |
/**
|
171 |
* Relates an IWriter with the symbol of the layer
|
172 |
* (for error layers)
|
173 |
* */
|
174 |
private HashMap writer2sym = new HashMap(); |
175 |
|
176 |
/**
|
177 |
* Processes features (writing them in a persistent data store)
|
178 |
*/
|
179 |
FeaturePersisterProcessor2 processor; |
180 |
|
181 |
/**
|
182 |
* It saves all temporal writers (to save error geometries)
|
183 |
* */
|
184 |
ArrayList tempWriters = new ArrayList(); |
185 |
|
186 |
/**
|
187 |
* Schema of the result layer
|
188 |
*/
|
189 |
ILayerDefinition resultLayerDefinition; |
190 |
|
191 |
|
192 |
public PolygonBuildGeoprocess(FLyrVect inputLayer) {
|
193 |
this.firstLayer = inputLayer;
|
194 |
} |
195 |
|
196 |
public void setParameters(Map params) throws GeoprocessException { |
197 |
Boolean firstLayerSelection = (Boolean) params |
198 |
.get("firstlayerselection");
|
199 |
if (firstLayerSelection != null) |
200 |
this.onlyFirstLayerSelection = firstLayerSelection.booleanValue();
|
201 |
|
202 |
Boolean applySnap = (Boolean) params.get("applysnaptol"); |
203 |
if (applySnap != null) |
204 |
this.applySnapTolerance = applySnap.booleanValue();
|
205 |
Double snapTol = (Double) params.get("snaptolerance"); |
206 |
if (snapTol != null) |
207 |
this.snapTolerance = snapTol.doubleValue();
|
208 |
|
209 |
Boolean applyDange = (Boolean) params.get("applydangletol"); |
210 |
if (applyDange != null) |
211 |
this.applyDangleTolerance = applyDange.booleanValue();
|
212 |
|
213 |
Double dangleTol = (Double) params.get("dangletolerance"); |
214 |
if (dangleTol != null) |
215 |
this.dangleTolerance = dangleTol.doubleValue();
|
216 |
|
217 |
Boolean cleanBefore = (Boolean) params.get("computeclean"); |
218 |
if (cleanBefore != null) |
219 |
this.computeCleanBefore = cleanBefore.booleanValue();
|
220 |
|
221 |
Boolean groupOfLyrs = (Boolean) params.get("addgroupoflyrs"); |
222 |
if (groupOfLyrs != null) |
223 |
this.addGroupOfLyrs = groupOfLyrs.booleanValue();
|
224 |
|
225 |
} |
226 |
|
227 |
public void checkPreconditions() throws GeoprocessException { |
228 |
if (firstLayer == null) |
229 |
throw new GeoprocessException( |
230 |
"POLIGON BUILD: capa de entrada a null");
|
231 |
if (this.writer == null || this.schemaManager == null) { |
232 |
throw new GeoprocessException( |
233 |
"Operacion de BUILD de pol?gonos sin especificar capa de resultados");
|
234 |
} |
235 |
try {
|
236 |
if (firstLayer.getSource().getShapeCount() == 0) { |
237 |
throw new GeoprocessException("Capa de entrada vacia"); |
238 |
} |
239 |
} catch (ReadDriverException e) {
|
240 |
throw new GeoprocessException( |
241 |
"Error al verificar si la capa est? vac?a");
|
242 |
} |
243 |
} |
244 |
|
245 |
// TODO Move this stuff to AbstractGeoprocess
|
246 |
public void process() throws GeoprocessException { |
247 |
try {
|
248 |
createTask().run(); |
249 |
} catch (Exception e) { |
250 |
throw new GeoprocessException("Error al ejecutar el geoproceso"); |
251 |
} |
252 |
} |
253 |
|
254 |
/**
|
255 |
*
|
256 |
* Creates the schema (ILayerDefinition) of the result layer which will have
|
257 |
* all the polygons resulting from the BUILD
|
258 |
*/
|
259 |
public ILayerDefinition createLayerDefinition() {
|
260 |
if (resultLayerDefinition == null) { |
261 |
resultLayerDefinition = getLayerDefinition(); |
262 |
} |
263 |
return resultLayerDefinition;
|
264 |
} |
265 |
|
266 |
/**
|
267 |
* Utility method to create schemas for all kind of layers this
|
268 |
* geoprocess could create (polygons, and error layers -dangles, etc-)
|
269 |
*
|
270 |
* */
|
271 |
private ILayerDefinition getLayerDefinition(){
|
272 |
SHPLayerDefinition definition = new SHPLayerDefinition();
|
273 |
definition.setShapeType(XTypes.POLYGON); |
274 |
FieldDescription[] fields = new FieldDescription[1]; |
275 |
fields[0] = new FieldDescription(); |
276 |
fields[0].setFieldLength(10); |
277 |
fields[0].setFieldName("FID"); |
278 |
fields[0].setFieldType(XTypes.BIGINT);
|
279 |
definition.setFieldsDesc(fields); |
280 |
return definition;
|
281 |
} |
282 |
|
283 |
public IMonitorableTask createTask() {
|
284 |
return new PolygonBuildTask(); |
285 |
} |
286 |
|
287 |
|
288 |
class PolygonBuildTask extends AbstractMonitorableTask { |
289 |
|
290 |
PolygonBuildTask() { |
291 |
setInitialStep(0);
|
292 |
int additionalSteps = 2; |
293 |
try {
|
294 |
if (onlyFirstLayerSelection) {
|
295 |
int numSelected = firstLayer.getRecordset().getSelection()
|
296 |
.cardinality(); |
297 |
setFinalStep(numSelected + additionalSteps); |
298 |
} else {
|
299 |
int numShapes = firstLayer.getSource().getShapeCount();
|
300 |
setFinalStep(numShapes + additionalSteps); |
301 |
}// else
|
302 |
} catch (ReadDriverException e) {
|
303 |
// TODO Auto-generated catch block
|
304 |
e.printStackTrace(); |
305 |
} |
306 |
setDeterminatedProcess(true);
|
307 |
setStatusMessage(PluginServices.getText(this,
|
308 |
"PolygonBuild._Progress_Message"));
|
309 |
|
310 |
} |
311 |
|
312 |
/**
|
313 |
* Verifies cancelation events, and return a boolean flag if processes
|
314 |
* must be stopped for this cancelations events.
|
315 |
*
|
316 |
* @param cancel
|
317 |
* @param va
|
318 |
* @param visitor
|
319 |
* @return
|
320 |
* @throws DriverIOException
|
321 |
*/
|
322 |
|
323 |
// TODO Move all this stuff and remove
|
324 |
boolean verifyCancelation(ReadableVectorial va) {
|
325 |
if (isCanceled()) {
|
326 |
try {
|
327 |
va.stop(); |
328 |
} finally {
|
329 |
return true; |
330 |
} |
331 |
} |
332 |
return false; |
333 |
} |
334 |
|
335 |
/**
|
336 |
* Processes the record "record" of the given vectorial data source
|
337 |
* (ReadableVectorial) to extract linear components with "lineFilter".
|
338 |
* (Previous step necessary to polygonize a linear layer).
|
339 |
*
|
340 |
* If user has choosen add to the toc a group of layers (with
|
341 |
* topological errors, pseudonodes, dangles, etc) this method computes
|
342 |
* pseudonodes also.
|
343 |
* @throws StopWriterVisitorException
|
344 |
*/
|
345 |
void process(ReadableVectorial va,
|
346 |
FeaturePersisterProcessor2 processor, |
347 |
LinearComponentExtracter lineFilter, |
348 |
NodeMap nodeMap, |
349 |
int record) throws ReadDriverException, StopVisitorException { |
350 |
|
351 |
if (verifyCancelation(va)) {
|
352 |
processor.finish(); |
353 |
return;
|
354 |
} |
355 |
reportStep(); |
356 |
IGeometry g; |
357 |
try {
|
358 |
g = va.getShape(record); |
359 |
} catch (ExpansionFileReadException e) {
|
360 |
throw new ReadDriverException(va.getDriver().getName(),e); |
361 |
} |
362 |
if(g == null) |
363 |
return;
|
364 |
Geometry jtsGeom = g.toJTSGeometry(); |
365 |
jtsGeom.apply(lineFilter); |
366 |
|
367 |
// In parallel to the line filtering, if nodeMap != null we
|
368 |
// look for pseudonodes
|
369 |
if(nodeMap != null){ |
370 |
Coordinate[] coords = jtsGeom.getCoordinates();
|
371 |
if (jtsGeom.isEmpty())
|
372 |
return;
|
373 |
Coordinate[] linePts = CoordinateArrays.
|
374 |
removeRepeatedPoints(coords); |
375 |
Coordinate startPt = linePts[0];
|
376 |
Coordinate endPt = linePts[linePts.length - 1];
|
377 |
|
378 |
NodeError nStart = (NodeError) nodeMap.find(startPt); |
379 |
NodeError nEnd = (NodeError) nodeMap.find(endPt); |
380 |
if (nStart == null) |
381 |
{ |
382 |
nStart = new NodeError(startPt);
|
383 |
nodeMap.add(nStart); |
384 |
} |
385 |
else
|
386 |
nStart.setOccurrences(nStart.getOccurrences()+1);
|
387 |
if (nEnd == null) |
388 |
{ |
389 |
nEnd = new NodeError(endPt);
|
390 |
nodeMap.add(nEnd); |
391 |
} |
392 |
else
|
393 |
nEnd.setOccurrences(nEnd.getOccurrences()+1);
|
394 |
}// if nodeMap
|
395 |
} |
396 |
|
397 |
|
398 |
|
399 |
public void run() throws Exception { |
400 |
processor = new FeaturePersisterProcessor2(writer);
|
401 |
Polygonizer polygonizer = new Polygonizer();
|
402 |
try {
|
403 |
processor.start(); |
404 |
ReadableVectorial va = firstLayer.getSource(); |
405 |
va.start(); |
406 |
|
407 |
List linesList = new ArrayList(); |
408 |
LinearComponentExtracter lineFilter = new LinearComponentExtracter(
|
409 |
linesList); |
410 |
|
411 |
NodeMap nodeMap = null;
|
412 |
if(addGroupOfLyrs)
|
413 |
nodeMap = new NodeMap();
|
414 |
if (onlyFirstLayerSelection) {
|
415 |
FBitSet selection = firstLayer.getRecordset() |
416 |
.getSelection(); |
417 |
for (int i = selection.nextSetBit(0); i >= 0; i = selection |
418 |
.nextSetBit(i + 1)) {
|
419 |
process(va, processor, lineFilter, nodeMap, i); |
420 |
} |
421 |
} else {
|
422 |
for (int i = 0; i < va.getShapeCount(); i++) {// for each |
423 |
process(va, processor, lineFilter, nodeMap, i); |
424 |
}// for
|
425 |
}// if selection
|
426 |
va.stop(); |
427 |
|
428 |
// here lineList has all the linear elements
|
429 |
if (computeCleanBefore) {
|
430 |
linesList = cleanLines(linesList); |
431 |
} |
432 |
for (Iterator i = linesList.iterator(); i.hasNext(); ) { |
433 |
Geometry g = (Geometry) i.next(); |
434 |
polygonizer.add(g); |
435 |
} |
436 |
|
437 |
reportStep(); |
438 |
|
439 |
// First we save polygons from build
|
440 |
List polygons = (List) polygonizer.getPolygons(); |
441 |
for(int i = 0; i < polygons.size(); i++){ |
442 |
Geometry geom = (Geometry) polygons.get(i); |
443 |
Value[] values = new Value[1]; |
444 |
values[0] = ValueFactory.createValue(i);
|
445 |
IGeometry igeom = FConverter.jts_to_igeometry(geom); |
446 |
DefaultFeature feature = new
|
447 |
DefaultFeature(igeom, values, (i+""));
|
448 |
processor.processFeature(feature); |
449 |
} |
450 |
processor.finish(); |
451 |
|
452 |
reportStep(); |
453 |
if(addGroupOfLyrs){
|
454 |
Collection cutEdgesLines = (List) polygonizer.getCutEdges(); |
455 |
Collection danglingLines = polygonizer.getDangles();
|
456 |
Collection invalidRingLines = (List) polygonizer.getInvalidRingLines(); |
457 |
List nodeErrors = new ArrayList(); |
458 |
// Obtain pseudonodes
|
459 |
// (we look for nodes of valency 1)
|
460 |
Iterator it = nodeMap.iterator();
|
461 |
while (it.hasNext()){
|
462 |
NodeError node = (NodeError) it.next(); |
463 |
if (node.getOccurrences() == 1){ |
464 |
FPoint2D p = FConverter.coordinate2FPoint2D( |
465 |
node.getCoordinate()); |
466 |
IGeometry gAux = ShapeFactory.createPoint2D(p); |
467 |
nodeErrors.add(gAux.toJTSGeometry()); |
468 |
}// if
|
469 |
}// while
|
470 |
|
471 |
if(cutEdgesLines != null){ |
472 |
if(cutEdgesLines.size() > 0) |
473 |
writeCutEdgeLines(cutEdgesLines); |
474 |
} |
475 |
|
476 |
if(danglingLines != null){ |
477 |
//check to filter dangling lines by length
|
478 |
if(applyDangleTolerance){
|
479 |
ArrayList filteredDangles = new ArrayList(); |
480 |
Iterator iterator = danglingLines.iterator();
|
481 |
while(iterator.hasNext()){
|
482 |
Geometry geom = (Geometry) iterator.next(); |
483 |
if(geom.getLength() >= dangleTolerance)
|
484 |
filteredDangles.add(geom); |
485 |
}//while
|
486 |
danglingLines = filteredDangles; |
487 |
} |
488 |
if(danglingLines.size() > 0) |
489 |
writeDanglingLines(danglingLines); |
490 |
} |
491 |
|
492 |
if(invalidRingLines != null){ |
493 |
if(invalidRingLines.size() > 0) |
494 |
writeInvalidRingLines(invalidRingLines); |
495 |
} |
496 |
|
497 |
if(nodeErrors != null){ |
498 |
if(nodeErrors.size() > 0) |
499 |
writeNodeErrors(nodeErrors); |
500 |
} |
501 |
}// if addGroupOfLayers
|
502 |
} catch (ReadDriverException e) {
|
503 |
e.printStackTrace(); |
504 |
} |
505 |
} |
506 |
|
507 |
public String getNote() { |
508 |
String buildText = PluginServices.getText(this, |
509 |
"Generando_topologia_de_poligonos");
|
510 |
String of = PluginServices.getText(this, "de"); |
511 |
return buildText + " " + getCurrentStep() + " " + of + " " |
512 |
+ getFinishStep(); |
513 |
} |
514 |
|
515 |
public void cancel() { |
516 |
setCanceled(true);
|
517 |
PolygonBuildGeoprocess.this.cancel(); |
518 |
} |
519 |
|
520 |
}// PolygonBuildTask
|
521 |
|
522 |
/**
|
523 |
* This method apply a topology clean to the list of lines.
|
524 |
*
|
525 |
* This clean is made in memory (against LineCleanGeoprocess, that makes
|
526 |
* this clean without memory consumption).
|
527 |
*
|
528 |
*/
|
529 |
// TODO Move this method to a JTS Utility class
|
530 |
List cleanLines(List lines) { |
531 |
Geometry linesGeom = fact.createMultiLineString(GeometryFactory |
532 |
.toLineStringArray(lines)); |
533 |
Geometry empty = fact.createMultiLineString(null);
|
534 |
Geometry noded = linesGeom.union(empty); |
535 |
List nodedList = new ArrayList(); |
536 |
nodedList.add(noded); |
537 |
return nodedList;
|
538 |
} |
539 |
|
540 |
|
541 |
void writeGeometriesInMemory(Collection geometries, int geometryType, FSymbol symbol, String fileName) throws InitializeWriterException, SchemaEditionException, VisitorException { |
542 |
|
543 |
ShpWriter writer = new ShpWriter();
|
544 |
File newFile = new File(fileName); |
545 |
writer.setFile(newFile); |
546 |
SHPLayerDefinition schema = (SHPLayerDefinition) getLayerDefinition(); |
547 |
schema.setShapeType(geometryType); |
548 |
writer.initialize(schema); |
549 |
schema.setFile(newFile); |
550 |
ShpSchemaManager schemaManager = |
551 |
new ShpSchemaManager(newFile.getAbsolutePath());
|
552 |
schemaManager.createSchema(schema); |
553 |
FeaturePersisterProcessor2 tempProcessor = new
|
554 |
FeaturePersisterProcessor2(writer); |
555 |
tempProcessor = new FeaturePersisterProcessor2(writer);
|
556 |
tempProcessor.start(); |
557 |
Iterator it = geometries.iterator();
|
558 |
int i = 0; |
559 |
while(it.hasNext()){
|
560 |
Geometry geom = (Geometry) it.next(); |
561 |
Value[] values = new Value[1]; |
562 |
values[0] = ValueFactory.createValue(i);
|
563 |
IGeometry igeom = FConverter.jts_to_igeometry(geom); |
564 |
DefaultFeature feature = new
|
565 |
DefaultFeature(igeom, values, (i+""));
|
566 |
tempProcessor.processFeature(feature); |
567 |
i++; |
568 |
} |
569 |
tempProcessor.finish(); |
570 |
//We save the information to recover these layers after
|
571 |
//(to add them to the toc)
|
572 |
tempWriters.add(writer); |
573 |
|
574 |
//saves the symbol specified for this writer, to use it
|
575 |
//when we will add the layer derived of the writer to the TOC
|
576 |
writer2sym.put(writer, symbol); |
577 |
} |
578 |
|
579 |
|
580 |
|
581 |
void writeCutEdgeLines(Collection cutEdgeLines) throws InitializeWriterException, SchemaEditionException, VisitorException{ |
582 |
String temp = System.getProperty("java.io.tmpdir") + |
583 |
"/cutEdgeLines" +
|
584 |
(numOcurrences++)+ |
585 |
".shp";
|
586 |
writeGeometriesInMemory(cutEdgeLines, XTypes.LINE, symCutEdge, temp); |
587 |
} |
588 |
|
589 |
|
590 |
void writeDanglingLines(Collection danglingLines) throws InitializeWriterException, SchemaEditionException, VisitorException{ |
591 |
String temp = System.getProperty("java.io.tmpdir") + |
592 |
"/danglingLines" +
|
593 |
(numOcurrences++)+ |
594 |
".shp";
|
595 |
writeGeometriesInMemory(danglingLines, XTypes.LINE, symDangle, temp); |
596 |
} |
597 |
|
598 |
void writeInvalidRingLines(Collection invalidRingLines) throws InitializeWriterException, SchemaEditionException, VisitorException{ |
599 |
String temp = System.getProperty("java.io.tmpdir") + |
600 |
"/invalidRingLines" +
|
601 |
(numOcurrences++)+ |
602 |
".shp";
|
603 |
writeGeometriesInMemory(invalidRingLines, XTypes.LINE,symInvalidRing, temp); |
604 |
} |
605 |
|
606 |
void writeNodeErrors(Collection nodeErrors) throws InitializeWriterException, SchemaEditionException, VisitorException{ |
607 |
String temp = System.getProperty("java.io.tmpdir") + |
608 |
"/pseudonodes" +
|
609 |
(numOcurrences++)+ |
610 |
".shp";
|
611 |
writeGeometriesInMemory(nodeErrors, XTypes.POINT,symNodeError, temp); |
612 |
} |
613 |
|
614 |
|
615 |
public FLayer getResult() throws GeoprocessException { |
616 |
if(! addGroupOfLyrs){
|
617 |
// user choose in GUI not to load errors in TOC
|
618 |
return super.getResult(); |
619 |
}else{
|
620 |
if(tempWriters.size() == 0) |
621 |
return super.getResult(); |
622 |
IWriter[] writers = new IWriter[tempWriters.size()]; |
623 |
tempWriters.toArray(writers); |
624 |
|
625 |
MapContext map = ((View)PluginServices.getMDIManager().
|
626 |
getActiveWindow()).getModel().getMapContext(); |
627 |
FLayers solution = new FLayers(map, map.getLayers());
|
628 |
solution.setName("Build");
|
629 |
solution.addLayer(super.getResult());
|
630 |
for(int i = 0; i < writers.length; i++){ |
631 |
FLyrVect layer = (FLyrVect) createLayerFrom(writers[i]); |
632 |
FSymbol symbol = (FSymbol) writer2sym.get(writers[i]); |
633 |
try {
|
634 |
layer.setLegend(new SingleSymbolLegend(symbol));
|
635 |
} catch (Exception e) { |
636 |
throw new GeoprocessException("Error al crear la leyenda de una de las capas resultado", e); |
637 |
} |
638 |
solution.addLayer(layer); |
639 |
} |
640 |
return solution;
|
641 |
}//else
|
642 |
} |
643 |
} |