Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / gui / cad / tools / ExploitCADTool.java @ 39088

History | View | Annotate | Download (21.3 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22
package org.gvsig.editing.gui.cad.tools;
23

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

    
34
import javax.swing.JLabel;
35
import javax.swing.JOptionPane;
36
import javax.swing.JPanel;
37

    
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

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

    
66
//import com.vividsolutions.jts.geom.GeometryCollection;
67

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

    
78
    protected ExploitCADToolContext _fsm;
79
    
80

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

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

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

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

    
124
    /**
125
     * DOCUMENT ME!
126
     */
127
    public void selection() {
128
        FeatureSet selection = null;
129
        try {
130
            selection = (FeatureSet) getVLE().getFeatureStore().getSelection();
131

    
132
            if (selection.getSize() == 0
133
                && !CADExtension
134
                    .getCADTool()
135
                    .getClass()
136
                    .getName()
137
                    .equals("com.iver.cit.gvsig.gui.cad.tools.SelectionCADTool")) {
138
                CADExtension.setCADTool("_selection", false);
139
                ((SelectionCADTool) CADExtension.getCADTool())
140
                    .setNextTool("_exploit");
141
            }
142
        } catch (ReadException e) {
143
            // TODO Auto-generated catch block
144
            e.printStackTrace();
145
        } catch (DataException e) {
146
            // TODO Auto-generated catch block
147
            e.printStackTrace();
148
        }
149
    }
150

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

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

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

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

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

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

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

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

    
277
    }
278

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
507
    }
508

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

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

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

    
566
        JLabel lbl = new JLabel(Messages.getText("_Allow_lines"));
567
        lbl.setFont(boldf);
568
        mainPanel.add(lbl, cc);
569
        cc.gridx = 1;
570
        mainPanel.add(new JLabel(Messages.getText("_Lines_will_exist_in_editing_mode_Must_remove_or_cancel")), cc);
571
        
572
        cc.gridx = 0;
573
        cc.gridy = 1;
574
        lbl = new JLabel(Messages.getText("_Keep_as_polygons"));
575
        lbl.setFont(boldf);
576
        mainPanel.add(lbl, cc);
577
        cc.gridx = 1;
578
        mainPanel.add(new JLabel(Messages.getText("_Multi_polygons_separated_Simple_polygons_kept")), cc);
579

    
580
        resp.add(mainPanel, BorderLayout.CENTER);
581
        resp.add(topLabel, BorderLayout.NORTH);
582
        return resp;
583
    }
584
    
585
    
586
    private Feature cloneFeatureWithGeometry(
587
        Geometry geometry, Feature feature) {
588
        
589
        VectorialLayerEdited vle = getVLE();
590

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

    
609
}