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 @ 43510

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

    
26
import java.awt.event.MouseAdapter;
27
import java.awt.event.MouseEvent;
28
import java.util.ArrayList;
29
import java.util.Iterator;
30

    
31
import javax.swing.JButton;
32

    
33
import org.cresques.cts.ICoordTrans;
34
import org.cresques.cts.IProjection;
35
import org.gvsig.andami.PluginServices;
36
import org.gvsig.andami.messages.NotificationManager;
37
import org.gvsig.andami.ui.mdiManager.IWindow;
38
import org.gvsig.app.project.documents.view.gui.IView;
39
import org.gvsig.fmap.dal.feature.Feature;
40
import org.gvsig.fmap.dal.feature.FeatureSelection;
41
import org.gvsig.fmap.dal.feature.FeatureSet;
42
import org.gvsig.fmap.dal.feature.FeatureStore;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.mapcontext.MapContext;
47
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
48
import org.gvsig.fmap.mapcontrol.MapControl;
49
import org.gvsig.gui.beans.buttonspanel.ButtonsPanel;
50
import org.gvsig.gui.beans.incrementabletask.IncrementableProcess;
51
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
52
import org.gvsig.selectiontools.app.extension.tools.buffer.gui.BufferConfigurationPanel;
53
import org.gvsig.tools.dispose.DisposableIterator;
54

    
55
public class BufferSelectionProcess extends IncrementableProcess {
56

    
57
    // private boolean layerWasBeingEdited = false;
58

    
59
    private MapControl mapControl = null;
60
    private byte pol_side = -1;
61
    private byte line_side = -1;
62
    private byte point_side = -1;
63
    private byte multi_point_side = -1;
64
    private short selectedDistanceUnit = -1;
65
    private FLyrVect[] layers = null;
66
    private final double f_width;
67
    private boolean multiLayerSelection = false;
68

    
69
    /**
70
     * For polygonal buffers, only compute interior buffers
71
     */
72
    public static final byte BUFFER_INSIDE_POLY = 0;
73

    
74
    /**
75
     * For polygonal buffers, only compute exterior buffers (is the default
76
     * operation, it applies to any geometry type)
77
     */
78
    public static final byte BUFFER_OUTSIDE_POLY = 1;
79

    
80
    /**
81
     * For polygonal buffers, compute interior and exterior buffers
82
     */
83
    public static final byte BUFFER_INSIDE_OUTSIDE_POLY = 2;
84

    
85
    /**
86
     * Buffer with square cap
87
     */
88
    public static final byte CAP_SQUARE = 0;
89
    /**
90
     * Buffer with round cap
91
     */
92
    public static final byte CAP_ROUND = 1;
93

    
94
    /**
95
     * flag that represents buffer computing with one only buffer distance.
96
     */
97
    public static final byte CONSTANT_DISTANCE_STRATEGY = 0;
98

    
99
    /**
100
     * buffer computing with variable buffer distance in function of feature
101
     * attribute value
102
     */
103
    public static final byte ATTRIBUTE_DISTANCE_STRATEGY = 1;
104

    
105
    /**
106
     * Creates a new
107
     * <p>
108
     * BufferSelectionProcess
109
     * </p>
110
     * .
111
     * 
112
     * @param title
113
     *            of the progress dialog
114
     * @param label
115
     *            the label that explains the process
116
     * @param mapControl
117
     *            reference to the current active view's <code>MapControl</code>
118
     *            .
119
     * @param pol_side
120
     *            side of the buffer in a polyline layer:
121
     *            {@link BufferConfigurationPanel#OUTSIDE
122
     *            BufferConfigurationPanel#OUTSIDE},
123
     *            {@link BufferConfigurationPanel#INSIDE
124
     *            BufferConfigurationPanel#INSIDE}, or
125
     *            {@link BufferConfigurationPanel#OUTSIDE_AND_INSIDE
126
     *            BufferConfigurationPanel#OUTSIDE_AND_INSIDE}
127
     * @param line_side
128
     *            side of the buffer in a line layer:
129
     *            {@link BufferConfigurationPanel#OUTSIDE_AND_INSIDE
130
     *            BufferConfigurationPanel#OUTSIDE_AND_INSIDE}
131
     * @param point_side
132
     *            side of the buffer in a point layer:
133
     *            {@link BufferConfigurationPanel#OUTSIDE
134
     *            BufferConfigurationPanel#OUTSIDE}
135
     * @param multi_point_side
136
     *            side of the buffer in a multi point layer:
137
     *            {@link BufferConfigurationPanel#OUTSIDE
138
     *            BufferConfigurationPanel#OUTSIDE}
139
     * @param width
140
     *            buffer's width
141
     * @param selectedDistanceUnit
142
     *            distance unit selected
143
     * @param activeLayers
144
     *            current active view's active layers
145
     * @param showBufferLayers
146
     *            determines if will show the layers with the buffers as new
147
     *            temporal layers
148
     * @param multiLayerSelection
149
     *            determines if the selection in each active layer affects the
150
     *            other
151
     */
152
    public BufferSelectionProcess(String title,
153
        String label,
154
        MapControl mapControl,
155
        byte pol_side,
156
        byte line_side,
157
        byte point_side,
158
        byte multi_point_side,
159
        double width,
160
        short selectedDistanceUnit,
161
        FLyrVect[] activeLayers,
162
        boolean multiLayerSelection) {
163
        super(title);
164

    
165
        this.label = label;
166
        this.mapControl = mapControl;
167
        this.pol_side = pol_side;
168
        this.line_side = line_side;
169
        this.point_side = point_side;
170
        this.multi_point_side = multi_point_side;
171
        this.f_width = width;
172
        this.selectedDistanceUnit = selectedDistanceUnit;
173
        this.layers = activeLayers;
174
        this.multiLayerSelection = multiLayerSelection;
175
        this.isPausable = true;
176
    }
177

    
178
    /**
179
     * Sets the object that will display the evolution of this loading process
180
     * as a progress dialog.
181
     * 
182
     * @param iTask
183
     *            the object that will display the evolution of this loading
184
     *            process
185
     */
186
    public void setIncrementableTask(IncrementableTask iTask) {
187
        this.iTask = iTask;
188
        iTask.setAskCancel(true);
189
        iTask.getButtonsPanel().addAccept();
190
        iTask.getButtonsPanel().setEnabled(ButtonsPanel.BUTTON_ACCEPT, false);
191

    
192
        JButton jButton =
193
            iTask.getButtonsPanel().getButton(ButtonsPanel.BUTTON_ACCEPT);
194
        jButton.addMouseListener(new MouseAdapter() {
195

    
196
            /*
197
             * (non-Javadoc)
198
             * 
199
             * @see
200
             * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent
201
             * )
202
             */
203
            public void mouseClicked(MouseEvent e) {
204
                processFinalize();
205
                // Force repaint
206
                mapControl.getMapContext().invalidate();
207
            }
208
        });
209
    }
210

    
211
    /**
212
     * Importation process.
213
     * 
214
     * @throws InterruptedException
215
     *             if fails the process
216
     */
217
    public void process() throws InterruptedException {
218
        percentage = 5;
219
        double inc = 0;
220
        FeatureSelection selections[] = new FeatureSelection[layers.length];
221
        ArrayList<Geometry> buffer[] = new ArrayList[layers.length];
222
        try {
223

    
224
            /* 2- Gets the distance relation */
225
            percentage = 6;
226

    
227
            /* 3- Stores the new selections */
228
            FLyrVect layer = null;
229

    
230
            // int size;
231

    
232
            percentage = 9;
233

    
234
            /* 4- Gets the buffer and intersects to select new geometries */
235
            double width = 1; // default value (not used)
236
            byte side;
237

    
238
            percentage = 11;
239

    
240
            boolean isProjected = false;
241

    
242
            IWindow f = PluginServices.getMDIManager().getActiveWindow();
243
            if (f instanceof IView) {
244
                IView vista = (IView) f;
245

    
246
                // Sets projection
247
                IProjection proj =
248
                    vista.getMapControl().getViewPort().getProjection();
249

    
250
                // Sets distance units
251
                isProjected = proj.isProjected();
252
            }
253
            // Sets map units
254
            int mapUnits = -1;
255
            if (isProjected) {
256
                mapUnits =
257
                    ((IView) PluginServices.getMDIManager().getActiveWindow()).getMapControl()
258
                        .getViewPort()
259
                        .getMapUnits();
260
            } else {
261
                mapUnits = 1;
262
            }
263

    
264
            percentage = 14;
265

    
266
            FeatureStore store = null;
267
            inc = (100 - percentage) / layers.length;
268

    
269
            /* 4.1- For each vector layer with geometries selected */
270
            for (int i = 0; i < layers.length; i++) {
271
                try {
272
                    if (cancelProcess.isCanceled()) {
273
                        throw new InterruptedException();
274
                    }
275

    
276
                    layer = layers[i];
277
                    store = layer.getFeatureStore();
278
                    FeatureSelection selection = (FeatureSelection) store
279
                            .getFeatureSelection()
280
                            .clone();
281
                    selections[i] = selection;
282

    
283
                    log.addLine(PluginServices.getText(null,
284
                        "Starting_selection_of_layer")
285
                        + " \""
286
                        + layer.getName() + "\"");
287

    
288
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
289
                    if( geomManager.isSubtype(Geometry.TYPES.POINT, layer.getShapeType()) ) {
290
                        side = point_side;
291
                        
292
                    } else if( geomManager.isSubtype(Geometry.TYPES.CURVE, layer.getShapeType()) ) {
293
                        side = line_side;
294
                        
295
                    } else if( geomManager.isSubtype(Geometry.TYPES.SURFACE, layer.getShapeType()) ) {
296
                        side = pol_side;
297

    
298
                    } else if( geomManager.isSubtype(Geometry.TYPES.MULTIPOINT, layer.getShapeType()) ) {
299
                        side = multi_point_side;
300
                        
301
                    } else if( geomManager.isSubtype(Geometry.TYPES.MULTICURVE, layer.getShapeType()) ) {
302
                        side = line_side;
303
                        
304
                    } else if( geomManager.isSubtype(Geometry.TYPES.MULTISURFACE, layer.getShapeType()) ) {
305
                        side = pol_side;
306
                    } else {
307
                        log.addLine(PluginServices.getText(null,
308
                            "Layer_with_unsupported_geometries_type"));
309
                        percentage += inc;
310
                        continue;
311
                    }
312

    
313
                    /* 4.2- Calculates the width */
314
                    width =
315
                        f_width
316
                            * MapContext.getDistanceTrans2Meter()[selectedDistanceUnit]
317
                            / MapContext.getDistanceTrans2Meter()[mapUnits];
318

    
319
                    /* 4.4- Sets the buffer width */
320
                    /*
321
                    log.addLine(PluginServices.getText(null,
322
                        "Buffer_information") + ":");
323
                        */
324

    
325
                    /* 4.5- Shows width information */
326
                    /*
327
                    if (mapControl.getProjection().isProjected()) {
328
                        log.addLine("    "
329
                            + PluginServices.getText(null, "Buffer_width")
330
                            + ": " + width + " m.");
331
                    } else {
332
                        log.addLine("    "
333
                            + PluginServices.getText(null, "Buffer_width")
334
                            + ": " + width + " m");
335
                        log.addLine("    "
336
                            + PluginServices.getText(null, "Buffer_width")
337
                            + ": " + width
338
                            / MapContext.getDistanceTrans2Meter()[8] + " ?");
339
                    }
340

341
                    log.addLine("    "
342
                        + PluginServices.getText(null, "Buffer_cap") + ": "
343
                        + PluginServices.getText(null, "Round"));
344

345
                    switch (side) {
346
                    case BUFFER_OUTSIDE_POLY:
347
                        log.addLine("    "
348
                            + PluginServices.getText(null, "Side") + ": "
349
                            + PluginServices.getText(null, "Outside"));
350
                        break;
351
                    case BUFFER_INSIDE_POLY:
352
                        log.addLine("    "
353
                            + PluginServices.getText(null, "Side") + ": "
354
                            + PluginServices.getText(null, "Inside"));
355
                        break;
356
                    case BUFFER_INSIDE_OUTSIDE_POLY:
357
                        log.addLine("    "
358
                            + PluginServices.getText(null, "Side")
359
                            + ": "
360
                            + PluginServices.getText(null, "Outside_and_inside"));
361
                        break;
362
                    }
363
                    */
364

    
365
                    /*
366
                     * 4.3- Creates the influence area
367
                     */
368
                    // if (cancelProcess.isCanceled()) {
369
                    // throw new InterruptedException();
370
                    // }
371

    
372
                    DisposableIterator selIt = selection.fastIterator();
373
                    ArrayList<Geometry> bufferLayer = new ArrayList<Geometry>();
374
                    while (selIt.hasNext()) {
375
                        Feature feat = (Feature) selIt.next();
376
                        Geometry geomBuffer = null;
377
                        switch (side) {
378
                        case BUFFER_OUTSIDE_POLY:
379
                            geomBuffer = buffer(
380
                                feat.getDefaultGeometry(),
381
                                layer.getProjection(),
382
                                layer.getCoordTrans(),
383
                                width);
384
                            // feat.getDefaultGeometry().buffer(width);
385
                            break;
386
                        case BUFFER_INSIDE_POLY:
387
                            geomBuffer = buffer(
388
                                feat.getDefaultGeometry(),
389
                                layer.getProjection(),
390
                                layer.getCoordTrans(),
391
                                -width);
392
                            // feat.getDefaultGeometry().buffer(-width);
393
                            break;
394
                        case BUFFER_INSIDE_OUTSIDE_POLY:
395
                            // Aqu? no deber?a llegar nunca, por si acaso lo
396
                            // dejamos igual que el BUFFER_OUTSIDE_POLY
397
                            geomBuffer = buffer(
398
                                feat.getDefaultGeometry(),
399
                                layer.getProjection(),
400
                                layer.getCoordTrans(),
401
                                width);
402
                            // feat.getDefaultGeometry().buffer(width);
403
                            break;
404
                        }
405
                        bufferLayer.add(geomBuffer);
406
                    }
407
                    buffer[i] = bufferLayer;
408
                    selIt.dispose();
409

    
410
                } catch (Exception e3) {
411
                    /* Notifies the exception in the log */
412
                    if (!cancelProcess.isCanceled()) {
413
                        NotificationManager.showMessageError(PluginServices.getText(null,
414
                            "Error_fallo_geoproceso"),
415
                            e3);
416
                        log.addLine(PluginServices.getText(null,
417
                            "Error_fallo_geoproceso"));
418
                    }
419

    
420
                    throw new InterruptedException();
421
                }
422
            }
423

    
424
            for (int i = 0; i < layers.length; i++) {
425
                layer = layers[i];
426
                
427
                layer.getFeatureStore().disableNotifications();
428

    
429
                FeatureSelection layerSelection =
430
                    layer.getFeatureStore().getFeatureSelection();
431
                
432
                Geometry aux_geometry;
433
                if (multiLayerSelection) {
434
                    for (int j = 0; j < buffer.length; j++) {
435
                        ArrayList<Geometry> bufferLayer = buffer[j];
436
                        if (bufferLayer != null) {
437
                            Iterator<Geometry> geomIt = bufferLayer.iterator();
438
                            while (geomIt.hasNext()) {
439
                                aux_geometry = geomIt.next();
440
                                FeatureSet aux_featSet =
441
                                    layer.queryByGeometry(aux_geometry,
442
                                        layer.getFeatureStore()
443
                                            .getDefaultFeatureType());
444
                                layerSelection.select(aux_featSet);
445
                            }
446
                        }
447
                    }
448

    
449
                } else {
450
                    ArrayList<Geometry> bufferLayer = buffer[i];
451
                    Iterator<Geometry> geomIt = bufferLayer.iterator();
452
                    while (geomIt.hasNext()) {
453
                        aux_geometry = geomIt.next();
454
                        FeatureSet aux_featSet =
455
                            layer.queryByGeometry(aux_geometry,
456
                                layer.getFeatureStore().getDefaultFeatureType());
457
                        layerSelection.select(aux_featSet);
458
                    }
459

    
460
                }
461
                
462
                layer.getFeatureStore().enableNotifications();
463
            }
464

    
465
            /*
466
            log.addLine(PluginServices.getText(null,
467
                "Selection_process_finished_succesfully"));
468
            log.addLine(""); // Empty line
469
            */
470
            
471
        } catch (Exception de) {
472
            /* 5- Notifies the exception in the log */
473
            if (!cancelProcess.isCanceled()) {
474
                log.addLine(PluginServices.getText(null, "Selection_restored"));
475

    
476
                throw new InterruptedException();
477
            }
478

    
479
            percentage += inc;
480
        }
481

    
482
        percentage = 100;
483
    }
484
    
485
    /**
486

487
     * @param geom geom of store
488
     * @param storeProj
489
     * @param layerCT
490
     * @param dist in meters
491
     * @return buffered geom in CRS of view
492
     */
493
    private Geometry buffer(
494
        Geometry geom,
495
        IProjection storeProj,
496
        ICoordTrans layerCT,
497
        double dist) throws Exception {
498
        
499
        if (layerCT == null) {
500
            // Not reprojected on the fly
501
            if (storeProj.isProjected()) {
502
                return geom.buffer(dist);
503
            } else {
504
                dist = dist * 180.0 / (Math.PI * 6378137);
505
                return geom.buffer(dist);
506
            }
507
            
508
        } else {
509
            
510
         // Reprojected on the fly
511
            Geometry aux = geom.cloneGeometry();
512
            aux.reProject(layerCT);
513
            return buffer(aux, layerCT.getPDest(), null, dist);
514
        }
515
    }
516

    
517
}