Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.editing.app / org.gvsig.editing.app.mainplugin / src / main / java / org / gvsig / editing / gui / cad / tools / ExploitCADTool.java @ 40557

History | View | Annotate | Download (21.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.editing.gui.cad.tools;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Component;
28
import java.awt.Font;
29
import java.awt.GridBagConstraints;
30
import java.awt.GridBagLayout;
31
import java.awt.Insets;
32
import java.awt.event.InputEvent;
33
import java.awt.geom.PathIterator;
34
import java.awt.geom.Point2D;
35

    
36
import javax.swing.JLabel;
37
import javax.swing.JOptionPane;
38
import javax.swing.JPanel;
39

    
40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
42

    
43
import org.gvsig.andami.PluginServices;
44
import org.gvsig.andami.messages.NotificationManager;
45
import org.gvsig.app.ApplicationLocator;
46
import org.gvsig.editing.CADExtension;
47
import org.gvsig.editing.gui.cad.DefaultCADTool;
48
import org.gvsig.editing.gui.cad.exception.CommandException;
49
import org.gvsig.editing.gui.cad.tools.smc.ExploitCADToolContext;
50
import org.gvsig.editing.layers.VectorialLayerEdited;
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.exception.ReadException;
53
import org.gvsig.fmap.dal.feature.EditableFeature;
54
import org.gvsig.fmap.dal.feature.Feature;
55
import org.gvsig.fmap.dal.feature.FeatureSelection;
56
import org.gvsig.fmap.dal.feature.FeatureSet;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58
import org.gvsig.fmap.dal.feature.FeatureType;
59
import org.gvsig.fmap.geom.Geometry;
60
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
61
import org.gvsig.fmap.geom.primitive.Curve;
62
import org.gvsig.fmap.geom.primitive.GeneralPathX;
63
import org.gvsig.fmap.geom.primitive.Surface;
64
import org.gvsig.fmap.geom.type.GeometryType;
65
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
66
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
67
import org.gvsig.i18n.Messages;
68
import org.gvsig.tools.dispose.DisposableIterator;
69

    
70
//import com.vividsolutions.jts.geom.GeometryCollection;
71

    
72
/**
73
 * Elimina la geometr?a compuesta y a?ade todas la geometr?as simples que la
74
 * componen, implementado para polil?neas y pol?gonos.
75
 * 
76
 * @author Vicente Caballero Navarro
77
 */
78
public class ExploitCADTool extends DefaultCADTool {
79
    
80
    private static Logger logger = LoggerFactory.getLogger(ExploitCADTool.class);
81

    
82
    protected ExploitCADToolContext _fsm;
83
    
84

    
85
    /**
86
     * M?todo de inicio, para poner el c?digo de todo lo que se requiera de una
87
     * carga previa a la utilizaci?n de la herramienta.
88
     */
89
    public void init() {
90
        _fsm = new ExploitCADToolContext(this);
91
    }
92

    
93
    /*
94
     * (non-Javadoc)
95
     * 
96
     * @see
97
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
98
     * .layers.FBitSet, double, double)
99
     */
100
    public void transition(double x, double y, InputEvent event) {
101
        _fsm.addPoint(x, y, event);
102
    }
103

    
104
    /*
105
     * (non-Javadoc)
106
     * 
107
     * @see
108
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
109
     * .layers.FBitSet, double)
110
     */
111
    public void transition(double d) {
112
        _fsm.addValue(d);
113
    }
114

    
115
    /*
116
     * (non-Javadoc)
117
     * 
118
     * @see
119
     * com.iver.cit.gvsig.gui.cad.CADTool#transition(com.iver.cit.gvsig.fmap
120
     * .layers.FBitSet, java.lang.String)
121
     */
122
    public void transition(String s) throws CommandException {
123
        if (!super.changeCommand(s)) {
124
            _fsm.addOption(s);
125
        }
126
    }
127

    
128
    /**
129
     * DOCUMENT ME!
130
     */
131
    public void selection() {
132
        FeatureSet selection = null;
133
        try {
134
            selection = (FeatureSet) getVLE().getFeatureStore().getSelection();
135

    
136
            if (selection.getSize() == 0
137
                && !SelectionCADTool.isInstance(CADExtension.getCADTool(), true)) {
138
                
139
                CADExtension.setCADTool("_selection", false);
140
                ((SelectionCADTool) CADExtension.getCADTool())
141
                    .setNextTool("_exploit");
142
            }
143
        } catch (ReadException e) {
144
            // TODO Auto-generated catch block
145
            e.printStackTrace();
146
        } catch (DataException e) {
147
            // TODO Auto-generated catch block
148
            e.printStackTrace();
149
        }
150
    }
151

    
152
    /**
153
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
154
     * editableFeatureSource que ya estar? creado.
155
     * 
156
     * @param x
157
     *            par?metro x del punto que se pase en esta transici?n.
158
     * @param y
159
     *            par?metro y del punto que se pase en esta transici?n.
160
     */
161
    public void addPoint(double x, double y, InputEvent event) {
162
    }
163

    
164
    /**
165
     * M?todo para dibujar la lo necesario para el estado en el que nos
166
     * encontremos.
167
     * 
168
     * @param g
169
     *            Graphics sobre el que dibujar.
170
     * @param x
171
     *            par?metro x del punto que se pase para dibujar.
172
     * @param y
173
     *            par?metro x del punto que se pase para dibujar.
174
     */
175
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
176
    }
177

    
178
    public void exploit() {
179
        
180
        VectorialLayerEdited vle = getVLE();
181
        DisposableIterator iterator = null;
182
        FeatureStore featureStore = null;
183
        FeatureType fety = null;
184

    
185
        try {
186
            featureStore = vle.getFeatureStore();
187
            fety = featureStore.getDefaultFeatureType();
188
        } catch (Exception ex) {
189
            NotificationManager.addError(ex.getMessage(), ex);
190
            return;
191
        }
192

    
193
        
194
        GeometryType gety = fety.getDefaultGeometryAttribute().getGeomType();
195
        
196
        /*
197
         * If we find a geometry which will violate
198
         * geometry type retriction after being exploded,
199
         * then we will ask user what to do (we'll ask once
200
         * for all cases)
201
         */
202
        boolean decisionHasBeenTaken = false;
203
        boolean differentTypesAllowed = false;
204

    
205
        if (gety.getType() == Geometry.TYPES.GEOMETRY) {
206
            /*
207
             * Multi allowed, so we don't need to ask
208
             */
209
            decisionHasBeenTaken = true;
210
            differentTypesAllowed = true;
211
        }
212
        // ==============================
213

    
214
        try {
215
            iterator =
216
                ((FeatureSelection) featureStore.getSelection()).iterator();
217
            FeatureSelection newSelection =
218
                featureStore.createFeatureSelection();
219
            // ArrayList selectedRowAux = new ArrayList();
220
            featureStore.beginEditingGroup(getName());
221

    
222
            while (iterator.hasNext()) {
223
                Feature feature = (Feature) iterator.next();
224
                Geometry geom = (feature.getDefaultGeometry()).cloneGeometry();
225
                featureStore.delete(feature);
226
                if (geom instanceof MultiPrimitive) {
227
                    exploitGeometryCollection(feature, newSelection);
228
                } else {
229
                    
230
                    if (geom instanceof Curve) {
231
                        /*
232
                         * Splitting line gives lines, no problem
233
                         */
234
                        exploitLine(feature, newSelection);
235
                    } else {
236
                        if (geom instanceof Surface) {
237
                            
238
                            if (decisionHasBeenTaken) {
239
                                
240
                                /*
241
                                 * We have already decided what to do
242
                                 * in these cases
243
                                 */
244
                                exploitPolygon(
245
                                    feature,
246
                                    newSelection,
247
                                    differentTypesAllowed);
248
                                
249
                            } else {
250
                                
251
                                differentTypesAllowed = askUserAllowOther();
252
                                decisionHasBeenTaken = true;
253
                                /*
254
                                 * User has taken a decision. The same
255
                                 * decision applies for other geometries
256
                                 * in the current explode process
257
                                 */
258
                                exploitPolygon(
259
                                    feature,
260
                                    newSelection,
261
                                    differentTypesAllowed);
262
                            }
263
                        }
264
                    }
265
                }
266
            }
267
            // clearSelection();
268
            featureStore.setSelection(newSelection);
269
            featureStore.endEditingGroup();
270
        } catch (Exception e) {
271
            NotificationManager.addError(e.getMessage(), e);
272
        } finally {
273
            if (iterator != null) {
274
                iterator.dispose();
275
            }
276
        }
277

    
278
    }
279

    
280
    private void exploitGeometryCollection(Feature feature,
281
        FeatureSelection selectedRowAux) throws ReadException, DataException {
282
        Geometry geom = (feature.getDefaultGeometry()).cloneGeometry();
283
        MultiPrimitive gc = (MultiPrimitive) geom;
284
        int numGeoms = gc.getPrimitivesNumber();
285
        Feature f = null;
286

    
287
        for (int i = 0; i < numGeoms; i++) {
288
            Geometry primitiveGeom = gc.getPrimitiveAt(i);
289
            f = insertGeometry(primitiveGeom, feature);
290
            selectedRowAux.select(f);
291
        }
292
        refresh();
293
    }
294

    
295
    private void exploitLine(Feature feature,
296
        FeatureSelection selectedRowAux) {
297
        
298
        GeneralPathX newGp1 = new GeneralPathX();
299
        // DefaultFeature df = (DefaultFeature) dre.getLinkedRow()
300
        // .cloneRow();
301
        // Point2D firstPoint=null;
302
        // Point2D lastPoint=null;
303
        // Object[] attributes=new Object[feature.size()];
304
        // for (int j = 0; j < feature.size(); j++) {
305
        // attributes[j]=feature.get(j);
306
        // }
307
        FeatureStore featureStore;
308
        // try {
309
        try {
310
            featureStore = getVLE().getFeatureStore();
311

    
312
            // EditableFeature
313
            // eFeature=featureStore.createNewFeature(feature.getType(),
314
            // feature);
315
            PathIterator theIterator =
316
                (feature.getDefaultGeometry()).getPathIterator(null,
317
                    geomManager.getFlatness());
318
            double[] theData = new double[6];
319
            int theType;
320
            int numParts = 0;
321
            Point2D initialPoint = null;
322
            Feature f = null;
323
            
324
            while (!theIterator.isDone()) {
325
                theType = theIterator.currentSegment(theData);
326
                switch (theType) {
327

    
328
                case PathIterator.SEG_MOVETO:
329
                    numParts++;
330
                    newGp1 = new GeneralPathX();
331
                    // firstPoint=new Point2D.Double(theData[0], theData[1]);
332
                    initialPoint = new Point2D.Double(theData[0], theData[1]);
333
                    newGp1.moveTo(theData[0], theData[1]);
334
                    // lastPoint=new Point2D.Double(theData[0], theData[1]);
335
                    break;
336

    
337
                case PathIterator.SEG_LINETO:
338
                    newGp1.lineTo(theData[0], theData[1]);
339
                    Geometry geomLine = createCurve(newGp1);
340
                    // DefaultFeature dfLine = (DefaultFeature) df.cloneRow();
341
                    // dfLine.setGeometry(geomLine);
342
                    // EditableFeature
343
                    // eFeature=featureStore.createNewFeature(feature.getType(),
344
                    // feature);
345
                    // eFeature.setGeometry(featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName(),geomLine);
346
                    f = insertGeometry(geomLine, feature);
347
                    // featureStore.insert(eFeature);
348
                    selectedRowAux.select(f);
349
                    newGp1 = new GeneralPathX();
350
                    newGp1.moveTo(theData[0], theData[1]);
351
                    // lastPoint=new Point2D.Double(theData[0], theData[1]);
352
                    break;
353
                case PathIterator.SEG_CLOSE:
354
                    if (initialPoint != null) {
355
                        newGp1.lineTo(initialPoint.getX(), initialPoint.getY());
356
                        geomLine = createCurve(newGp1);
357

    
358
                        f = insertGeometry(geomLine, feature);
359
                        selectedRowAux.select(f);
360

    
361
                        newGp1 = new GeneralPathX();
362
                        newGp1.moveTo(initialPoint.getX(), initialPoint.getY());
363
                    }
364
                    break;
365
                } // end switch
366

    
367
                theIterator.next();
368
            } // end while loop
369
        } catch (ReadException e) {
370
            // TODO Auto-generated catch block
371
            e.printStackTrace();
372
        } catch (DataException e) {
373
            // TODO Auto-generated catch block
374
            e.printStackTrace();
375
        }
376
        refresh();
377
    }
378

    
379
    private void exploitPolygon(
380
        Feature deleted_feature,
381
        FeatureSelection selectedRowAux,
382
        boolean allows_other) {
383
        
384
        GeneralPathX newGp1 = null;
385
        // Object[] attributes=new Object[feature.size()];
386
        // for (int j = 0; j < feature.size(); j++) {
387
        // attributes[j]=feature.get(j);
388
        // }
389

    
390
        FeatureStore featureStore;
391
        Feature added_feat = null;
392
        try {
393
            featureStore = getVLE().getFeatureStore();
394

    
395
            PathIterator theIterator =
396
                (deleted_feature.getDefaultGeometry()).getPathIterator(null,
397
                    geomManager.getFlatness());
398
            double[] theData = new double[6];
399
            int theType;
400
            int numParts = 0;
401
            Point2D initialPoint = null;
402
            while (!theIterator.isDone()) {
403
                theType = theIterator.currentSegment(theData);
404
                switch (theType) {
405

    
406
                case PathIterator.SEG_MOVETO:
407
                    numParts++;
408
                    if (newGp1 != null) {
409
                        Geometry new_part = null;
410

    
411
                        if (allows_other) {
412
                            new_part = createCurve(newGp1);
413
                            added_feat = cloneFeatureWithGeometry(new_part, deleted_feature);
414
                            /*
415
                             * added_feat not added
416
                             * Now explode resulting line
417
                             */
418
                            exploitLine(added_feat, selectedRowAux);
419
                        } else {
420
                            new_part = createSurface(newGp1);
421
                            added_feat = insertGeometry(new_part, deleted_feature);
422
                            selectedRowAux.select(added_feat);
423
                        }
424

    
425
                    }
426
                    newGp1 = new GeneralPathX();
427
                    initialPoint = new Point2D.Double(theData[0], theData[1]);
428
                    newGp1.moveTo(theData[0], theData[1]);
429
                    break;
430

    
431
                case PathIterator.SEG_LINETO:
432
                    newGp1.lineTo(theData[0], theData[1]);
433
                    // newGp1 = new GeneralPathX();
434
                    // newGp1.moveTo(theData[0], theData[1]);
435
                    break;
436

    
437
                case PathIterator.SEG_QUADTO:
438
                    newGp1.quadTo(theData[0], theData[1], theData[2],
439
                        theData[3]);
440
                    // newGp1 = new GeneralPathX();
441
                    // newGp1.moveTo(theData[0], theData[1]);
442
                    break;
443
                case PathIterator.SEG_CUBICTO:
444
                    newGp1.curveTo(theData[0], theData[1], theData[2],
445
                        theData[3], theData[4], theData[5]);
446
                    // newGp1 = new GeneralPathX();
447
                    // newGp1.moveTo(theData[0], theData[1]);
448
                    break;
449
                case PathIterator.SEG_CLOSE:
450
                    if (initialPoint != null) {
451
                        newGp1.lineTo(initialPoint.getX(), initialPoint.getY());
452
                    }
453
                    // System.out.println("aqu?");
454
                    // if (isFirstPart)
455
                    // newGp1.closePath();
456
                    // else
457
                    // newGp2.closePath();
458
                    break;
459
                } // end switch
460

    
461
                theIterator.next();
462
            } // end while loop
463
            if (newGp1 != null) {
464
                
465
                Geometry new_part = null;
466
                
467
                if (allows_other) {
468
                    new_part = createCurve(newGp1);
469
                    added_feat = cloneFeatureWithGeometry(new_part, deleted_feature);
470
                    /*
471
                     * added_feat not added
472
                     * Now explode resulting line
473
                     */
474
                    exploitLine(added_feat, selectedRowAux);
475
                } else {
476
                    new_part = createSurface(newGp1);
477
                    added_feat = insertGeometry(new_part, deleted_feature);
478
                    selectedRowAux.select(added_feat);
479
                }
480
                
481
            }
482
        } catch (Throwable e) {
483
            logger.info("While doing exploit of polygon.", e);
484
            ApplicationLocator.getManager().message(
485
                "_Unable_to_exploit_polygon", JOptionPane.ERROR_MESSAGE);
486
            // TODO Auto-generated catch block
487
            // e.printStackTrace();
488
        }
489
        refresh();
490
    }
491

    
492
    /**
493
     * Add a diferent option.
494
     * 
495
     * @param s
496
     *            Diferent option.
497
     */
498
    public void addOption(String s) {
499
    }
500

    
501
    /*
502
     * (non-Javadoc)
503
     * 
504
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
505
     */
506
    public void addValue(double d) {
507

    
508
    }
509

    
510
    public String getName() {
511
        return PluginServices.getText(this, "exploit_");
512
    }
513

    
514
    public String toString() {
515
        return "_exploit";
516
    }
517

    
518
    @Override
519
    protected int[] getSupportedGeometryTypes() {
520
        return new int[] {
521
            CURVE,
522
            MULTICURVE,
523
            SURFACE,
524
            MULTISURFACE };
525
    }
526
    
527
    /**
528
     * @return
529
     */
530
    private boolean askUserAllowOther() {
531
        
532
        int resp = 0;
533
        
534
        Object[] options = {
535
            Messages.getText("_Allow_lines"),
536
            Messages.getText("_Keep_as_polygons") };
537
        
538
        JPanel explanation_panel = getExplanationPanel();
539
        Component parent = ApplicationLocator.getManager().getRootComponent();
540
        
541
        resp = JOptionPane.showOptionDialog(
542
                    parent,
543
                    explanation_panel,
544
                    Messages.getText("exploit"),
545
                    JOptionPane.YES_NO_OPTION,
546
                    JOptionPane.QUESTION_MESSAGE, null, options,
547
                    options[1]);
548
        
549
        return (resp == JOptionPane.YES_OPTION);
550
    }
551
    
552
    
553
    private JPanel getExplanationPanel() {
554
        
555
        JPanel resp = new JPanel(new BorderLayout(10, 10));
556
        
557
        String msg = Messages.getText("_Polygons_will_exploded_in_polygon_only_layer_Decision_question");
558
        JLabel topLabel = new JLabel(msg);
559
        
560
        JPanel mainPanel = new JPanel(new GridBagLayout());
561
        GridBagConstraints cc = new GridBagConstraints();
562
        
563
        cc.gridx = 0;
564
        cc.gridy = 0;
565
        cc.anchor = GridBagConstraints.WEST;
566
        
567
        cc.insets = new Insets(3, 6, 3, 6);
568
        
569
        Font boldf = mainPanel.getFont().deriveFont(Font.BOLD);
570

    
571
        JLabel lbl = new JLabel(Messages.getText("_Allow_lines"));
572
        lbl.setFont(boldf);
573
        mainPanel.add(lbl, cc);
574
        cc.gridx = 1;
575
        mainPanel.add(new JLabel(Messages.getText("_Lines_will_exist_in_editing_mode_Must_remove_or_cancel")), cc);
576
        
577
        cc.gridx = 0;
578
        cc.gridy = 1;
579
        lbl = new JLabel(Messages.getText("_Keep_as_polygons"));
580
        lbl.setFont(boldf);
581
        mainPanel.add(lbl, cc);
582
        cc.gridx = 1;
583
        mainPanel.add(new JLabel(Messages.getText("_Multi_polygons_separated_Simple_polygons_kept")), cc);
584

    
585
        resp.add(mainPanel, BorderLayout.CENTER);
586
        resp.add(topLabel, BorderLayout.NORTH);
587
        return resp;
588
    }
589
    
590
    
591
    private Feature cloneFeatureWithGeometry(
592
        Geometry geometry, Feature feature) {
593
        
594
        VectorialLayerEdited vle = getVLE();
595

    
596
        try {
597
            FeatureStore featureStore =
598
                ((FLyrVect) vle.getLayer()).getFeatureStore();
599
            EditableFeature eFeature =
600
                featureStore.createNewFeature(
601
                    featureStore.getDefaultFeatureType(), feature);
602
            eFeature.setGeometry(featureStore.getDefaultFeatureType()
603
                .getDefaultGeometryAttributeName(), geometry);
604
            return eFeature;
605
        } catch (ReadException e) {
606
            NotificationManager.addError(e.getMessage(), e);
607
            return null;
608
        } catch (DataException e) {
609
            NotificationManager.addError(e.getMessage(), e);
610
            return null;
611
        }
612
    }
613

    
614
}