Statistics
| Revision:

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

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

    
30
import javax.swing.JOptionPane;
31

    
32
import com.vividsolutions.jts.geom.GeometryCollection;
33

    
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

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

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

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

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

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

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

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

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

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

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

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

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

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

    
219
            Geometry geom = createSurface(gpx);
220
            Geometry geom1 = createSurface(gpx1);
221

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

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

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

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

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

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

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

    
337
        return newGeometry;
338
    }
339

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

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

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

    
359
        return multiPrimitiveAux;
360
    }
361

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

    
366
    public String toString() {
367
        return "_internalpolygon";
368
    }
369

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