Statistics
| Revision:

gvsig-geoprocess / org.gvsig.geoprocess / trunk / org.gvsig.geoprocess / org.gvsig.geoprocess.lib / org.gvsig.geoprocess.lib.sextante / src / main / java / org / gvsig / geoprocess / lib / sextante / AbstractSextanteGeoProcess.java @ 1274

History | View | Annotate | Download (18.5 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.lib.sextante;
25

    
26
import java.io.File;
27
import java.util.HashMap;
28
import java.util.Iterator;
29

    
30
import org.gvsig.fmap.dal.DataTypes;
31
import org.gvsig.fmap.dal.exception.DataException;
32
import org.gvsig.fmap.dal.exception.ReadException;
33
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
34
import org.gvsig.fmap.dal.feature.FeatureQuery;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36
import org.gvsig.fmap.dal.feature.FeatureType;
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
41
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
42
import org.gvsig.fmap.geom.primitive.Envelope;
43
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsEnvelopeEvaluator;
44
import org.gvsig.geoprocess.lib.api.GeoProcess;
45
import org.gvsig.geoprocess.lib.api.GeoProcessLocator;
46
import org.gvsig.geoprocess.lib.api.GeoProcessManager;
47
import org.gvsig.geoprocess.lib.sextante.core.DefaultOutputFactory;
48
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
49

    
50
import es.unex.sextante.core.AnalysisExtent;
51
import es.unex.sextante.core.GeoAlgorithm;
52
import es.unex.sextante.core.ITaskMonitor;
53
import es.unex.sextante.core.OutputFactory;
54
import es.unex.sextante.core.OutputObjectsSet;
55
import es.unex.sextante.core.Sextante;
56
import es.unex.sextante.dataObjects.IRasterLayer;
57
import es.unex.sextante.dataObjects.IVectorLayer;
58
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
59
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
60
import es.unex.sextante.exceptions.WrongOutputIDException;
61
import es.unex.sextante.gui.algorithm.GeoAlgorithmParametersPanel;
62
import es.unex.sextante.outputs.IOutputChannel;
63
import es.unex.sextante.outputs.Output;
64
import java.util.ArrayList;
65
import java.util.List;
66
import org.gvsig.fmap.dal.feature.EditableFeatureType;
67
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
68
import org.gvsig.tools.evaluator.Evaluator;
69
import org.gvsig.tools.namestranslator.NamesTranslator;
70

    
71
/**
72
 * Base implementation for Sextante based {@link GeoProcess} objects.
73
 *
74
 * @author gvSIG Team
75
 * @version $Id$
76
 */
77
public abstract class AbstractSextanteGeoProcess extends GeoAlgorithm implements GeoProcess {
78

    
79
    protected String[] attrNames = null;
80
    private SimpleTaskStatusDelegated status = null;
81
    protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
82
    protected NamesTranslator namesTranslator = null;
83

    
84
    @Override
85
    public boolean execute(ITaskMonitor task, OutputFactory outputFactory,
86
            HashMap<String, String> outputMap)
87
            throws GeoAlgorithmExecutionException {
88
        status = new SimpleTaskStatusDelegated(m_Task, getGeoProcessName());
89
        status.add();
90
        boolean result = false;
91
        try {
92
            result = super.execute(task, outputFactory, outputMap);
93
        } finally {
94
            status.remove();
95
        }
96
        return result;
97
    }
98

    
99
    /**
100
     * This method creates a new raster layer and adds it to the set of output
101
     * objects of the algorithm. Use this when your algorithm generates a new
102
     * raster layer and you have to create it. The grid extent is taken from the
103
     * algorithm analysis extent (@see {@link #getAnalysisExtent()}
104
     *
105
     * @param sName The name of the layer. Has to be the same that you used to
106
     * define this output in the
107
     * @see {@link #defineCharacteristics()} method.
108
     * @param sDescription the long description of the output. This is the one
109
     * usually used to describe the layer when added to a GIS GUI
110
     * @param iDataType The data type. See
111
     * @see {@link IRasterLayer} for more info about valid values
112
     * @param iBands the number of bands of the new layer
113
     * @return a new raster layer
114
     * @throws UnsupportedOutputChannelException
115
     */
116
    protected IRasterLayer getNewRORasterLayer(final String sName,
117
            final String sDescription,
118
            final int iDataType,
119
            final int iBands) throws UnsupportedOutputChannelException {
120

    
121
        final IOutputChannel channel = getOutputChannel(sName);
122

    
123
        final IRasterLayer newLayer = ((DefaultOutputFactory) m_OutputFactory).getNewEmptyRORasterLayer(sName, iDataType,
124
                m_AnalysisExtent, iBands, channel, m_CRS);
125

    
126
        addOutputRasterLayer(sName, sDescription, iBands, channel, newLayer);
127

    
128
        return newLayer;
129

    
130
    }
131

    
132
    /**
133
     * Builds the output FeatureStore
134
     *
135
     * @param featureType
136
     * @return FeatureStore
137
     */
138
    protected FeatureStore buildOutPutStore(FeatureType featureType,
139
            int shapeType, String sextanteLayerName, String sextanteLayerLabel) {
140

    
141
//        Class<?>[] types = null;
142
//        if (featureType.getDefaultGeometryAttribute() != null) {
143
//            // Tiene campo GEOMETRY.
144
//            // Hay que quitarlo
145
//            attrNames = new String[featureType.size() - 1];
146
//            types = new Class[featureType.size() - 1];
147
//        } else {
148
//            attrNames = new String[featureType.size()];
149
//            types = new Class[featureType.size()];
150
//        }
151
        List<Class> types = new ArrayList();
152
        List<String> theAttrNames = new ArrayList();
153

    
154
        List<FeatureAttributeDescriptor> emulateds = new ArrayList();
155
        @SuppressWarnings("unchecked")
156
        Iterator<FeatureAttributeDescriptor> it = featureType.iterator();
157
        while (it.hasNext()) {
158
            FeatureAttributeDescriptor attribute = it.next();
159
            if (attribute.isComputed()) {
160
                emulateds.add(attribute);
161
            } else {
162
                String attrName = attribute.getName();
163
                if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
164
                    theAttrNames.add(attrName);
165
                    types.add(attribute.getObjectClass());
166
                }
167
            }
168
        }
169

    
170
        try {
171
            FlyrVectIVectorLayer output
172
                    = (FlyrVectIVectorLayer) getNewVectorLayer(
173
                            sextanteLayerLabel,
174
                            sextanteLayerName,
175
                            shapeType,
176
                            types.toArray(new Class[types.size()]),
177
                            theAttrNames.toArray(new String[theAttrNames.size()])
178
                    );
179
            if (output != null) {
180
                FeatureStore store = output.getFeatureStore();
181
                if (!emulateds.isEmpty()) {
182
                    try {
183
                        boolean needStartEditingMode = !(store.isEditing() || store.isAppending());
184
                        if (needStartEditingMode) {
185
                            store.edit();
186
                        }
187
                        EditableFeatureType ft = store.getDefaultFeatureType().getEditable();
188

    
189
                        for (FeatureAttributeDescriptor emulated : emulateds) {
190
                            theAttrNames.add(emulated.getName());
191
                            ft.add(emulated.getName(), emulated.getType(), emulated.getFeatureAttributeEmulator());
192
                        }
193
                        store.update(ft);
194
                        if (needStartEditingMode) {
195
                            store.finishEditing();
196
                        }
197

    
198
                    } catch (Exception e) {
199
                        Sextante.addErrorToLog(e);
200
                    }
201
                }
202
                this.attrNames = theAttrNames.toArray(new String[theAttrNames.size()]);
203
                return output.getFeatureStore();
204
            }
205
        } catch (UnsupportedOutputChannelException e) {
206
            Sextante.addErrorToLog(e);
207
        } catch (GeoAlgorithmExecutionException e) {
208
            Sextante.addErrorToLog(e);
209
        }
210
        return null;
211
    }
212

    
213
    /**
214
     * Builds the output FeatureStore
215
     *
216
     * @param featureType
217
     * @return FeatureStore
218
     */
219
    protected FeatureStore buildOutPutStoreFromUnion(FeatureType featureType1,
220
            FeatureType featureType2, int shapeType, String sextanteLayerName,
221
            String sextanteLayerLabel) {
222
        return buildOutPutStoreFromUnion(featureType1, featureType2, shapeType,
223
                sextanteLayerName, sextanteLayerLabel, null, null);
224
    }
225

    
226
    /**
227
     * Builds the output FeatureStore
228
     *
229
     * @param featureType
230
     * @return FeatureStore
231
     */
232
    protected FeatureStore buildOutPutStoreFromUnion(FeatureType featureType1,
233
            FeatureType featureType2, int shapeType, String sextanteLayerName,
234
            String sextanteLayerLabel, String newField, Class<?> newFieldType) {
235

    
236
        NamesTranslator myNamesTranslator = getNamesTranslator();
237

    
238
        int sizeAux = 0;
239
        if (newField != null && newFieldType != null) {
240
            sizeAux = 1;
241
        }
242

    
243
        Class<?>[] types = null;
244
        // Tiene campo GEOMETRY. Hay que quitarlo
245
        if (featureType1.getDefaultGeometryAttribute() != null) {
246
            attrNames
247
                    = new String[featureType1.size() + featureType2.size() - 2
248
                    + sizeAux];
249
            types
250
                    = new Class[featureType1.size() + featureType2.size() - 2
251
                    + sizeAux];
252
        } else {
253
            attrNames
254
                    = new String[featureType1.size() + featureType2.size() + sizeAux];
255
            types
256
                    = new Class[featureType1.size() + featureType2.size() + sizeAux];
257
        }
258

    
259
        int i = 0;
260
        @SuppressWarnings("unchecked")
261
        Iterator<FeatureAttributeDescriptor> it = featureType1.iterator();
262
        myNamesTranslator.clear();
263
        while (it.hasNext()) {
264
            FeatureAttributeDescriptor attribute
265
                    = (FeatureAttributeDescriptor) it.next();
266
            if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
267
                attrNames[i] = attribute.getName();
268
                myNamesTranslator.addSource(attribute.getName());
269
                types[i] = attribute.getObjectClass();
270
                i++;
271
            }
272
        }
273

    
274
        @SuppressWarnings("unchecked")
275
        Iterator<FeatureAttributeDescriptor> it2 = featureType2.iterator();
276
        while (it2.hasNext()) {
277
            FeatureAttributeDescriptor attribute = it2.next();
278
            if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
279
                String attrName
280
                        = checkAttrName(attribute.getName(), featureType1.size() - 1);
281
                attrNames[i] = attrName;
282
                myNamesTranslator.addSource(attribute.getName());
283
                types[i] = attribute.getObjectClass();
284
                i++;
285
            }
286
        }
287

    
288
        if (newField != null && newFieldType != null) {
289
            attrNames[attrNames.length - 1] = newField;
290
            myNamesTranslator.addSource(newField);
291
            types[types.length - 1] = newFieldType;
292
        }
293

    
294
        try {
295
            IVectorLayer output
296
                    = getNewVectorLayer(sextanteLayerLabel, sextanteLayerName,
297
                            shapeType, types, myNamesTranslator.getTranslatedNamesAsArray());
298
            if (output != null) {
299
                return ((FlyrVectIVectorLayer) output).getFeatureStore();
300
            }
301
        } catch (UnsupportedOutputChannelException e) {
302
            Sextante.addErrorToLog(e);
303
        } catch (GeoAlgorithmExecutionException e) {
304
            Sextante.addErrorToLog(e);
305
        }
306
        return null;
307
    }
308

    
309
    /**
310
     * Changes the attribute name if this name is in the list.
311
     *
312
     * @param name
313
     * @return
314
     */
315
    protected String checkAttrName(String name, int size) {
316
        return checkAttrName(name, size, attrNames);
317
    }
318

    
319
    /**
320
     * Gets the shape type of the selected feature store
321
     *
322
     * @param FeatureStore source
323
     * @return shape type
324
     * @throws ReadException
325
     */
326
    protected int getShapeType(FeatureStore storeLayer1) throws ReadException {
327
        FeatureType featureType;
328
        try {
329
            featureType = storeLayer1.getDefaultFeatureType();
330
        } catch (DataException e) {
331
            throw new ReadException(storeLayer1.getName(), e);
332
        }
333
        int indexGeom = featureType.getDefaultGeometryAttributeIndex();
334
        return featureType.getAttributeDescriptor(indexGeom).getGeomType()
335
                .getType();
336
    }
337

    
338
    /**
339
     * Returns true if it is a point layer
340
     *
341
     * @param store
342
     * @return
343
     * @throws ReadException
344
     */
345
    protected boolean isPoint(FeatureStore store) throws ReadException {
346
        return (getShapeType(store) == Geometry.TYPES.POINT || getShapeType(store) == Geometry.TYPES.MULTIPOINT);
347
    }
348

    
349
    /**
350
     * Returns true if it is a polygon layer
351
     *
352
     * @param store
353
     * @return
354
     * @throws ReadException
355
     */
356
    protected boolean isPolygon(FeatureStore store) throws ReadException {
357
        int type = getShapeType(store);
358
        return geomManager.isSubtype(Geometry.TYPES.SURFACE, type) || geomManager.isSubtype(Geometry.TYPES.MULTISURFACE, type);
359
    }
360

    
361
    /**
362
     * Returns true if it is a line layer
363
     *
364
     * @param store
365
     * @return
366
     * @throws ReadException
367
     */
368
    protected boolean isLine(FeatureStore store) throws ReadException {
369
        int type = getShapeType(store);
370
        return geomManager.isSubtype(Geometry.TYPES.CURVE, type) || geomManager.isSubtype(Geometry.TYPES.MULTICURVE, type);
371
    }
372

    
373
    /**
374
     * Returns true if it is a line layer
375
     *
376
     * @param store
377
     * @return
378
     * @throws ReadException
379
     */
380
    protected boolean isUndefined(FeatureStore store) throws ReadException {
381
        return (getShapeType(store) == Geometry.TYPES.GEOMETRY);
382
    }
383

    
384
    public String getGeoProcessName() {
385
        return getName();
386
    }
387

    
388
    @Override
389
    protected void setProgressText(String sText) {
390
        super.setProgressText(sText);
391
        getStatus().message(sText);
392
    }
393

    
394
    @Override
395
    public boolean setProgress(int iStep, int iTotalNumberOfSteps) {
396
        boolean cancelled = super.setProgress(iStep, iTotalNumberOfSteps);
397
        SimpleTaskStatusDelegated status = getStatus();
398
        status.setRangeOfValues(0, iTotalNumberOfSteps);
399
        status.setCurValue(iStep);
400
        if (cancelled || status.isCancelled()) {
401
            return true;
402
        }
403
        return false;
404
    }
405

    
406
    protected SimpleTaskStatusDelegated getStatus() {
407
        return status;
408
    }
409

    
410
    @Override
411
    public String getCommandLineName() {
412
        // Override sextante command line value, as it might be the same as
413
        // other sextante algorithms and some information is not shown as
414
        // expected.
415
        return "gvSIG-".concat(super.getCommandLineName());
416
    }
417

    
418
    /**
419
     * Returns the {@link GeoProcessManager}.
420
     *
421
     * @return the {@link GeoProcessManager}
422
     */
423
    public GeoProcessManager getGeoProcessManager() {
424
        return GeoProcessLocator.getGeoProcessManager();
425
    }
426

    
427
    /**
428
     * Returns the translation for a label depending on the current locale.
429
     *
430
     * @param label to translate
431
     * @return text in the current locale
432
     */
433
    protected String getTranslation(String label) {
434
        return getGeoProcessManager().getTranslation(label);
435
    }
436

    
437
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
438
        return null;
439
    }
440

    
441
    /**
442
     * Gets a feature query using the analysis bounding box
443
     *
444
     * @param e
445
     * @param store
446
     * @return
447
     * @throws CreateEnvelopeException
448
     * @throws DataException
449
     */
450
    public FeatureQuery getQueryFromAnalysisExtent(AnalysisExtent e, FeatureStore store) throws CreateEnvelopeException, DataException {
451
        Envelope analysisEnvelope = geomManager.createEnvelope(e.getXMin(), e.getYMin(), e.getXMax(), e.getYMax(), SUBTYPES.GEOM2D);
452
        FeatureQuery query = store.createFeatureQuery();
453
        Evaluator filter = SpatialEvaluatorsFactory.getInstance().intersects(
454
                analysisEnvelope,
455
                store.getDefaultFeatureType().getDefaultSRS(),
456
                store
457
        );
458
        query.setFilter(filter);
459
        return query;
460
    }
461

    
462
    /**
463
     * Returns true if exists the output file and false i
464
     *
465
     * @param resultLabel
466
     * @param type zero shape and one tif
467
     * @return
468
     */
469
    public boolean existsOutPutFile(String resultLabel, int type) {
470
        OutputObjectsSet ooSet = getOutputObjects();
471
        Output out;
472
        try {
473
            out = ooSet.getOutput(resultLabel);
474
        } catch (WrongOutputIDException e) {
475
            return false;
476
        }
477
        String s = out.getOutputChannel() != null ? out.getOutputChannel().getAsCommandLineParameter() : "";
478
        if (new File(s).exists()) {
479
            return true;
480
        }
481
        if (type == 0) {
482
            return (new File(s + ".shp").exists());
483
        }
484
        if (type == 1) {
485
            return (new File(s + ".tif").exists());
486
        }
487
        return false;
488
    }
489

    
490
    public String getOutPutFile(String resultLabel) {
491
        OutputObjectsSet ooSet = getOutputObjects();
492
        Output out;
493
        try {
494
            out = ooSet.getOutput(resultLabel);
495
        } catch (WrongOutputIDException e) {
496
            return null;
497
        }
498
        return out.getOutputChannel().getAsCommandLineParameter();
499
    }
500

    
501
    public ITaskMonitor getTaskMonitor() {
502
        return m_Task;
503
    }
504

    
505
    public void setTaskMonitor(ITaskMonitor task) {
506
        this.m_Task = task;
507
    }
508

    
509
    public NamesTranslator getNamesTranslator() {
510
        if (this.namesTranslator == null) {
511
            NamesTranslator dummy = NamesTranslator.createDummyTranslator();
512
            if( attrNames!=null ) {
513
                for (String attrName : attrNames) {
514
                    dummy.addSource(attrName);
515
                }
516
            }
517
            this.namesTranslator = dummy;
518
        }
519
        return this.namesTranslator;
520
    }
521
}