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

History | View | Annotate | Download (11.3 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.visitor.VisitCanceledException;
60
import org.gvsig.tools.visitor.Visitor;
61

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

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

    
80
        public void defineCharacteristics(){
81
        setName(getTranslation("Spatialjoin"));
82
        setGroup(getTranslation("basic_vect_algorithms"));
83
        // setGeneratesUserDefinedRasterOutput(false);
84

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

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

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

    
128
                DataManager dataManager = DALLocator.getDataManager();
129

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

    
135
                        GeometryOperation operation = null;
136
                        FeatureStore outFeatStore = null;
137

    
138
            if (nearest) {
139
                outFeatStore =
140
                    buildOutPutStoreFromUnion(featureTypeInputLayer, featureTypeOverlayLayer,
141
                        inputLayer.getShapeType(), getTranslation("SpatialJoin"),
142
                        RESULT, "DIST", Double.class);
143

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

    
159
            operation.setTaskStatus(getStatus());
160
                        operation.computesGeometryOperation(inputLayer.getFeatureStore(),
161
                                        outFeatStore,
162
                                        attrNames,
163
                                        selectedGeomInput,
164
                                        selectedGeomOverlay,
165
                                        true);
166
                } catch (Exception e) {
167
                        Sextante.addErrorToLog(e);
168
        }
169

    
170
                return true;
171
        }
172

    
173
        private SpatialIndex createIndex(FeatureStore store, boolean selectionOnly) throws BaseException{
174
            GeometryManager geomManager = GeometryLocator.getGeometryManager();
175

    
176
            SpatialIndexFactory factory = geomManager.getSpatialIndexFactory(geomManager.SPATIALINDEX_DEFAULT_RTREE);
177
            DynObject parameters = factory.createParameters();
178

    
179
            SpatialIndex index = (SpatialIndex) factory.create(parameters, geomManager);
180
            final SpatialIndex wrappedIndex = store.wrapSpatialIndex(index);
181

    
182
            Visitor visitor = new Visitor() {
183

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

    
198
            return wrappedIndex;
199
        }
200

    
201
        /**
202
         * Checks if the parameter is in Summary list
203
         * @param it
204
         * @return the position in the list
205
         */
206
        private int isInList(String it) {
207
                for (int i = 0; i < Summary.length; i++) {
208
                        if(Summary[i].compareTo(it) == 0)
209
                                return i;
210
                }
211
                return -1;
212
        }
213

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

    
232
        /**
233
         * Builds the output FeatureStore
234
         * @param featureType
235
         * @return FeatureStore
236
         */
237
        protected FeatureStore buildSpatialJoinOutPutStore(FeatureType featureType1,
238
                                                                                        int shapeType,
239
                                                                                        String sextanteLayerName,
240
                                                                                        String sextanteLayerLabel) {
241
                ArrayList<Class> typesList = new ArrayList<Class>();
242
                ArrayList<String> attr = new ArrayList<String>();
243

    
244
                Iterator it = featureType1.iterator();
245
                while( it.hasNext() ) {
246
                        FeatureAttributeDescriptor attribute = (FeatureAttributeDescriptor)it.next();
247
                        if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
248
                                attr.add(attribute.getName());
249
                                typesList.add(attribute.getObjectClass());
250
                        }
251
                }
252

    
253
                for (int i = 0; i < funcList.length; i++) {
254
                        if(funcList[i]) {
255
                                String fieldName = funcMap.get(Summary[i]);
256
                                if(fieldName.length() >= 6)
257
                                        fieldName = fieldName.substring(0, 7);
258
                                attr.add(fieldName + "_" + Summary[i]);
259
                                typesList.add(Double.class);
260
                        }
261
                }
262

    
263
                attr.add(NEW_FIELD);
264
                typesList.add(Integer.class);
265

    
266
                attrNames = new String[attr.size()];
267
                attr.toArray(attrNames);
268
                Class[] types = new Class[typesList.size()];
269
                typesList.toArray(types);
270

    
271
                try {
272
                        IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
273
                                                                                                        sextanteLayerName,
274
                                                                                                        shapeType, types, attrNames);
275
                        return ((FlyrVectIVectorLayer)output).getFeatureStore();
276
                } catch (UnsupportedOutputChannelException e) {
277
                        Sextante.addErrorToLog(e);
278
        } catch (GeoAlgorithmExecutionException e) {
279
            Sextante.addErrorToLog(e);
280
        }
281
                return null;
282
        }
283

    
284
    @Override
285
    public Class<? extends GeoAlgorithmParametersPanel> getCustomParametersPanelClass() {
286
        return SpatialJoinParametersPanel.class;
287
    }
288
}