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

History | View | Annotate | Download (19.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.math.BigDecimal;
65
import java.util.ArrayList;
66
import java.util.List;
67
import org.apache.commons.collections4.CollectionUtils;
68
import org.apache.commons.lang3.ArrayUtils;
69
import org.gvsig.fmap.dal.feature.EditableFeatureType;
70
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
71
import org.gvsig.tools.evaluator.Evaluator;
72
import org.gvsig.tools.namestranslator.NamesTranslator;
73

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

    
82
    protected String[] attrNames = null; //targetAttrNames
83
    private SimpleTaskStatusDelegated status = null;
84
    protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
85
    protected NamesTranslator namesTranslator = null;
86

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

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

    
124
        final IOutputChannel channel = getOutputChannel(sName);
125

    
126
        final IRasterLayer newLayer = ((DefaultOutputFactory) m_OutputFactory).getNewEmptyRORasterLayer(sName, iDataType,
127
                m_AnalysisExtent, iBands, channel, m_CRS);
128

    
129
        addOutputRasterLayer(sName, sDescription, iBands, channel, newLayer);
130

    
131
        return newLayer;
132

    
133
    }
134

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

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

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

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

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

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

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

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

    
243
        NamesTranslator myNamesTranslator = getNamesTranslator();
244

    
245
        int sizeAux = 0;
246
        if (newField != null && newFieldType != null) {
247
            sizeAux = 1;
248
        }
249

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

    
266
        int i = 0;
267
        @SuppressWarnings("unchecked")
268
        Iterator<FeatureAttributeDescriptor> it = featureType1.iterator();
269
        myNamesTranslator.clear();
270
        List<Integer> sizes = new ArrayList();
271
        while (it.hasNext()) {
272
            FeatureAttributeDescriptor attribute
273
                    = (FeatureAttributeDescriptor) it.next();
274
            if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
275
                attrNames[i] = attribute.getName();
276
                myNamesTranslator.addSource(attribute.getName());
277
                types[i] = attribute.getObjectClass();
278
                int size = attribute.getSize();
279
                if (attribute.getObjectClass().equals(BigDecimal.class)) {
280
                    size = attribute.getPrecision();
281
                }
282
                sizes.add(size);
283
                i++;
284
            }
285
        }
286

    
287
        @SuppressWarnings("unchecked")
288
        Iterator<FeatureAttributeDescriptor> it2 = featureType2.iterator();
289
        while (it2.hasNext()) {
290
            FeatureAttributeDescriptor attribute = it2.next();
291
            if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
292
                String attrName
293
                        = checkAttrName(attribute.getName(), featureType1.size() - 1);
294
                attrNames[i] = attrName;
295
                myNamesTranslator.addSource(attribute.getName());
296
                types[i] = attribute.getObjectClass();
297
                int size = attribute.getSize();
298
                if (attribute.getObjectClass().equals(BigDecimal.class)) {
299
                    size = attribute.getPrecision();
300
                }
301
                sizes.add(size);
302
                i++;
303
            }
304
        }
305

    
306
        if (newField != null && newFieldType != null) {
307
            attrNames[attrNames.length - 1] = newField;
308
            myNamesTranslator.addSource(newField);
309
            types[types.length - 1] = newFieldType;
310
            sizes.add(0);
311
        }
312
        
313
        int[] arrayOfSizes = sizes.stream().mapToInt(ii->ii).toArray();
314

    
315
        try {
316
            IVectorLayer output
317
                    = getNewVectorLayer(sextanteLayerLabel, sextanteLayerName,
318
                            shapeType, types, myNamesTranslator.getTranslatedNamesAsArray(), arrayOfSizes);
319
            if (output != null) {
320
                return ((FlyrVectIVectorLayer) output).getFeatureStore();
321
            }
322
        } catch (UnsupportedOutputChannelException e) {
323
            Sextante.addErrorToLog(e);
324
        } catch (GeoAlgorithmExecutionException e) {
325
            Sextante.addErrorToLog(e);
326
        }
327
        return null;
328
    }
329

    
330
    /**
331
     * Changes the attribute name if this name is in the list.
332
     *
333
     * @param name
334
     * @return
335
     */
336
    protected String checkAttrName(String name, int size) {
337
        return checkAttrName(name, size, attrNames);
338
    }
339

    
340
    /**
341
     * Gets the shape type of the selected feature store
342
     *
343
     * @param FeatureStore source
344
     * @return shape type
345
     * @throws ReadException
346
     */
347
    protected int getShapeType(FeatureStore storeLayer1) throws ReadException {
348
        FeatureType featureType;
349
        try {
350
            featureType = storeLayer1.getDefaultFeatureType();
351
        } catch (DataException e) {
352
            throw new ReadException(storeLayer1.getName(), e);
353
        }
354
        int indexGeom = featureType.getDefaultGeometryAttributeIndex();
355
        return featureType.getAttributeDescriptor(indexGeom).getGeomType()
356
                .getType();
357
    }
358

    
359
    /**
360
     * Returns true if it is a point layer
361
     *
362
     * @param store
363
     * @return
364
     * @throws ReadException
365
     */
366
    protected boolean isPoint(FeatureStore store) throws ReadException {
367
        return (getShapeType(store) == Geometry.TYPES.POINT || getShapeType(store) == Geometry.TYPES.MULTIPOINT);
368
    }
369

    
370
    /**
371
     * Returns true if it is a polygon layer
372
     *
373
     * @param store
374
     * @return
375
     * @throws ReadException
376
     */
377
    protected boolean isPolygon(FeatureStore store) throws ReadException {
378
        int type = getShapeType(store);
379
        return geomManager.isSubtype(Geometry.TYPES.SURFACE, type) || geomManager.isSubtype(Geometry.TYPES.MULTISURFACE, type);
380
    }
381

    
382
    /**
383
     * Returns true if it is a line layer
384
     *
385
     * @param store
386
     * @return
387
     * @throws ReadException
388
     */
389
    protected boolean isLine(FeatureStore store) throws ReadException {
390
        int type = getShapeType(store);
391
        return geomManager.isSubtype(Geometry.TYPES.CURVE, type) || geomManager.isSubtype(Geometry.TYPES.MULTICURVE, type);
392
    }
393

    
394
    /**
395
     * Returns true if it is a line layer
396
     *
397
     * @param store
398
     * @return
399
     * @throws ReadException
400
     */
401
    protected boolean isUndefined(FeatureStore store) throws ReadException {
402
        return (getShapeType(store) == Geometry.TYPES.GEOMETRY);
403
    }
404

    
405
    public String getGeoProcessName() {
406
        return getName();
407
    }
408

    
409
    @Override
410
    protected void setProgressText(String sText) {
411
        super.setProgressText(sText);
412
        getStatus().message(sText);
413
    }
414

    
415
    @Override
416
    public boolean setProgress(int iStep, int iTotalNumberOfSteps) {
417
        boolean cancelled = super.setProgress(iStep, iTotalNumberOfSteps);
418
        SimpleTaskStatusDelegated status = getStatus();
419
        status.setRangeOfValues(0, iTotalNumberOfSteps);
420
        status.setCurValue(iStep);
421
        if (cancelled || status.isCancelled()) {
422
            return true;
423
        }
424
        return false;
425
    }
426

    
427
    protected SimpleTaskStatusDelegated getStatus() {
428
        return status;
429
    }
430

    
431
    @Override
432
    public String getCommandLineName() {
433
        // Override sextante command line value, as it might be the same as
434
        // other sextante algorithms and some information is not shown as
435
        // expected.
436
        return "gvSIG-".concat(super.getCommandLineName());
437
    }
438

    
439
    /**
440
     * Returns the {@link GeoProcessManager}.
441
     *
442
     * @return the {@link GeoProcessManager}
443
     */
444
    public GeoProcessManager getGeoProcessManager() {
445
        return GeoProcessLocator.getGeoProcessManager();
446
    }
447

    
448
    /**
449
     * Returns the translation for a label depending on the current locale.
450
     *
451
     * @param label to translate
452
     * @return text in the current locale
453
     */
454
    protected String getTranslation(String label) {
455
        return getGeoProcessManager().getTranslation(label);
456
    }
457

    
458
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
459
        return null;
460
    }
461

    
462
    /**
463
     * Gets a feature query using the analysis bounding box
464
     *
465
     * @param e
466
     * @param store
467
     * @return
468
     * @throws CreateEnvelopeException
469
     * @throws DataException
470
     */
471
    public FeatureQuery getQueryFromAnalysisExtent(AnalysisExtent e, FeatureStore store) throws CreateEnvelopeException, DataException {
472
        Envelope analysisEnvelope = geomManager.createEnvelope(e.getXMin(), e.getYMin(), e.getXMax(), e.getYMax(), SUBTYPES.GEOM2D);
473
        FeatureQuery query = store.createFeatureQuery();
474
        Evaluator filter = SpatialEvaluatorsFactory.getInstance().intersects(
475
                analysisEnvelope,
476
                store.getDefaultFeatureType().getDefaultSRS(),
477
                store
478
        );
479
        query.setFilter(filter);
480
        return query;
481
    }
482

    
483
    /**
484
     * Returns true if exists the output file and false i
485
     *
486
     * @param resultLabel
487
     * @param type zero shape and one tif
488
     * @return
489
     */
490
    public boolean existsOutPutFile(String resultLabel, int type) {
491
        OutputObjectsSet ooSet = getOutputObjects();
492
        Output out;
493
        try {
494
            out = ooSet.getOutput(resultLabel);
495
        } catch (WrongOutputIDException e) {
496
            return false;
497
        }
498
        String s = out.getOutputChannel() != null ? out.getOutputChannel().getAsCommandLineParameter() : "";
499
        if (new File(s).exists()) {
500
            return true;
501
        }
502
        if (type == 0) {
503
            return (new File(s + ".shp").exists());
504
        }
505
        if (type == 1) {
506
            return (new File(s + ".tif").exists());
507
        }
508
        return false;
509
    }
510

    
511
    public String getOutPutFile(String resultLabel) {
512
        OutputObjectsSet ooSet = getOutputObjects();
513
        Output out;
514
        try {
515
            out = ooSet.getOutput(resultLabel);
516
        } catch (WrongOutputIDException e) {
517
            return null;
518
        }
519
        return out.getOutputChannel().getAsCommandLineParameter();
520
    }
521

    
522
    public ITaskMonitor getTaskMonitor() {
523
        return m_Task;
524
    }
525

    
526
    public void setTaskMonitor(ITaskMonitor task) {
527
        this.m_Task = task;
528
    }
529

    
530
    public NamesTranslator getNamesTranslator() {
531
        if (this.namesTranslator == null) {
532
            NamesTranslator dummy = NamesTranslator.createDummyTranslator();
533
            if( attrNames!=null ) {
534
                for (String attrName : attrNames) {
535
                    dummy.addSource(attrName);
536
                }
537
            }
538
            this.namesTranslator = dummy;
539
        }
540
        return this.namesTranslator;
541
    }
542
}