Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.selectiontools.app / org.gvsig.selectiontools.app.mainplugin / src / main / java / org / gvsig / selectiontools / app / extension / tools / buffer / process / BufferSelectionProcess.java @ 40944

History | View | Annotate | Download (19.9 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.selectiontools.app.extension.tools.buffer.process;
25

    
26
/* gvSIG. Geographic Information System of the Valencian Government
27
 *
28
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
29
 * of the Valencian Government (CIT)
30
 * 
31
 * This program is free software; you can redistribute it and/or
32
 * modify it under the terms of the GNU General Public License
33
 * as published by the Free Software Foundation; either version 2
34
 * of the License, or (at your option) any later version.
35
 * 
36
 * This program is distributed in the hope that it will be useful,
37
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39
 * GNU General Public License for more details.
40
 *  
41
 * You should have received a copy of the GNU General Public License
42
 * along with this program; if not, write to the Free Software
43
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
44
 * MA  02110-1301, USA.
45
 * 
46
 */
47

    
48
import java.awt.event.MouseAdapter;
49
import java.awt.event.MouseEvent;
50
import java.util.ArrayList;
51
import java.util.Iterator;
52

    
53
import javax.swing.JButton;
54

    
55
import org.cresques.cts.ICoordTrans;
56
import org.cresques.cts.IProjection;
57
import org.gvsig.andami.PluginServices;
58
import org.gvsig.andami.messages.NotificationManager;
59
import org.gvsig.andami.ui.mdiManager.IWindow;
60
import org.gvsig.app.project.documents.view.gui.IView;
61
import org.gvsig.fmap.dal.DataSet;
62
import org.gvsig.fmap.dal.feature.Feature;
63
import org.gvsig.fmap.dal.feature.FeatureSelection;
64
import org.gvsig.fmap.dal.feature.FeatureSet;
65
import org.gvsig.fmap.dal.feature.FeatureStore;
66
import org.gvsig.fmap.geom.Geometry;
67
import org.gvsig.fmap.geom.GeometryException;
68
import org.gvsig.fmap.geom.operation.GeometryOperationException;
69
import org.gvsig.fmap.mapcontext.MapContext;
70
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
71
import org.gvsig.fmap.mapcontrol.MapControl;
72
import org.gvsig.gui.beans.buttonspanel.ButtonsPanel;
73
import org.gvsig.gui.beans.incrementabletask.IncrementableProcess;
74
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
75
import org.gvsig.selectiontools.app.extension.tools.buffer.gui.BufferConfigurationPanel;
76
import org.gvsig.tools.dispose.DisposableIterator;
77

    
78
/**
79
 * 
80
 * 
81
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
82
 */
83
public class BufferSelectionProcess extends IncrementableProcess {
84

    
85
    // private boolean layerWasBeingEdited = false;
86

    
87
    private MapControl mapControl = null;
88
    private byte pol_side = -1;
89
    private byte line_side = -1;
90
    private byte point_side = -1;
91
    private byte multi_point_side = -1;
92
    private short selectedDistanceUnit = -1;
93
    private FLyrVect[] layers = null;
94
    private final double f_width;
95
    private boolean multiLayerSelection = false;
96

    
97
    /**
98
     * For polygonal buffers, only compute interior buffers
99
     */
100
    public static final byte BUFFER_INSIDE_POLY = 0;
101

    
102
    /**
103
     * For polygonal buffers, only compute exterior buffers (is the default
104
     * operation, it applies to any geometry type)
105
     */
106
    public static final byte BUFFER_OUTSIDE_POLY = 1;
107

    
108
    /**
109
     * For polygonal buffers, compute interior and exterior buffers
110
     */
111
    public static final byte BUFFER_INSIDE_OUTSIDE_POLY = 2;
112

    
113
    /**
114
     * Buffer with square cap
115
     */
116
    public static final byte CAP_SQUARE = 0;
117
    /**
118
     * Buffer with round cap
119
     */
120
    public static final byte CAP_ROUND = 1;
121

    
122
    /**
123
     * flag that represents buffer computing with one only buffer distance.
124
     */
125
    public static final byte CONSTANT_DISTANCE_STRATEGY = 0;
126

    
127
    /**
128
     * buffer computing with variable buffer distance in function of feature
129
     * attribute value
130
     */
131
    public static final byte ATTRIBUTE_DISTANCE_STRATEGY = 1;
132

    
133
    /**
134
     * Creates a new
135
     * <p>
136
     * BufferSelectionProcess
137
     * </p>
138
     * .
139
     * 
140
     * @param title
141
     *            of the progress dialog
142
     * @param label
143
     *            the label that explains the process
144
     * @param mapControl
145
     *            reference to the current active view's <code>MapControl</code>
146
     *            .
147
     * @param pol_side
148
     *            side of the buffer in a polyline layer:
149
     *            {@link BufferConfigurationPanel#OUTSIDE
150
     *            BufferConfigurationPanel#OUTSIDE},
151
     *            {@link BufferConfigurationPanel#INSIDE
152
     *            BufferConfigurationPanel#INSIDE}, or
153
     *            {@link BufferConfigurationPanel#OUTSIDE_AND_INSIDE
154
     *            BufferConfigurationPanel#OUTSIDE_AND_INSIDE}
155
     * @param line_side
156
     *            side of the buffer in a line layer:
157
     *            {@link BufferConfigurationPanel#OUTSIDE_AND_INSIDE
158
     *            BufferConfigurationPanel#OUTSIDE_AND_INSIDE}
159
     * @param point_side
160
     *            side of the buffer in a point layer:
161
     *            {@link BufferConfigurationPanel#OUTSIDE
162
     *            BufferConfigurationPanel#OUTSIDE}
163
     * @param multi_point_side
164
     *            side of the buffer in a multi point layer:
165
     *            {@link BufferConfigurationPanel#OUTSIDE
166
     *            BufferConfigurationPanel#OUTSIDE}
167
     * @param width
168
     *            buffer's width
169
     * @param selectedDistanceUnit
170
     *            distance unit selected
171
     * @param activeLayers
172
     *            current active view's active layers
173
     * @param showBufferLayers
174
     *            determines if will show the layers with the buffers as new
175
     *            temporal layers
176
     * @param multiLayerSelection
177
     *            determines if the selection in each active layer affects the
178
     *            other
179
     */
180
    public BufferSelectionProcess(String title,
181
        String label,
182
        MapControl mapControl,
183
        byte pol_side,
184
        byte line_side,
185
        byte point_side,
186
        byte multi_point_side,
187
        double width,
188
        short selectedDistanceUnit,
189
        FLyrVect[] activeLayers,
190
        boolean multiLayerSelection) {
191
        super(title);
192

    
193
        this.label = label;
194
        this.mapControl = mapControl;
195
        this.pol_side = pol_side;
196
        this.line_side = line_side;
197
        this.point_side = point_side;
198
        this.multi_point_side = multi_point_side;
199
        this.f_width = width;
200
        this.selectedDistanceUnit = selectedDistanceUnit;
201
        this.layers = activeLayers;
202
        this.multiLayerSelection = multiLayerSelection;
203
        this.isPausable = true;
204
    }
205

    
206
    /**
207
     * Sets the object that will display the evolution of this loading process
208
     * as a progress dialog.
209
     * 
210
     * @param iTask
211
     *            the object that will display the evolution of this loading
212
     *            process
213
     */
214
    public void setIncrementableTask(IncrementableTask iTask) {
215
        this.iTask = iTask;
216
        iTask.setAskCancel(true);
217
        iTask.getButtonsPanel().addAccept();
218
        iTask.getButtonsPanel().setEnabled(ButtonsPanel.BUTTON_ACCEPT, false);
219

    
220
        JButton jButton =
221
            iTask.getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT);
222
        jButton.addMouseListener(new MouseAdapter() {
223

    
224
            /*
225
             * (non-Javadoc)
226
             * 
227
             * @see
228
             * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent
229
             * )
230
             */
231
            public void mouseClicked(MouseEvent e) {
232
                processFinalize();
233
                // Force repaint
234
                mapControl.getMapContext().invalidate();
235
            }
236
        });
237
    }
238

    
239
    /**
240
     * Importation process.
241
     * 
242
     * @throws InterruptedException
243
     *             if fails the process
244
     */
245
    public void process() throws InterruptedException {
246
        percentage = 5;
247
        double inc = 0;
248
        FeatureSelection selections[] = new FeatureSelection[layers.length];
249
        ArrayList<Geometry> buffer[] = new ArrayList[layers.length];
250
        try {
251

    
252
            /* 2- Gets the distance relation */
253
            percentage = 6;
254

    
255
            /* 3- Stores the new selections */
256
            FLyrVect layer = null;
257

    
258
            // int size;
259

    
260
            percentage = 9;
261

    
262
            /* 4- Gets the buffer and intersects to select new geometries */
263
            double width = 1; // default value (not used)
264
            byte side;
265

    
266
            percentage = 11;
267

    
268
            boolean isProjected = false;
269

    
270
            IWindow f = PluginServices.getMDIManager().getActiveWindow();
271
            if (f instanceof IView) {
272
                IView vista = (IView) f;
273

    
274
                // Sets projection
275
                IProjection proj =
276
                    vista.getMapControl().getViewPort().getProjection();
277

    
278
                // Sets distance units
279
                isProjected = proj.isProjected();
280
            }
281
            // Sets map units
282
            int mapUnits = -1;
283
            if (isProjected) {
284
                mapUnits =
285
                    ((IView) PluginServices.getMDIManager().getActiveWindow()).getMapControl()
286
                        .getViewPort()
287
                        .getMapUnits();
288
            } else {
289
                mapUnits = 1;
290
            }
291

    
292
            percentage = 14;
293

    
294
            FeatureStore store = null;
295
            inc = (100 - percentage) / layers.length;
296

    
297
            /* 4.1- For each vector layer with geometries selected */
298
            for (int i = 0; i < layers.length; i++) {
299
                try {
300
                    if (cancelProcess.isCanceled()) {
301
                        throw new InterruptedException();
302
                    }
303

    
304
                    layer = layers[i];
305
                    store = layer.getFeatureStore();
306
                    FeatureSelection selection = (FeatureSelection) store
307
                            .getFeatureSelection()
308
                            .clone();
309
                    selections[i] = selection;
310

    
311
                    log.addLine(PluginServices.getText(null,
312
                        "Starting_selection_of_layer")
313
                        + " \""
314
                        + layer.getName() + "\"");
315

    
316
                    switch (layer.getShapeType()) {
317
                    case Geometry.TYPES.POINT:
318
                        side = point_side;
319
                        break;
320
                    case Geometry.TYPES.CURVE:
321
                    case Geometry.TYPES.MULTICURVE:
322
                        side = line_side;
323
                        break;
324
                    case Geometry.TYPES.SURFACE:
325
                    case Geometry.TYPES.MULTISURFACE:
326
                        side = pol_side;
327
                        break;
328
                    case Geometry.TYPES.MULTIPOINT:
329
                        side = multi_point_side;
330
                        break;
331
                    default: // UNDEFINED
332
                        // UNSUPPORTED
333
                        log.addLine(PluginServices.getText(null,
334
                            "Layer_with_unsupported_geometries_type"));
335
                        percentage += inc;
336
                        continue;
337
                    }
338

    
339
                    /* 4.2- Calculates the width */
340
                    width =
341
                        f_width
342
                            * MapContext.getDistanceTrans2Meter()[selectedDistanceUnit]
343
                            / MapContext.getDistanceTrans2Meter()[mapUnits];
344

    
345
                    /* 4.4- Sets the buffer width */
346
                    /*
347
                    log.addLine(PluginServices.getText(null,
348
                        "Buffer_information") + ":");
349
                        */
350

    
351
                    /* 4.5- Shows width information */
352
                    /*
353
                    if (mapControl.getProjection().isProjected()) {
354
                        log.addLine("    "
355
                            + PluginServices.getText(null, "Buffer_width")
356
                            + ": " + width + " m.");
357
                    } else {
358
                        log.addLine("    "
359
                            + PluginServices.getText(null, "Buffer_width")
360
                            + ": " + width + " m");
361
                        log.addLine("    "
362
                            + PluginServices.getText(null, "Buffer_width")
363
                            + ": " + width
364
                            / MapContext.getDistanceTrans2Meter()[8] + " ?");
365
                    }
366

367
                    log.addLine("    "
368
                        + PluginServices.getText(null, "Buffer_cap") + ": "
369
                        + PluginServices.getText(null, "Round"));
370

371
                    switch (side) {
372
                    case BUFFER_OUTSIDE_POLY:
373
                        log.addLine("    "
374
                            + PluginServices.getText(null, "Side") + ": "
375
                            + PluginServices.getText(null, "Outside"));
376
                        break;
377
                    case BUFFER_INSIDE_POLY:
378
                        log.addLine("    "
379
                            + PluginServices.getText(null, "Side") + ": "
380
                            + PluginServices.getText(null, "Inside"));
381
                        break;
382
                    case BUFFER_INSIDE_OUTSIDE_POLY:
383
                        log.addLine("    "
384
                            + PluginServices.getText(null, "Side")
385
                            + ": "
386
                            + PluginServices.getText(null, "Outside_and_inside"));
387
                        break;
388
                    }
389
                    */
390

    
391
                    /*
392
                     * 4.3- Creates the influence area
393
                     */
394
                    // if (cancelProcess.isCanceled()) {
395
                    // throw new InterruptedException();
396
                    // }
397

    
398
                    DisposableIterator selIt = selection.iterator();
399
                    ArrayList<Geometry> bufferLayer = new ArrayList<Geometry>();
400
                    while (selIt.hasNext()) {
401
                        Feature feat = (Feature) selIt.next();
402
                        Geometry geomBuffer = null;
403
                        switch (side) {
404
                        case BUFFER_OUTSIDE_POLY:
405
                            geomBuffer = buffer(
406
                                feat.getDefaultGeometry(),
407
                                layer.getProjection(),
408
                                layer.getCoordTrans(),
409
                                width);
410
                            // feat.getDefaultGeometry().buffer(width);
411
                            break;
412
                        case BUFFER_INSIDE_POLY:
413
                            geomBuffer = buffer(
414
                                feat.getDefaultGeometry(),
415
                                layer.getProjection(),
416
                                layer.getCoordTrans(),
417
                                -width);
418
                            // feat.getDefaultGeometry().buffer(-width);
419
                            break;
420
                        case BUFFER_INSIDE_OUTSIDE_POLY:
421
                            // Aqu? no deber?a llegar nunca, por si acaso lo
422
                            // dejamos igual que el BUFFER_OUTSIDE_POLY
423
                            geomBuffer = buffer(
424
                                feat.getDefaultGeometry(),
425
                                layer.getProjection(),
426
                                layer.getCoordTrans(),
427
                                width);
428
                            // feat.getDefaultGeometry().buffer(width);
429
                            break;
430
                        }
431
                        bufferLayer.add(geomBuffer);
432
                    }
433
                    buffer[i] = bufferLayer;
434
                    selIt.dispose();
435

    
436
                } catch (Exception e3) {
437
                    /* Notifies the exception in the log */
438
                    if (!cancelProcess.isCanceled()) {
439
                        NotificationManager.showMessageError(PluginServices.getText(null,
440
                            "Error_fallo_geoproceso"),
441
                            e3);
442
                        log.addLine(PluginServices.getText(null,
443
                            "Error_fallo_geoproceso"));
444
                    }
445

    
446
                    throw new InterruptedException();
447
                }
448
            }
449

    
450
            for (int i = 0; i < layers.length; i++) {
451
                layer = layers[i];
452
                
453
                layer.getFeatureStore().disableNotifications();
454

    
455
                FeatureSelection layerSelection =
456
                    layer.getFeatureStore().getFeatureSelection();
457
                
458
                Geometry aux_geometry;
459
                if (multiLayerSelection) {
460
                    for (int j = 0; j < buffer.length; j++) {
461
                        ArrayList<Geometry> bufferLayer = buffer[j];
462
                        if (bufferLayer != null) {
463
                            Iterator<Geometry> geomIt = bufferLayer.iterator();
464
                            while (geomIt.hasNext()) {
465
                                aux_geometry = geomIt.next();
466
                                FeatureSet aux_featSet =
467
                                    layer.queryByGeometry(aux_geometry,
468
                                        layer.getFeatureStore()
469
                                            .getDefaultFeatureType());
470
                                layerSelection.select(aux_featSet);
471
                            }
472
                        }
473
                    }
474

    
475
                } else {
476
                    ArrayList<Geometry> bufferLayer = buffer[i];
477
                    Iterator<Geometry> geomIt = bufferLayer.iterator();
478
                    while (geomIt.hasNext()) {
479
                        aux_geometry = geomIt.next();
480
                        FeatureSet aux_featSet =
481
                            layer.queryByGeometry(aux_geometry,
482
                                layer.getFeatureStore().getDefaultFeatureType());
483
                        layerSelection.select(aux_featSet);
484
                    }
485

    
486
                }
487
                
488
                layer.getFeatureStore().enableNotifications();
489
            }
490

    
491
            /*
492
            log.addLine(PluginServices.getText(null,
493
                "Selection_process_finished_succesfully"));
494
            log.addLine(""); // Empty line
495
            */
496
            
497
        } catch (Exception de) {
498
            /* 5- Notifies the exception in the log */
499
            if (!cancelProcess.isCanceled()) {
500
                log.addLine(PluginServices.getText(null, "Selection_restored"));
501

    
502
                throw new InterruptedException();
503
            }
504

    
505
            percentage += inc;
506
        }
507

    
508
        percentage = 100;
509
    }
510
    
511
    /**
512

513
     * @param geom geom of store
514
     * @param storeProj
515
     * @param layerCT
516
     * @param dist in meters
517
     * @return buffered geom in CRS of view
518
     */
519
    private Geometry buffer(
520
        Geometry geom,
521
        IProjection storeProj,
522
        ICoordTrans layerCT,
523
        double dist) throws Exception {
524
        
525
        if (layerCT == null) {
526
            // Not reprojected on the fly
527
            if (storeProj.isProjected()) {
528
                return geom.buffer(dist);
529
            } else {
530
                dist = dist * 180.0 / (Math.PI * 6378137);
531
                return geom.buffer(dist);
532
            }
533
            
534
        } else {
535
            
536
         // Reprojected on the fly
537
            Geometry aux = geom.cloneGeometry();
538
            aux.reProject(layerCT);
539
            return buffer(aux, layerCT.getPDest(), null, dist);
540
        }
541
    }
542

    
543
}