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 237 cordinyana
/**
2
 * gvSIG. Desktop Geographic Information System.
3 175 cordinyana
 *
4 245 cordinyana
 * Copyright (C) 2007-2012 gvSIG Association.
5 175 cordinyana
 *
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 237 cordinyana
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20 245 cordinyana
 *
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 175 cordinyana
 */
24
package org.gvsig.geoprocess.algorithm.buffer;
25
26 277 nbrodin
import java.io.File;
27
28 175 cordinyana
import javax.swing.JOptionPane;
29
30 277 nbrodin
import org.cresques.cts.IProjection;
31
import org.gvsig.fmap.dal.DALLocator;
32
import org.gvsig.fmap.dal.DataManager;
33 278 nbrodin
import org.gvsig.fmap.dal.DataStoreParameters;
34 277 nbrodin
import org.gvsig.fmap.dal.DataTypes;
35 271 nbrodin
import org.gvsig.fmap.dal.exception.DataException;
36 278 nbrodin
import org.gvsig.fmap.dal.exception.InitializeException;
37
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
38 277 nbrodin
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
39
import org.gvsig.fmap.dal.feature.EditableFeatureType;
40 271 nbrodin
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43 277 nbrodin
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 332 nbrodin
import org.gvsig.geoprocess.lib.api.GeoProcessLocator;
49 271 nbrodin
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
50
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
51 278 nbrodin
import org.hsqldb.Types;
52 271 nbrodin
53 175 cordinyana
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 332 nbrodin
import es.unex.sextante.gui.algorithm.GeoAlgorithmParametersPanel;
62 175 cordinyana
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 191 cordinyana
 * @author gvSIG Team
73 175 cordinyana
 */
74 191 cordinyana
public class BufferAlgorithm extends AbstractSextanteGeoProcess {
75
76 244 cordinyana
    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 332 nbrodin
    public static String[] sOptions = {
86
            GeoProcessLocator.getGeoProcessManager().getTranslation("poly_out"),
87
            GeoProcessLocator.getGeoProcessManager().getTranslation("poly_in"),
88
            GeoProcessLocator.getGeoProcessManager().getTranslation("poly_inandout")
89
            };
90 244 cordinyana
91
    public void defineCharacteristics() {
92
        setName(getTranslation("Buffer"));
93
        setGroup(getTranslation("basic_vect_algorithms"));
94 175 cordinyana
        // setGeneratesUserDefinedRasterOutput(false);
95 332 nbrodin
96 244 cordinyana
        try {
97 272 nbrodin
            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 244 cordinyana
                AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE);
102 264 nbrodin
            m_Parameters.addTableField(FIELD, getTranslation("area_field"), "LAYER");
103 272 nbrodin
            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 244 cordinyana
                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 175 cordinyana
119 244 cordinyana
    public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
120 271 nbrodin
121
            if(existsOutPutFile(BufferAlgorithm.RESULT, 0)) {
122
                    throw new GeoAlgorithmExecutionException(getTranslation("file_exists"));
123
            }
124
125 244 cordinyana
        IVectorLayer layer = m_Parameters.getParameterValueAsVectorLayer(LAYER);
126 264 nbrodin
        boolean selectedGeom = m_Parameters.getParameter(SELECTED_GEOM).getParameterValueAsBoolean();
127
        double dist = m_Parameters.getParameter(DISTANCE).getParameterValueAsDouble();
128 244 cordinyana
        int attributePosition = m_Parameters.getParameterValueAsInt(FIELD);
129
        // boolean dissolve =
130
        // m_Parameters.getParameter(DISSOLVE).getParameterValueAsBoolean();
131 264 nbrodin
        boolean round_border = m_Parameters.getParameter(ROUND_BORDER).getParameterValueAsBoolean();
132 244 cordinyana
        int inflArea = m_Parameters.getParameterValueAsInt(AREA);
133
        int rings = m_Parameters.getParameterValueAsInt(RING_NUMBER);
134 277 nbrodin
        boolean dissolve = m_Parameters.getParameter(DISSOLVE).getParameterValueAsBoolean();
135 175 cordinyana
136 244 cordinyana
        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 175 cordinyana
144 244 cordinyana
        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 289 nbrodin
                operation = new OutBufferOperation(distance, layer, dist, this);
167 244 cordinyana
                break;
168
            case 1:
169 289 nbrodin
                operation = new InBufferOperation(distance, layer, dist, this);
170 244 cordinyana
                break;
171
            case 2:
172 289 nbrodin
                operation = new InOutBufferOperation(distance, layer, dist, this);
173 244 cordinyana
                break;
174
            }
175
            operation.setTypeOfCap(round_border ? BufferOperation.CAP_ROUND
176
                : BufferOperation.CAP_SQUARE);
177
            operation.setNumberOfRadialBuffers(rings + 1);
178 288 nbrodin
            operation.setGeoProcess(this, 100);
179
180 277 nbrodin
                // 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 290 nbrodin
187
            if(dissolve && rings == 0) { //solo se disuelve si hay un anillo
188 277 nbrodin
                    FeatureStore outAuxFeatStore = null;
189
                    try {
190 278 nbrodin
                            String file = System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis() + ".shp";
191 277 nbrodin
                            outAuxFeatStore = buildTemporalStore(featureType,
192 278 nbrodin
                                            org.gvsig.fmap.geom.Geometry.TYPES.SURFACE, file, inflArea,
193
                                            storeLayer.getDefaultFeatureType().getDefaultSRS());
194 244 cordinyana
195 277 nbrodin
                            operation.setTaskStatus(getStatus());
196
                            operation.computesGeometryOperation(storeLayer, outAuxFeatStore,
197
                                            attrNames, selectedGeom, true);
198
199 278 nbrodin
                            outAuxFeatStore = open(file, storeLayer.getDefaultFeatureType().getDefaultSRS());
200 277 nbrodin
                            FuseSpatiallyAlgorithm alg = new FuseSpatiallyAlgorithm();
201 288 nbrodin
                            alg.setTaskMonitor(m_Task);
202
                            alg.setParentProcess(this);
203
                            m_Task.setProgressText(getTranslation("fuse_spatially"));
204 278 nbrodin
                            alg.execute(outAuxFeatStore, outFeatStore, IVectorLayer.SHAPE_TYPE_POLYGON,
205
                                            false, getStatus(), "FID", false);
206 277 nbrodin
                    } catch (ValidateDataParametersException e) {
207
                            Sextante.addErrorToLog(e);
208
                    }
209 290 nbrodin
            } else {
210
                    // Computes the operation
211
                    operation.setTaskStatus(getStatus());
212
                    operation.computesGeometryOperation(storeLayer, outFeatStore,
213
                                    attrNames, selectedGeom, true);
214
            }
215 244 cordinyana
        } catch (DataException e) {
216
            Sextante.addErrorToLog(e);
217
            return false;
218
        }
219 321 nbrodin
220
                if(getTaskMonitor().isCanceled())
221
                        return false;
222 175 cordinyana
223 244 cordinyana
        return true;
224
    }
225 278 nbrodin
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 244 cordinyana
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 175 cordinyana
        } catch (GeoAlgorithmExecutionException e) {
262
            Sextante.addErrorToLog(e);
263
        }
264 244 cordinyana
        return null;
265
    }
266 277 nbrodin
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 278 nbrodin
        int shapeType, String file,
277 277 nbrodin
        int infArea, IProjection crs) throws DataException, ValidateDataParametersException {
278 175 cordinyana
279 277 nbrodin
        int[] types = null;
280
        if (infArea == 2) {
281 278 nbrodin
            types = new int[] { Types.INTEGER, Types.DOUBLE, Types.DOUBLE };
282 277 nbrodin
            attrNames = new String[] { "FID", "FROM", "TO" };
283
        } else {
284 278 nbrodin
            types = new int[] { Types.INTEGER, Types.DOUBLE };
285 277 nbrodin
            attrNames = new String[] { "FID", "DIST" };
286
        }
287
288 278 nbrodin
        return create(file, types, attrNames, crs);
289 277 nbrodin
    }
290
291 290 nbrodin
        @SuppressWarnings("deprecation")
292 277 nbrodin
        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 278 nbrodin
                                ft.add(attrNames[i], types[i], 7);
305 277 nbrodin
                        }
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 332 nbrodin
    @Override
327
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
328
        return BufferParametersPanel.class;
329
    }
330 175 cordinyana
}