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

History | View | Annotate | Download (14 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.sextante.AbstractSextanteGeoProcess;
49
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
50
import org.hsqldb.Types;
51

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

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

    
74
    public static final String RESULT = "RESULT";
75
    public static final String LAYER = "LAYER";
76
    public static final String SELECTED_GEOM = "SELECTED_GEOM";
77
    public static final String DISTANCE = "DISTANCE";
78
    public static final String FIELD = "FIELD";
79
    public static final String DISSOLVE = "DISSOLVE";
80
    public static final String ROUND_BORDER = "ROUND_BORDER";
81
    public static final String AREA = "AREA";
82
    public static final String RING_NUMBER = "RING_NUMBER";
83

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

    
116
    public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
117

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

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

    
141
        FeatureStore storeLayer = null;
142
        if (layer instanceof FlyrVectIVectorLayer)
143
            storeLayer = ((FlyrVectIVectorLayer) layer).getFeatureStore();
144
        else
145
            return false;
146

    
147
        try {
148
            FeatureSet features = null;
149
            features = storeLayer.getFeatureSet();
150
            FeatureType featureType = features.getDefaultFeatureType();
151

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

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

    
192
                            operation.setTaskStatus(getStatus());
193
                            operation.computesGeometryOperation(storeLayer, outAuxFeatStore,
194
                                            attrNames, selectedGeom, true);
195

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

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

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

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

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

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

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

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

    
322

    
323
}