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

History | View | Annotate | Download (18.7 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<Integer> sizes = new ArrayList();
153
        List<String> theAttrNames = new ArrayList();
154

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

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

    
193
                        for (FeatureAttributeDescriptor emulated : emulateds) {
194
                            theAttrNames.add(emulated.getName());
195
                            ft.add(emulated.getName(), emulated.getType(), emulated.getFeatureAttributeEmulator());
196
                        }
197
                        store.update(ft);
198
                        if (needStartEditingMode) {
199
                            store.finishEditing();
200
                        }
201

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

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

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

    
240
        NamesTranslator myNamesTranslator = getNamesTranslator();
241

    
242
        int sizeAux = 0;
243
        if (newField != null && newFieldType != null) {
244
            sizeAux = 1;
245
        }
246

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

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

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

    
292
        if (newField != null && newFieldType != null) {
293
            attrNames[attrNames.length - 1] = newField;
294
            myNamesTranslator.addSource(newField);
295
            types[types.length - 1] = newFieldType;
296
        }
297

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

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

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

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

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

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

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

    
388
    public String getGeoProcessName() {
389
        return getName();
390
    }
391

    
392
    @Override
393
    protected void setProgressText(String sText) {
394
        super.setProgressText(sText);
395
        getStatus().message(sText);
396
    }
397

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

    
410
    protected SimpleTaskStatusDelegated getStatus() {
411
        return status;
412
    }
413

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

    
422
    /**
423
     * Returns the {@link GeoProcessManager}.
424
     *
425
     * @return the {@link GeoProcessManager}
426
     */
427
    public GeoProcessManager getGeoProcessManager() {
428
        return GeoProcessLocator.getGeoProcessManager();
429
    }
430

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

    
441
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
442
        return null;
443
    }
444

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

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

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

    
505
    public ITaskMonitor getTaskMonitor() {
506
        return m_Task;
507
    }
508

    
509
    public void setTaskMonitor(ITaskMonitor task) {
510
        this.m_Task = task;
511
    }
512

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