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

History | View | Annotate | Download (9.5 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2010 Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.geoprocess.algorithm.spatialjoin;
20

    
21
import java.util.ArrayList;
22
import java.util.HashMap;
23
import java.util.Iterator;
24

    
25
import es.unex.sextante.core.Sextante;
26
import es.unex.sextante.dataObjects.IVectorLayer;
27
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
28
import es.unex.sextante.exceptions.RepeatedParameterNameException;
29
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
30
import es.unex.sextante.outputs.OutputVectorLayer;
31

    
32
import org.gvsig.fmap.dal.DALLocator;
33
import org.gvsig.fmap.dal.DataManager;
34
import org.gvsig.fmap.dal.DataTypes;
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
37
import org.gvsig.fmap.dal.feature.FeatureSet;
38
import org.gvsig.fmap.dal.feature.FeatureStore;
39
import org.gvsig.fmap.dal.feature.FeatureType;
40
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
41
import org.gvsig.geoprocess.algorithm.dissolve.DissolveRule;
42
import org.gvsig.geoprocess.algorithm.dissolve.IDissolveRule;
43
import org.gvsig.geoprocess.algorithm.dissolve.Summary;
44
import org.gvsig.geoprocess.core.gvVectorLayer;
45
import org.gvsig.geoprocess.sextante.AbstractSextanteGeoProcess;
46

    
47
/**
48
 * Spatial join algorithm
49
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
50
 */
51
public class SpatialJoinAlgorithm extends AbstractSextanteGeoProcess {
52

    
53
        public static final String        NEW_FIELD         = "NUM_RELA";
54
        public static final String        RESULT            = "RESULT";
55
        public static final String        LAYER1            = "LAYER1";
56
        public static final String        LAYER2            = "LAYER2";
57
        public static final String        SELECTED_GEOM     = "SELECTED_GEOM";
58
        public static final String        NEAREST           = "NEAREST";
59
        public static final String        FUNCTION_LIST     = "FUNCTION_LIST";
60
        public static final String        Summary[]         = {"Min", "Max", "Sum", "Avg"};
61
        private boolean                   funcList[]        = new boolean[Summary.length];
62
        private HashMap<String, String>   funcMap           = new HashMap<String, String>();
63
        
64
        /*
65
         * (non-Javadoc)
66
         * @see es.unex.sextante.core.GeoAlgorithm#defineCharacteristics()
67
         */
68
        public void defineCharacteristics(){
69
                setName(Sextante.getText("Spatialjoin"));
70
                setGroup(Sextante.getText("gvSIG_Algorithms"));
71
        // setGeneratesUserDefinedRasterOutput(false);
72
                
73
                try {
74
                        m_Parameters.addInputVectorLayer(LAYER1, 
75
                                                                                                Sextante.getText("Input_layer"), 
76
                                                                                                IVectorLayer.SHAPE_TYPE_WRONG, 
77
                                                                                                true);
78
                        m_Parameters.addInputVectorLayer(LAYER2, 
79
                                                                                                Sextante.getText( "Input_layer"), 
80
                                                                                                IVectorLayer.SHAPE_TYPE_WRONG, 
81
                                                                                                true);
82
                        m_Parameters.addBoolean(SELECTED_GEOM, Sextante.getText("Selected_geometries"), false);
83
                        m_Parameters.addBoolean(NEAREST, Sextante.getText("use_the_nearest"), false);
84
                        m_Parameters.addString(FUNCTION_LIST, Sextante.getText("Function_list"));
85
                } catch (RepeatedParameterNameException e) {
86
                        Sextante.addErrorToLog(e);
87
                }
88
                addOutputVectorLayer(RESULT,
89
                                                                Sextante.getText("Spatialjoin"),
90
                                                                OutputVectorLayer.SHAPE_TYPE_UNDEFINED);
91
        }
92
        
93
        /*
94
         * (non-Javadoc)
95
         * @see es.unex.sextante.core.GeoAlgorithm#processAlgorithm()
96
         */
97
        public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
98
                IVectorLayer layer1 = m_Parameters.getParameterValueAsVectorLayer(LAYER1);
99
                IVectorLayer layer2 = m_Parameters.getParameterValueAsVectorLayer(LAYER2);
100
                boolean selectedGeom = m_Parameters.getParameterValueAsBoolean(SELECTED_GEOM);
101
                boolean nearest = m_Parameters.getParameterValueAsBoolean(NEAREST);
102
                String functionList = m_Parameters.getParameterValueAsString(FUNCTION_LIST);
103
                loadSummary(functionList);
104

    
105
                gvVectorLayer lyr1 = null;
106
                gvVectorLayer lyr2 = null;
107
                if(layer2 instanceof gvVectorLayer && layer1 instanceof gvVectorLayer) { 
108
                        lyr2 = ((gvVectorLayer)layer2);
109
                        lyr1 = ((gvVectorLayer)layer1);
110
                } else 
111
                        return false;
112

    
113
                DataManager dataManager = DALLocator.getDataManager();
114

    
115
                //Builds a new JSIRTree index. To do that we have to replace the default index and 
116
                //when the operation has finished then it restores the original default index 
117
                String indexName = "GEOMETRY";
118
                
119
                try {
120
                        indexName = lyr2.getFeatureStore().getDefaultFeatureType().getDefaultGeometryAttributeName();
121
                        FeatureAttributeDescriptor fat = lyr2.getFeatureStore().getDefaultFeatureType().getAttributeDescriptor(indexName);
122
                        String defaultIndex = dataManager
123
                                        .getDefaultFeatureIndexProviderName(fat.getDataType()
124
                                                        .getType());
125
                        dataManager.setDefaultFeatureIndexProviderName(fat.getDataType()
126
                                        .getType(), "JSIRTree");
127
                        lyr2.getFeatureStore().createIndex(lyr2.getFeatureStore().getDefaultFeatureType(), indexName, indexName + "_idx");
128
                        dataManager.setDefaultFeatureIndexProviderName(fat.getDataType()
129
                                        .getType(), defaultIndex);
130
                } catch (DataException e) {
131
                        Sextante.addErrorToLog(e);
132
                }
133

    
134
                //Builds the output and computes the operation
135
                try {
136
                        FeatureSet features = null;
137
                        features = lyr1.getFeatureStore().getFeatureSet();
138
                        FeatureType featureType1 = features.getDefaultFeatureType();
139
                        features = lyr2.getFeatureStore().getFeatureSet();
140
                        FeatureType featureType2 = features.getDefaultFeatureType();
141
                        
142
                        GeometryOperation operation = null;
143
                        FeatureStore outFeatStore = null;
144
                        
145
                        if(nearest) {
146
                                outFeatStore = buildOutPutStoreFromUnion(featureType1, 
147
                                                featureType2, 
148
                                                lyr1.getShapeType(), 
149
                                                Sextante.getText("SpatialJoin"), 
150
                                                RESULT, 
151
                                                "DIST", 
152
                                                Double.class);
153

    
154
                                operation = new SpatiallyIndexedSpatialJoinOperation(lyr2, indexName + "_idx");
155
                        } else {
156
                                outFeatStore = buildSpatialJoinOutPutStore(featureType1,
157
                                                lyr1.getShapeType(), 
158
                                                Sextante.getText("SpatialJoin"), 
159
                                                RESULT);
160
                                IDissolveRule rule = new DissolveRule(0, funcMap);
161
                                Summary summary = new Summary(rule, outFeatStore.getDefaultFeatureType());
162
                                operation = new IntersectsSpatialJoinOperation(lyr2, indexName + "_idx", summary);
163
                        }
164
                        
165
                        operation.setProgressModel(this);
166
                        operation.computesGeometryOperation(lyr1.getFeatureStore(), 
167
                                        outFeatStore, 
168
                                        attrNames, 
169
                                        selectedGeom, 
170
                                        true);                
171
                } catch (DataException e) {
172
                        Sextante.addErrorToLog(e);
173
                }
174

    
175
                return true;
176
        }
177

    
178
        /**
179
         * Checks if the parameter is in Summary list
180
         * @param it
181
         * @return the position in the list
182
         */
183
        private int isInList(String it) {
184
                for (int i = 0; i < Summary.length; i++) {
185
                        if(Summary[i].compareTo(it) == 0)
186
                                return i;
187
                }
188
                return -1;
189
        }
190
        
191
        /**
192
         * Loads the list of functions to use
193
         * @param functionList
194
         */
195
        private void loadSummary(String functionList) {
196
                String[] attrList = functionList.split(";");
197
                for (int i = 0; i < attrList.length; i++) {
198
                        String[] func = attrList[i].split(",");
199
                        for (int j = 1; j < func.length; j++) {
200
                                int pos = isInList(func[j]);
201
                                if(pos != -1) {
202
                                        funcList[pos] = true;
203
                                        funcMap.put(Summary[pos], func[0]);
204
                                }
205
                        }
206
                }
207
        }
208
        
209
        /**
210
         * Builds the output FeatureStore 
211
         * @param featureType
212
         * @return FeatureStore
213
         */
214
        @SuppressWarnings("unchecked")
215
        protected FeatureStore buildSpatialJoinOutPutStore(FeatureType featureType1,
216
                                                                                        int shapeType,
217
                                                                                        String sextanteLayerName, 
218
                                                                                        String sextanteLayerLabel) {
219
                ArrayList<Class> typesList = new ArrayList<Class>();
220
                ArrayList<String> attr = new ArrayList<String>();
221
                
222
                Iterator it = featureType1.iterator();
223
                while( it.hasNext() ) {
224
                        FeatureAttributeDescriptor attribute = (FeatureAttributeDescriptor)it.next();
225
                        if (attribute.getDataType().getType() != DataTypes.GEOMETRY) {
226
                                attr.add(attribute.getName());
227
                                typesList.add(attribute.getObjectClass());
228
                        }
229
                }
230
                
231
                for (int i = 0; i < funcList.length; i++) {
232
                        if(funcList[i]) {
233
                                String fieldName = funcMap.get(Summary[i]);
234
                                if(fieldName.length() >= 6)
235
                                        fieldName = fieldName.substring(0, 7);
236
                                attr.add(fieldName + "_" + Summary[i]);
237
                                typesList.add(Double.class);
238
                        }
239
                }
240
                
241
                attr.add(NEW_FIELD);
242
                typesList.add(Integer.class);
243
                
244
                attrNames = new String[attr.size()];
245
                attr.toArray(attrNames);
246
                Class[] types = new Class[typesList.size()];
247
                typesList.toArray(types);
248
                
249
                try {
250
                        IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
251
                                                                                                        sextanteLayerName,
252
                                                                                                        shapeType, types, attrNames);
253
                        return ((gvVectorLayer)output).getFeatureStore();
254
                } catch (UnsupportedOutputChannelException e) {
255
                        Sextante.addErrorToLog(e);
256
        } catch (GeoAlgorithmExecutionException e) {
257
            Sextante.addErrorToLog(e);
258
        }
259
                return null;
260
        }
261
        
262
}