Statistics
| Revision:

gvsig-geoprocess / org.gvsig.geoprocess / trunk / org.gvsig.geoprocess / org.gvsig.geoprocess.algorithm / org.gvsig.geoprocess.algorithm.buffer / src / main / java / org / gvsig / geoprocess / algorithm / buffer / BufferAlgorithm.java @ 332

History | View | Annotate | Download (14.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2012 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 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
 * 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.geoprocess.algorithm.buffer;
25

    
26
import java.io.File;
27

    
28
import javax.swing.JOptionPane;
29

    
30
import org.cresques.cts.IProjection;
31
import org.gvsig.fmap.dal.DALLocator;
32
import org.gvsig.fmap.dal.DataManager;
33
import org.gvsig.fmap.dal.DataStoreParameters;
34
import org.gvsig.fmap.dal.DataTypes;
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.exception.InitializeException;
37
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
38
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
39
import org.gvsig.fmap.dal.feature.EditableFeatureType;
40
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
44
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
45
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.geoprocess.algorithm.fusespatially.FuseSpatiallyAlgorithm;
48
import org.gvsig.geoprocess.lib.api.GeoProcessLocator;
49
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
50
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
51
import org.hsqldb.Types;
52

    
53
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
54
import es.unex.sextante.core.Sextante;
55
import es.unex.sextante.dataObjects.IVectorLayer;
56
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
57
import es.unex.sextante.exceptions.OptionalParentParameterException;
58
import es.unex.sextante.exceptions.RepeatedParameterNameException;
59
import es.unex.sextante.exceptions.UndefinedParentParameterNameException;
60
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
61
import es.unex.sextante.gui.algorithm.GeoAlgorithmParametersPanel;
62
import es.unex.sextante.outputs.OutputVectorLayer;
63

    
64
/**
65
 * Geoprocess that computes a buffer area around each feature's geometry of the
66
 * input layer. <br>
67
 * All the points interior to this buffer area has to be at a distance inferior
68
 * to "buffer distance" to the original geometry. This buffer distance could be
69
 * constant, or it could be a function of the value of a feature attribute.<br>
70
 * 
71
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
72
 * @author gvSIG Team
73
 */
74
public class BufferAlgorithm extends AbstractSextanteGeoProcess {
75

    
76
    public static final String RESULT = "RESULT";
77
    public static final String LAYER = "LAYER";
78
    public static final String SELECTED_GEOM = "SELECTED_GEOM";
79
    public static final String DISTANCE = "DISTANCE";
80
    public static final String FIELD = "FIELD";
81
    public static final String DISSOLVE = "DISSOLVE";
82
    public static final String ROUND_BORDER = "ROUND_BORDER";
83
    public static final String AREA = "AREA";
84
    public static final String RING_NUMBER = "RING_NUMBER";
85
    public static String[] sOptions = {
86
            GeoProcessLocator.getGeoProcessManager().getTranslation("poly_out"), 
87
            GeoProcessLocator.getGeoProcessManager().getTranslation("poly_in"),
88
            GeoProcessLocator.getGeoProcessManager().getTranslation("poly_inandout") 
89
            };
90

    
91
    public void defineCharacteristics() {
92
        setName(getTranslation("Buffer"));
93
        setGroup(getTranslation("basic_vect_algorithms"));
94
        // setGeneratesUserDefinedRasterOutput(false);
95
       
96
        try {
97
            m_Parameters.addInputVectorLayer(LAYER, getTranslation("Input_layer"), 
98
                    IVectorLayer.SHAPE_TYPE_WRONG, true);
99
            m_Parameters.addBoolean(SELECTED_GEOM, getTranslation("Selected_geometries"), false);
100
            m_Parameters.addNumericalValue(DISTANCE, getTranslation("area_distance"), 0,
101
                AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE);
102
            m_Parameters.addTableField(FIELD, getTranslation("area_field"), "LAYER");
103
            m_Parameters.addBoolean(DISSOLVE, getTranslation("Dissolve_entities"), false);
104
            m_Parameters.addBoolean(ROUND_BORDER, getTranslation("Round_border"), true);
105
            m_Parameters.addSelection(AREA, getTranslation("Builds_influence_area"), sOptions);
106
            m_Parameters.addSelection(RING_NUMBER, getTranslation("Number_of_rings"),
107
                new String[] { "1", "2", "3" });
108
        } catch (RepeatedParameterNameException e) {
109
            Sextante.addErrorToLog(e);
110
        } catch (UndefinedParentParameterNameException e) {
111
            Sextante.addErrorToLog(e);
112
        } catch (OptionalParentParameterException e) {
113
            Sextante.addErrorToLog(e);
114
        }
115
        addOutputVectorLayer(RESULT, getTranslation("Buffer"),
116
            OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
117
    }
118

    
119
    public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
120

    
121
            if(existsOutPutFile(BufferAlgorithm.RESULT, 0)) {
122
                    throw new GeoAlgorithmExecutionException(getTranslation("file_exists"));
123
            }
124
            
125
        IVectorLayer layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
126
        boolean selectedGeom = m_Parameters.getParameter(SELECTED_GEOM).getParameterValueAsBoolean();
127
        double dist = m_Parameters.getParameter(DISTANCE).getParameterValueAsDouble();
128
        int attributePosition = m_Parameters.getParameterValueAsInt(FIELD);
129
        // boolean dissolve =
130
        // m_Parameters.getParameter(DISSOLVE).getParameterValueAsBoolean();
131
        boolean round_border = m_Parameters.getParameter(ROUND_BORDER).getParameterValueAsBoolean();
132
        int inflArea = m_Parameters.getParameterValueAsInt(AREA);
133
        int rings = m_Parameters.getParameterValueAsInt(RING_NUMBER);
134
        boolean dissolve = m_Parameters.getParameter(DISSOLVE).getParameterValueAsBoolean();
135

    
136
        if (layer.getShapeType() != IVectorLayer.SHAPE_TYPE_POLYGON
137
            && inflArea != 0) {
138
            JOptionPane.showMessageDialog(null,
139
                getTranslation("Wrong_type_for_this_shapetype"), "Error",
140
                JOptionPane.WARNING_MESSAGE);
141
            inflArea = 0;
142
        }
143

    
144
        FeatureStore storeLayer = null;
145
        if (layer instanceof FlyrVectIVectorLayer)
146
            storeLayer = ((FlyrVectIVectorLayer) layer).getFeatureStore();
147
        else
148
            return false;
149

    
150
        try {
151
            FeatureSet features = null;
152
            features = storeLayer.getFeatureSet();
153
            FeatureType featureType = features.getDefaultFeatureType();
154

    
155
            // Object to compute the distance
156
            IDistance distance = null;
157
            if (dist == 0)
158
                distance = new FieldDistance(attributePosition);
159
            else
160
                distance = new ConstantDistance();
161

    
162
            // Object to compute the buffer operation
163
            BufferOperation operation = null;
164
            switch (inflArea) {
165
            case 0:
166
                operation = new OutBufferOperation(distance, layer, dist, this);
167
                break;
168
            case 1:
169
                operation = new InBufferOperation(distance, layer, dist, this);
170
                break;
171
            case 2:
172
                operation = new InOutBufferOperation(distance, layer, dist, this);
173
                break;
174
            }
175
            operation.setTypeOfCap(round_border ? BufferOperation.CAP_ROUND
176
                : BufferOperation.CAP_SQUARE);
177
            operation.setNumberOfRadialBuffers(rings + 1);
178
            operation.setGeoProcess(this, 100);
179
            
180
                // Builds the output FeatureStore
181
                FeatureStore outFeatStore =
182
                        buildOutPutStore(featureType,
183
                                        org.gvsig.fmap.geom.Geometry.TYPES.SURFACE,
184
                                        getTranslation("Buffer"), RESULT, inflArea);
185
                
186
            
187
            if(dissolve && rings == 0) { //solo se disuelve si hay un anillo
188
                    FeatureStore outAuxFeatStore = null;
189
                    try {
190
                            String file = System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis() + ".shp";
191
                            outAuxFeatStore = buildTemporalStore(featureType,
192
                                            org.gvsig.fmap.geom.Geometry.TYPES.SURFACE, file, inflArea, 
193
                                            storeLayer.getDefaultFeatureType().getDefaultSRS());
194

    
195
                            operation.setTaskStatus(getStatus());
196
                            operation.computesGeometryOperation(storeLayer, outAuxFeatStore,
197
                                            attrNames, selectedGeom, true);
198

    
199
                            outAuxFeatStore = open(file, storeLayer.getDefaultFeatureType().getDefaultSRS());
200
                            FuseSpatiallyAlgorithm alg = new FuseSpatiallyAlgorithm();
201
                            alg.setTaskMonitor(m_Task);
202
                            alg.setParentProcess(this);
203
                            m_Task.setProgressText(getTranslation("fuse_spatially"));
204
                            alg.execute(outAuxFeatStore, outFeatStore, IVectorLayer.SHAPE_TYPE_POLYGON, 
205
                                            false, getStatus(), "FID", false);
206
                    } catch (ValidateDataParametersException e) {
207
                            Sextante.addErrorToLog(e);
208
                    }
209
            } else { 
210
                    // Computes the operation
211
                    operation.setTaskStatus(getStatus());
212
                    operation.computesGeometryOperation(storeLayer, outFeatStore,
213
                                    attrNames, selectedGeom, true);
214
            } 
215
        } catch (DataException e) {
216
            Sextante.addErrorToLog(e);
217
            return false;
218
        }
219
        
220
                if(getTaskMonitor().isCanceled())
221
                        return false;
222

    
223
        return true;
224
    }
225
    
226
    private FeatureStore open(String file, IProjection proj) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
227
            DataManager manager = DALLocator.getDataManager();
228
            DataStoreParameters params = manager.createStoreParameters("Shape");
229
            params.setDynValue("shpfile", file);
230
            params.setDynValue("crs", proj);
231
            FeatureStore featureStore = (FeatureStore) manager.openStore(params.getDataStoreName(), params);
232
            return featureStore;
233
    }
234

    
235
    /**
236
     * Builds the output FeatureStore
237
     * 
238
     * @param featureType
239
     * @return FeatureStore
240
     */
241
    protected FeatureStore buildOutPutStore(FeatureType featureType,
242
        int shapeType, String sextanteLayerName, String sextanteLayerLabel,
243
        int infArea) {
244

    
245
        Class<?>[] types = null;
246
        if (infArea == 2) {
247
            types = new Class[] { Integer.class, Double.class, Double.class };
248
            attrNames = new String[] { "FID", "FROM", "TO" };
249
        } else {
250
            types = new Class[] { Integer.class, Double.class };
251
            attrNames = new String[] { "FID", "DIST" };
252
        }
253

    
254
        try {
255
            IVectorLayer output =
256
                getNewVectorLayer(sextanteLayerLabel, sextanteLayerName,
257
                    shapeType, types, attrNames);
258
            return ((FlyrVectIVectorLayer) output).getFeatureStore();
259
        } catch (UnsupportedOutputChannelException e) {
260
            Sextante.addErrorToLog(e);
261
        } catch (GeoAlgorithmExecutionException e) {
262
            Sextante.addErrorToLog(e);
263
        }
264
        return null;
265
    }
266
    
267
    /**
268
     * Builds the output FeatureStore
269
     * 
270
     * @param featureType
271
     * @return FeatureStore
272
     * @throws DataException 
273
     * @throws ValidateDataParametersException 
274
     */
275
    protected FeatureStore buildTemporalStore(FeatureType featureType,
276
        int shapeType, String file,
277
        int infArea, IProjection crs) throws DataException, ValidateDataParametersException {
278

    
279
        int[] types = null;
280
        if (infArea == 2) {
281
            types = new int[] { Types.INTEGER, Types.DOUBLE, Types.DOUBLE };
282
            attrNames = new String[] { "FID", "FROM", "TO" };
283
        } else {
284
            types = new int[] { Types.INTEGER, Types.DOUBLE };
285
            attrNames = new String[] { "FID", "DIST" };
286
        }
287

    
288
        return create(file, types, attrNames, crs);
289
    }
290
    
291
        @SuppressWarnings("deprecation")
292
        public FeatureStore create(String sFilename,
293
                        int[] types, String[] sFields, IProjection crs) {
294
                try {
295
                        DataManager manager = DALLocator.getDataManager();
296
                        FilesystemServerExplorerParameters explorerParams =
297
                            (FilesystemServerExplorerParameters) manager.createServerExplorerParameters("FilesystemExplorer");
298
                        explorerParams.setRoot(new File(sFilename).getParent());
299
                        FilesystemServerExplorer explorer = (FilesystemServerExplorer) manager.createServerExplorer(explorerParams);
300
                        NewFeatureStoreParameters newParams = (NewFeatureStoreParameters) explorer.getAddParameters(new File(sFilename));
301
                        
302
                        EditableFeatureType ft = newParams.getDefaultFeatureType();
303
                        for (int i = 0; i < attrNames.length; i++) {
304
                                ft.add(attrNames[i], types[i], 7);
305
                        }
306
                        ft.add("GEOMETRY", DataTypes.GEOMETRY).setGeometryType(
307
                                        Geometry.TYPES.SURFACE).setGeometrySubType(Geometry.SUBTYPES.GEOM2D);
308
                        
309
                        newParams.setDefaultFeatureType(ft);
310
                        newParams.setDynValue("CRS", crs);
311
                        newParams.setDynValue("geometryType", Geometry.TYPES.SURFACE);
312

    
313
                        manager.newStore("FilesystemExplorer",
314
                newParams.getDataStoreName(), newParams, true);
315
                
316
                        FeatureStore featureStore = (FeatureStore) manager.openStore(newParams.getDataStoreName(), newParams);                        
317
                        featureStore.edit(FeatureStore.MODE_APPEND);
318
                        return featureStore;
319
                } catch (Exception e) {
320
                        Sextante.addErrorToLog(e);
321
                }
322
                return null;
323
        }
324

    
325

    
326
    @Override
327
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
328
        return BufferParametersPanel.class;
329
    }
330
}