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 / InternalPolygonCADTool.java @ 40557

History | View | Annotate | Download (13.2 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.Component;
27
import java.awt.event.InputEvent;
28
import java.awt.event.MouseEvent;
29
import java.util.ArrayList;
30
import java.util.List;
31

    
32
import javax.swing.JOptionPane;
33

    
34
import com.vividsolutions.jts.geom.GeometryCollection;
35

    
36
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38

    
39
import org.gvsig.andami.PluginServices;
40
import org.gvsig.andami.messages.NotificationManager;
41
import org.gvsig.editing.CADExtension;
42
import org.gvsig.editing.IEditionManager;
43
import org.gvsig.editing.gui.cad.DefaultCADTool;
44
import org.gvsig.editing.gui.cad.exception.CommandException;
45
import org.gvsig.editing.gui.cad.tools.smc.InternalPolygonCADToolContext;
46
import org.gvsig.editing.layers.VectorialLayerEdited;
47
import org.gvsig.fmap.dal.exception.DataException;
48
import org.gvsig.fmap.dal.exception.ReadException;
49
import org.gvsig.fmap.dal.feature.EditableFeature;
50
import org.gvsig.fmap.dal.feature.Feature;
51
import org.gvsig.fmap.dal.feature.FeatureSelection;
52
import org.gvsig.fmap.dal.feature.FeatureSet;
53
import org.gvsig.fmap.dal.feature.FeatureStore;
54
import org.gvsig.fmap.geom.Geometry;
55
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
56
import org.gvsig.fmap.geom.aggregate.MultiSurface;
57
import org.gvsig.fmap.geom.operation.GeometryOperationException;
58
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
59
import org.gvsig.fmap.geom.primitive.GeneralPathX;
60
import org.gvsig.fmap.geom.primitive.Point;
61
import org.gvsig.fmap.geom.primitive.Surface;
62
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
63
import org.gvsig.tools.dispose.DisposableIterator;
64
import org.gvsig.tools.dispose.DisposeUtils;
65

    
66
/**
67
 * DOCUMENT ME!
68
 * 
69
 * @author Vicente Caballero Navarro
70
 */
71
public class InternalPolygonCADTool extends DefaultCADTool {
72
    private static final Logger LOG = LoggerFactory
73
        .getLogger(InternalPolygonCADTool.class);
74

    
75
    protected InternalPolygonCADToolContext _fsm;
76
    protected List<Point> points = new ArrayList<Point>();
77
    protected Geometry geometry = null;
78

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

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

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

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

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

    
131
            if (selection.getSize() == 0
132
                && !SelectionCADTool.isInstance(CADExtension.getCADTool(), true)) {
133
                CADExtension.setCADTool("_selection", false);
134
                ((SelectionCADTool) CADExtension.getCADTool())
135
                    .setNextTool("_internalpolygon");
136
            }
137
        } catch (ReadException e) {
138
            // TODO Auto-generated catch block
139
            e.printStackTrace();
140
        } catch (DataException e) {
141
            // TODO Auto-generated catch block
142
            e.printStackTrace();
143
        }
144
    }
145

    
146
    /**
147
     * Equivale al transition del prototipo pero sin pasarle como par?metro el
148
     * editableFeatureSource que ya estar? creado.
149
     * 
150
     * @param x
151
     *            par?metro x del punto que se pase en esta transici?n.
152
     * @param y
153
     *            par?metro y del punto que se pase en esta transici?n.
154
     */
155
    public void addPoint(double x, double y, InputEvent event) {
156
        if (((MouseEvent) event).getClickCount() == 2) {
157
            addOption(PluginServices
158
                .getText(this, "InternalPolygonCADTool.end"));
159
            return;
160
        }
161
        VectorialLayerEdited vle = getVLE();
162
        FeatureSet featureCollection = null;
163
        DisposableIterator iterator = null;
164
        try {
165
            featureCollection =
166
                (FeatureSet) vle.getFeatureStore().getSelection();
167
            if (featureCollection.getSize() == 1) {
168
                iterator = featureCollection.iterator();
169
                Feature feature = (Feature) iterator.next();
170
                geometry = (feature.getDefaultGeometry()).cloneGeometry();
171
                if (geometry.contains(x, y)) {
172
                    points.add(createPoint(x, y));
173
                } else {
174
                    JOptionPane
175
                        .showMessageDialog(
176
                            ((Component) PluginServices.getMainFrame()),
177
                            PluginServices
178
                                .getText(this,
179
                                    "debe_insertar_el_punto_dentro_de_los_limites_de_la_geometria"));
180
                }
181
            }
182
        } catch (ReadException e) {
183
            NotificationManager.addError(e.getMessage(), e);
184
        } catch (DataException e) {
185
            NotificationManager.addError(e.getMessage(), e);
186
        } finally {
187
            DisposeUtils.dispose(iterator);
188
        }
189
    }
190

    
191
    /**
192
     * M?todo para dibujar la lo necesario para el estado en el que nos
193
     * encontremos.
194
     * 
195
     * @param g
196
     *            Graphics sobre el que dibujar.
197
     * @param x
198
     *            par?metro x del punto que se pase para dibujar.
199
     * @param y
200
     *            par?metro x del punto que se pase para dibujar.
201
     */
202
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
203
        GeneralPathX gpx = new GeneralPathX();
204
        GeneralPathX gpx1 = new GeneralPathX();
205

    
206
        if (points.size() > 0) {
207
            for (int i = 0; i < points.size(); i++) {
208
                if (i == 0) {
209
                    gpx.moveTo(points.get(i));
210
                    gpx1.moveTo(points.get(i));
211
                } else {
212
                    gpx.lineTo(points.get(i));
213
                    gpx1.lineTo(points.get(i));
214
                }
215

    
216
            }
217
            gpx.lineTo(createPoint(x, y));
218
            gpx.closePath();
219
            gpx1.closePath();
220

    
221
            Geometry geom = createSurface(gpx);
222
            Geometry geom1 = createSurface(gpx1);
223

    
224
            renderer.draw(geom1, mapControlManager.getSelectionSymbol());
225
            renderer.draw(geom, mapControlManager.getGeometrySelectionSymbol());
226
        }
227
    }
228

    
229
    /**
230
     * Add a diferent option.
231
     * 
232
     * @param s
233
     *            Diferent option.
234
     */
235
    public void addOption(String s) {
236
        VectorialLayerEdited vle = getVLE();
237
        
238
        IEditionManager ed_man = this.getEditionManager();
239
        
240
        FeatureStore featureStore = null;
241
        try {
242
            featureStore = vle.getFeatureStore();
243
        } catch (ReadException e1) {
244
            // TODO Auto-generated catch block
245
            e1.printStackTrace();
246
        }
247
        DisposableIterator iterator = null;
248
        try {
249
            iterator =
250
                ((FeatureSelection) featureStore.getSelection()).fastIterator();
251
            if (s.equals(PluginServices.getText(this, "end"))
252
                || s.equalsIgnoreCase(PluginServices.getText(this,
253
                    "InternalPolygonCADTool.end"))) {
254
                if (points.size() > 0) {
255
                    Feature feature = (Feature) iterator.next();
256
                    geometry = (feature.getDefaultGeometry()).cloneGeometry();
257
                    if (geometry instanceof GeometryCollection) {
258
                        MultiPrimitive gc = (MultiPrimitive) geometry;
259
                        geometry = createNewPolygonGC(gc, points);
260
                    } else {
261
                        geometry = createNewPolygon(geometry, points);
262
                    }
263
                    try {
264
                        EditableFeature eFeature = feature.getEditable();
265
                        eFeature.setGeometry(featureStore
266
                            .getDefaultFeatureType()
267
                            .getDefaultGeometryAttributeName(), geometry);
268
                        
269
                        ed_man.updateFeature(featureStore, eFeature);
270

    
271
                    } catch (ReadException e) {
272
                        NotificationManager.addError(e.getMessage(), e);
273
                    } catch (DataException e) {
274
                        NotificationManager.addError(e.getMessage(), e);
275
                    }
276
                    ArrayList rows = new ArrayList();
277
                    rows.add(feature);
278
                    // vle.setSelectionCache(VectorialLayerEdited.NOTSAVEPREVIOUS,
279
                    // rows);
280
                }
281
                points.clear();
282
                refresh();
283

    
284
            } else
285
                if (s.equals(PluginServices.getText(this, "cancel"))) {
286
                    points.clear();
287
                }
288
        } catch (DataException e1) {
289
            e1.printStackTrace();
290
        } finally {
291
            if (iterator != null) {
292
                iterator.dispose();
293
            }
294
        }
295
    }
296

    
297
    /*
298
     * (non-Javadoc)
299
     * 
300
     * @see com.iver.cit.gvsig.gui.cad.CADTool#addvalue(double)
301
     */
302
    public void addValue(double d) {
303
    }
304

    
305
    private Geometry createNewPolygon(Geometry geometry, List<Point> points) {        
306
        Geometry newGeometry = geometry.cloneGeometry();
307
                  
308
        GeneralPathX gpxInternal = new GeneralPathX();
309
        gpxInternal.moveTo(points.get(points.size() - 1));
310
        for (int i = points.size() - 2; i >= 0; i--) {
311
            gpxInternal.lineTo(points.get(i));
312
        }
313
        gpxInternal.closePath();
314

    
315
        if (!gpxInternal.isCCW()) {
316
            gpxInternal.flip();
317
        }
318
        
319
        if (newGeometry.getGeometryType().isTypeOf(Geometry.TYPES.SURFACE)){
320
            GeneralPathX newGp = newGeometry.getGeneralPath();
321
            newGp.append(gpxInternal.getPathIterator(null), false);
322
        }else if (newGeometry.getGeometryType().isTypeOf(Geometry.TYPES.MULTISURFACE)){
323
            MultiSurface multiSurface = (MultiSurface)newGeometry;
324
            for (int i=0 ; i<multiSurface.getPrimitivesNumber() ; i++){
325
                Surface surcafe = multiSurface.getSurfaceAt(i);
326
                try {
327
                    if (createSurface(gpxInternal).intersects(surcafe)){
328
                        GeneralPathX newGp = surcafe.getGeneralPath();
329
                        newGp.append(gpxInternal.getPathIterator(null), false);
330
                    }
331
                } catch (GeometryOperationNotSupportedException e) {
332
                    LOG.error("Erro calculating the intersection", e);
333
                } catch (GeometryOperationException e) {
334
                    LOG.error("Erro calculating the intersection", e);
335
                }
336
            }
337
        }
338

    
339
        return newGeometry;
340
    }
341

    
342
    private Geometry createNewPolygonGC(MultiPrimitive multiPrimitive,
343
        List<Point> points) {
344
        MultiPrimitive multiPrimitiveAux = createMultiPrimitive();
345

    
346
        for (int i = 0; i < multiPrimitive.getPrimitivesNumber(); i++) {
347
            multiPrimitiveAux.addPrimitive(multiPrimitive.getPrimitiveAt(i));
348
        }
349

    
350
        GeneralPathX gpx = new GeneralPathX();
351
        gpx.moveTo(points.get(points.size() - 1));
352
        for (int i = points.size() - 2; i >= 0; i--) {
353
            gpx.lineTo(points.get(i));
354
            multiPrimitiveAux.addPrimitive(createCurve(gpx));
355
            gpx = new GeneralPathX();
356
            gpx.moveTo(points.get(i));
357
        }
358
        gpx.closePath();
359
        multiPrimitiveAux.addPrimitive(createCurve(gpx));
360

    
361
        return multiPrimitiveAux;
362
    }
363

    
364
    public String getName() {
365
        return PluginServices.getText(this, "internal_polygon_");
366
    }
367

    
368
    public String toString() {
369
        return "_internalpolygon";
370
    }
371

    
372
    @Override
373
    protected int[] getSupportedGeometryTypes() {
374
        return new int[] { SURFACE, MULTISURFACE };
375
    }
376
}