Statistics
| Revision:

gvsig-geoprocess / org.gvsig.geoprocess / trunk / org.gvsig.geoprocess / org.gvsig.geoprocess.algorithm / org.gvsig.geoprocess.algorithm.spatialjoin / src / main / java / org / gvsig / geoprocess / algorithm / spatialjoin / SpatialJoinAlgorithm.java @ 1259

History | View | Annotate | Download (12.4 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.spatialjoin;
25

    
26
import java.util.ArrayList;
27
import java.util.HashMap;
28
import java.util.Iterator;
29

    
30
import es.unex.sextante.core.Sextante;
31
import es.unex.sextante.dataObjects.IVectorLayer;
32
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
33
import es.unex.sextante.exceptions.RepeatedParameterNameException;
34
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
35
import es.unex.sextante.gui.algorithm.GeoAlgorithmParametersPanel;
36
import es.unex.sextante.outputs.OutputVectorLayer;
37

    
38
import org.gvsig.fmap.dal.DALLocator;
39
import org.gvsig.fmap.dal.DataManager;
40
import org.gvsig.fmap.dal.DataTypes;
41
import org.gvsig.fmap.dal.feature.Feature;
42
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
43
import org.gvsig.fmap.dal.feature.FeatureReference;
44
import org.gvsig.fmap.dal.feature.FeatureStore;
45
import org.gvsig.fmap.dal.feature.FeatureType;
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.fmap.geom.GeometryLocator;
48
import org.gvsig.fmap.geom.GeometryManager;
49
import org.gvsig.fmap.geom.SpatialIndex;
50
import org.gvsig.fmap.geom.SpatialIndexFactory;
51
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
52
import org.gvsig.geoprocess.algorithm.dissolve.DissolveRule;
53
import org.gvsig.geoprocess.algorithm.dissolve.IDissolveRule;
54
import org.gvsig.geoprocess.algorithm.dissolve.Summary;
55
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
56
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
57
import org.gvsig.tools.dynobject.DynObject;
58
import org.gvsig.tools.exception.BaseException;
59
import org.gvsig.tools.namestranslator.NamesTranslator;
60
import org.gvsig.tools.visitor.VisitCanceledException;
61
import org.gvsig.tools.visitor.Visitor;
62

    
63
/**
64
 * Spatial join algorithm
65
 *
66
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
67
 */
68
public class SpatialJoinAlgorithm extends AbstractSextanteGeoProcess {
69

    
70
    public static final String NEW_FIELD = "NUM_RELA";
71
    public static final String RESULT = "RESULT";
72
    public static final String LAYER1 = "LAYER1";
73
    public static final String LAYER2 = "LAYER2";
74
    public static final String SELECTGEOM_INPUT = "SELECTGEOM_INPUT";
75
    public static final String SELECTGEOM_OVERLAY = "SELECTGEOM_OVERLAY";
76
    public static final String NEAREST = "NEAREST";
77
    public static final String FUNCTION_LIST = "FUNCTION_LIST";
78
    public static final String Summary[] = {"Min", "Max", "Sum", "Avg"};
79
    private boolean funcList[] = new boolean[Summary.length];
80
    private HashMap<String, String> funcMap = new HashMap<String, String>();
81
    public NamesTranslator namesTranslator;
82

    
83
    public void defineCharacteristics() {
84
        setName(getTranslation("Spatialjoin"));
85
        setGroup(getTranslation("basic_vect_algorithms"));
86
        // setGeneratesUserDefinedRasterOutput(false);
87

    
88
        try {
89
            m_Parameters.addInputVectorLayer(LAYER1,
90
                    getTranslation("Input_layer"),
91
                    IVectorLayer.SHAPE_TYPE_WRONG,
92
                    true);
93
            m_Parameters.addInputVectorLayer(LAYER2,
94
                    getTranslation("Input_layer"),
95
                    IVectorLayer.SHAPE_TYPE_WRONG,
96
                    true);
97
            m_Parameters.addBoolean(SELECTGEOM_INPUT,
98
                    getTranslation("Selected_geometries_input_layer"), false);
99
            m_Parameters.addBoolean(SELECTGEOM_OVERLAY,
100
                    getTranslation("Selected_geometries_overlay_layer"), false);
101
            m_Parameters.addBoolean(NEAREST, getTranslation("use_the_nearest"), false);
102
            m_Parameters.addString(FUNCTION_LIST,
103
                    getTranslation("Function_list"));
104
        } catch (RepeatedParameterNameException e) {
105
            Sextante.addErrorToLog(e);
106
        }
107
        addOutputVectorLayer(RESULT, getTranslation("Spatialjoin"),
108
                OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
109
    }
110

    
111
    public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
112
        if (existsOutPutFile(SpatialJoinAlgorithm.RESULT, 0)) {
113
            throw new GeoAlgorithmExecutionException(getTranslation("file_exists"));
114
        }
115
        IVectorLayer layer1 = m_Parameters.getParameterValueAsVectorLayer(LAYER1); //Capa de entrada
116
        IVectorLayer layer2 = m_Parameters.getParameterValueAsVectorLayer(LAYER2); //Capa de revestimiento
117
        boolean selectedGeomInput = m_Parameters.getParameter(SELECTGEOM_INPUT).getParameterValueAsBoolean();
118
        boolean selectedGeomOverlay = m_Parameters.getParameter(SELECTGEOM_OVERLAY).getParameterValueAsBoolean();
119
        boolean nearest = m_Parameters.getParameterValueAsBoolean(NEAREST);
120
        String functionList = m_Parameters.getParameterValueAsString(FUNCTION_LIST);
121
        loadSummary(functionList);
122

    
123
        FlyrVectIVectorLayer inputLayer = null;
124
        FlyrVectIVectorLayer overlayLayer = null;
125
                if(layer2 instanceof FlyrVectIVectorLayer && layer1 instanceof FlyrVectIVectorLayer) {
126
                        overlayLayer = ((FlyrVectIVectorLayer)layer2); //Capa de revestimiento
127
                        inputLayer = ((FlyrVectIVectorLayer)layer1); //Capa de entrada
128
                } else
129
            return false;
130

    
131
        DataManager dataManager = DALLocator.getDataManager();
132

    
133
        //Builds the output and computes the operation
134
        try {
135
            FeatureType featureTypeInputLayer = inputLayer.getFeatureStore().getDefaultFeatureType(); //Capa de entrada
136
            FeatureType featureTypeOverlayLayer = overlayLayer.getFeatureStore().getDefaultFeatureType(); //Capa de revestimiento
137

    
138
            GeometryOperation operation = null;
139
            FeatureStore outFeatStore = null;
140
            this.namesTranslator = NamesTranslator.createTrimTranslator(10);
141

    
142
            if (nearest) {
143
                outFeatStore =
144
                    buildOutPutStoreFromUnion(featureTypeInputLayer, featureTypeOverlayLayer,
145
                                inputLayer.getShapeType(), getTranslation("SpatialJoin"),
146
                                RESULT, "DIST", Double.class, namesTranslator);
147

    
148
                operation =
149
                    new SpatiallyIndexedSpatialJoinOperation(overlayLayer, createIndex(overlayLayer.getFeatureStore(), selectedGeomOverlay), this);
150
            } else {
151
                outFeatStore =
152
                    buildSpatialJoinOutPutStore(featureTypeInputLayer,
153
                                inputLayer.getShapeType(), getTranslation("SpatialJoin"),
154
                                RESULT);
155
                IDissolveRule rule = new DissolveRule(featureTypeInputLayer.getAttributeName(0), funcMap);
156
                
157
                Summary summary
158
                        = new Summary(rule, outFeatStore.getDefaultFeatureType());
159
                operation
160
                        = new IntersectsSpatialJoinOperation(overlayLayer,
161
                                createIndex(overlayLayer.getFeatureStore(), selectedGeomOverlay), summary, this);
162
            }
163

    
164
            operation.setTaskStatus(getStatus());
165
            operation.computesGeometryOperation(inputLayer.getFeatureStore(),
166
                    outFeatStore,
167
                    attrNames,
168
                    selectedGeomInput,
169
                    selectedGeomOverlay,
170
                    true);
171
        } catch (Exception e) {
172
            Sextante.addErrorToLog(e);
173
        }
174

    
175
        return true;
176
    }
177

    
178
    private SpatialIndex createIndex(FeatureStore store, boolean selectionOnly) throws BaseException {
179
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
180

    
181
        SpatialIndexFactory factory = geomManager.getSpatialIndexFactory(geomManager.SPATIALINDEX_DEFAULT_RTREE);
182
        DynObject parameters = factory.createParameters();
183

    
184
        SpatialIndex index = (SpatialIndex) factory.create(parameters, geomManager);
185
        final SpatialIndex wrappedIndex = store.wrapSpatialIndex(index);
186

    
187
        Visitor visitor = new Visitor() {
188

    
189
            @Override
190
            public void visit(Object obj) throws VisitCanceledException, BaseException {
191
                Feature f = (Feature) obj;
192
                Geometry g = f.getDefaultGeometry();
193
                FeatureReference ref = f.getReference();
194
                wrappedIndex.insert(g, ref);
195
            }
196
        };
197
        if (selectionOnly) {
198
            store.getFeatureSelection().accept(visitor);
199
        } else {
200
            store.accept(visitor);
201
        }
202

    
203
        return wrappedIndex;
204
    }
205

    
206
    /**
207
     * Checks if the parameter is in Summary list
208
     *
209
     * @param it
210
     * @return the position in the list
211
     */
212
    private int isInList(String it) {
213
        for (int i = 0; i < Summary.length; i++) {
214
            if (Summary[i].compareTo(it) == 0) {
215
                return i;
216
            }
217
        }
218
        return -1;
219
    }
220

    
221
    /**
222
     * Loads the list of functions to use
223
     *
224
     * @param functionList
225
     */
226
    private void loadSummary(String functionList) {
227
        String[] attrList = functionList.split(";");
228
        for (int i = 0; i < attrList.length; i++) {
229
            String[] func = attrList[i].split(",");
230
            for (int j = 1; j < func.length; j++) {
231
                int pos = isInList(func[j]);
232
                if (pos != -1) {
233
                    funcList[pos] = true;
234
                    funcMap.put(Summary[pos], func[0]);
235
                }
236
            }
237
        }
238
    }
239

    
240
    /**
241
     * Builds the output FeatureStore
242
     *
243
     * @param featureType
244
     * @return FeatureStore
245
     */
246
    protected FeatureStore buildSpatialJoinOutPutStore(FeatureType featureType1,
247
            int shapeType,
248
            String sextanteLayerName,
249
            String sextanteLayerLabel) {
250
        ArrayList<Class> typesList = new ArrayList<Class>();
251
        ArrayList<String> attr = new ArrayList<String>();
252

    
253
        Iterator it = featureType1.iterator();
254
        while (it.hasNext()) {
255
            FeatureAttributeDescriptor attribute = (FeatureAttributeDescriptor) it.next();
256
            if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
257
                attr.add(attribute.getName());
258
                typesList.add(attribute.getObjectClass());
259
            }
260
        }
261

    
262
        for (int i = 0; i < funcList.length; i++) {
263
            if (funcList[i]) {
264
                String fieldName = funcMap.get(Summary[i]);
265
                if (fieldName.length() >= 6) {
266
                    fieldName = fieldName.substring(0, 7);
267
                }
268
                attr.add(fieldName + "_" + Summary[i]);
269
                typesList.add(Double.class);
270
            }
271
        }
272

    
273
        attr.add(NEW_FIELD);
274
        typesList.add(Integer.class);
275

    
276
        attrNames = new String[attr.size()];
277
        attr.toArray(attrNames);
278
        Class[] types = new Class[typesList.size()];
279
        typesList.toArray(types);
280

    
281
        try {
282
            IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
283
                    sextanteLayerName,
284
                    shapeType, types, attrNames);
285
            return ((FlyrVectIVectorLayer) output).getFeatureStore();
286
        } catch (UnsupportedOutputChannelException e) {
287
            Sextante.addErrorToLog(e);
288
        } catch (GeoAlgorithmExecutionException e) {
289
            Sextante.addErrorToLog(e);
290
        }
291
        return null;
292
    }
293

    
294
    @Override
295
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
296
        return SpatialJoinParametersPanel.class;
297
    }
298
}