Revision 64

View differences:

org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.spatialjoin/src/main/java/org/gvsig/sextante/app/algorithm/spatialjoin/SpatialJoinParametersPanel.java
108 108
		this.add(getAlgorithmOutputPanel(), gbc);
109 109
		
110 110
		initTable();
111
		getRadioButtonTable().setVisible(false);
111 112
	}
112 113
	
113 114
	/**
......
197 198
	public JCheckBox getNearestCheck() {
198 199
		if(nearest == null) {
199 200
			nearest = new JCheckBox(Sextante.getText("use_the_nearest"));
201
			nearest.setSelected(true);
200 202
			nearest.addActionListener(this);
201 203
		}
202 204
		return nearest;
......
222 224
	 * (non-Javadoc)
223 225
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
224 226
	 */
227
	@SuppressWarnings("unchecked")
225 228
	public void actionPerformed(ActionEvent e) {
226
		if(e.getSource() ==  getLayers1Combo()) {			
227
			initTable();
228
		}
229
		
230 229
		if(e.getSource() == getNearestCheck()) {
231 230
			if(!getNearestCheck().isSelected())
232 231
				getRadioButtonTable().setVisible(true);
233 232
			else
234 233
				getRadioButtonTable().setVisible(false);
235 234
		}
235
		
236
		if(e.getSource() ==  getLayers2Combo()) {
237
			initTable();
238
			
239
			//If the second layer has not numerical fields only the nearest method can be applied
240
			IVectorLayer lyr = getSelectedVectorLayer2();
241
			Class[] types = lyr.getFieldTypes();
242
			boolean hasNumericField = false;
243
			for (int i = 0; i < types.length; i++) {
244
				if(types[i] == Integer.class 
245
						|| types[i] == Double.class 
246
						|| types[i] == Float.class 
247
						|| types[i] == Short.class) {
248
					hasNumericField = true;
249
					break;
250
				}
251
			}
252
			if(!hasNumericField)
253
				getNearestCheck().setSelected(true);
254
		}
236 255
	}
237 256
	
238 257
	/**
......
333 352
	 * @return
334 353
	 */
335 354
	public String[] getFieldList() {
336
		IVectorLayer layer = getSelectedVectorLayer();
355
		IVectorLayer layer = getSelectedVectorLayer2();
337 356
		String[] data = new String[layer.getFieldCount()];
338 357
		for (int i = 0; i < layer.getFieldCount(); i++) 
339 358
			data[i] = layer.getFieldName(i);
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.spatialjoin/src/main/java/org/gvsig/sextante/app/algorithm/spatialjoin/IntersectsSpatialJoinOperation.java
18 18
 */
19 19
package org.gvsig.sextante.app.algorithm.spatialjoin;
20 20

  
21
import java.util.Iterator;
22
import java.util.List;
23

  
24
import org.gvsig.fmap.dal.exception.DataException;
25
import org.gvsig.fmap.dal.feature.DisposableIterator;
21 26
import org.gvsig.fmap.dal.feature.EditableFeature;
22 27
import org.gvsig.fmap.dal.feature.Feature;
23
import org.gvsig.fmap.geom.Geometry;
28
import org.gvsig.fmap.dal.feature.FeatureIndex;
29
import org.gvsig.fmap.dal.feature.FeatureIndexes;
30
import org.gvsig.fmap.dal.feature.FeatureSet;
31
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
32
import org.gvsig.fmap.geom.exception.CreateGeometryException;
33
import org.gvsig.fmap.geom.primitive.Envelope;
24 34
import org.gvsig.sextante.app.algorithm.base.core.GeometryOperation;
35
import org.gvsig.sextante.app.algorithm.base.util.GeometryUtil;
36
import org.gvsig.sextante.app.algorithm.dissolve.Summary;
37
import org.gvsig.sextante.app.extension.core.gvVectorLayer;
25 38

  
39
import com.vividsolutions.jts.geom.Geometry;
40

  
41
import es.unex.sextante.core.Sextante;
42

  
26 43
/**
27 44
 * 
28 45
 * @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a>
29 46
 */
30 47
public class IntersectsSpatialJoinOperation extends GeometryOperation {
48
	/**
49
	 * Geometry.distance() is a costly operation. Thats the reason for we are
50
	 * only using a nearest neighbor. TODO SpatialIndex works with Rectangle2D,
51
	 * and this may be a simplification that drives to errors. Make additional
52
	 * probes to use a number of default neighbors
53
	 */
54
	static final int                  DEFAULT_NUM_NEIGBOURS = 1000;
31 55

  
56
	/**
57
	 * Number of neighbors that nearestFinder must found.
58
	 */
59
	int                               numOfNeighbours       = DEFAULT_NUM_NEIGBOURS;
60

  
61
	/**
62
	 * Specialized instance in nearest neighbor search.
63
	 */
64
	private FeatureIndex              index                 = null;
65
	private Summary                   summary               = null;
66
	
67
	public IntersectsSpatialJoinOperation(gvVectorLayer targetLayer, String indexName, Summary summary) {
68
		FeatureIndexes indexes = targetLayer.getFeatureStore().getIndexes();
69
		index = indexes.getFeatureIndex(indexName);
70
		this.summary = summary;
71
	}
72
	
32 73
	/*
33 74
	 * (non-Javadoc)
34 75
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
35 76
	 */
36
	public EditableFeature invoke(Geometry g, Feature featureInput) {
37
		return null;
77
	@SuppressWarnings("unchecked")
78
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature featureInput) {
79
		if(g == null)
80
			return lastEditFeature;
81

  
82
		try {
83

  
84
			Envelope rect = g.getEnvelope();
85
			FeatureSet featSet = index.getNearestFeatureSet(numOfNeighbours, rect);
86
			double nearestDistance = Double.MAX_VALUE;
87

  
88
			boolean first = true;
89
			DisposableIterator it = featSet.iterator();
90
			while(it.hasNext()) {
91
				Feature feat = (Feature)it.next();
92
				
93
				if(first) {
94
					summary.loadDefaultSummarizes(feat);
95
					first = false;
96
				}
97
				
98
				List geomList = feat.getGeometries();
99

  
100
				if(geomList == null) {
101
					org.gvsig.fmap.geom.Geometry g2 = feat.getDefaultGeometry();
102
					
103
					
104
					buildFeature(featureInput, feat, new Double(nearestDistance), g);
105
					continue;
106
				}
107
				
108
				Iterator<org.gvsig.fmap.geom.Geometry> itGeom = geomList.iterator();
109
				while(itGeom.hasNext()) {
110
					org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
111
					
112
					
113
				    buildFeature(featureInput, feat, new Double(nearestDistance), g);
114
				}
115
			}
116
			
117
		} catch(FeatureIndexException e) {
118
			Sextante.addErrorToLog(e);
119
		} catch (DataException e) {
120
			Sextante.addErrorToLog(e);
121
		}
122
		
123
		return lastEditFeature;
38 124
	}
125
	
126
	/**
127
	 * Builds a feature and adds it to the output file
128
	 * @param feat1
129
	 * @param feat2
130
	 * @param value
131
	 * @param g
132
	 * @throws DataException
133
	 */
134
	private void buildFeature(Feature feat1, Feature feat2, Object value, org.gvsig.fmap.geom.Geometry g) throws DataException {
135
		EditableFeature outFeat = persister.getOutputFeatureStore().createNewFeature();
136
		int sizeFeat1 = feat1.getType().size() - 1;
137
		
138
		for (int i = 0; i < sizeFeat1; i++) 
139
			outFeat.set(i, feat1.get(i));
140
		
141
		for (int i = sizeFeat1; i < sizeFeat1 + feat2.getType().size() - 1; i++) 
142
			outFeat.set(i, feat2.get(i - sizeFeat1));
143
		
144
		outFeat.set(outFeat.getType().size() - 2, value);
145
		try {
146
			persister.addFeature(outFeat, g);
147
		} catch (CreateGeometryException e) {
148
			Sextante.addErrorToLog(e);
149
		}
150
	}
39 151

  
40 152
	/*
41 153
	 * (non-Javadoc)
42 154
	 * @see org.gvsig.sextante.app.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature)
43 155
	 */
44
	public void invoke(Geometry g, EditableFeature featureInput) {
156
	public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature featureInput) {
45 157
		
46 158
	}
47 159

  
org.gvsig.sextante/trunk/org.gvsig.sextante.app/org.gvsig.sextante.app.algorithm/org.gvsig.sextante.app.algorithm.spatialjoin/src/main/java/org/gvsig/sextante/app/algorithm/spatialjoin/SpatialJoinAlgorithm.java
18 18
 */
19 19
package org.gvsig.sextante.app.algorithm.spatialjoin;
20 20

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

  
23 25
import org.gvsig.fmap.dal.DALLocator;
24 26
import org.gvsig.fmap.dal.DataManager;
......
27 29
import org.gvsig.fmap.dal.feature.FeatureSet;
28 30
import org.gvsig.fmap.dal.feature.FeatureStore;
29 31
import org.gvsig.fmap.dal.feature.FeatureType;
30
import org.gvsig.sextante.app.algorithm.spatialjoin.SpatiallyIndexedSpatialJoinOperation;
32
import org.gvsig.sextante.app.algorithm.base.core.GeometryOperation;
33
import org.gvsig.sextante.app.algorithm.dissolve.DissolveRule;
34
import org.gvsig.sextante.app.algorithm.dissolve.IDissolveRule;
35
import org.gvsig.sextante.app.algorithm.dissolve.Summary;
31 36
import org.gvsig.sextante.app.extension.core.gvGeoAlgorithm;
32 37
import org.gvsig.sextante.app.extension.core.gvVectorLayer;
33 38

  
......
35 40
import es.unex.sextante.dataObjects.IVectorLayer;
36 41
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
37 42
import es.unex.sextante.exceptions.RepeatedParameterNameException;
43
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
38 44
import es.unex.sextante.outputs.OutputVectorLayer;
39 45

  
40 46
/**
......
120 126

  
121 127
		//Builds the output and computes the operation
122 128
		try {
129
			FeatureSet features = null;
130
			features = lyr1.getFeatureStore().getFeatureSet();
131
			FeatureType featureType1 = features.getDefaultFeatureType();
132
			features = lyr2.getFeatureStore().getFeatureSet();
133
			FeatureType featureType2 = features.getDefaultFeatureType();
134
			
135
			GeometryOperation operation = null;
136
			FeatureStore outFeatStore = null;
137
			
123 138
			if(nearest) {
124
				FeatureSet features = null;
125
				features = lyr1.getFeatureStore().getFeatureSet();
126
				FeatureType featureType1 = features.getDefaultFeatureType();
127
				features = lyr2.getFeatureStore().getFeatureSet();
128
				FeatureType featureType2 = features.getDefaultFeatureType();
129
				
130
				FeatureStore outFeatStore = buildOutPutStoreFromUnion(featureType1, 
139
				outFeatStore = buildOutPutStoreFromUnion(featureType1, 
131 140
						featureType2, 
132 141
						lyr1.getShapeType(), 
133 142
						Sextante.getText("SpatialJoin"), 
......
135 144
						"DIST", 
136 145
						Double.class);
137 146

  
138
				SpatiallyIndexedSpatialJoinOperation operation = new SpatiallyIndexedSpatialJoinOperation(lyr2, indexName + "_idx");
139
				operation.setProgressModel(this);
140
				operation.computesGeometryOperation(lyr1.getFeatureStore(), 
141
						outFeatStore, 
142
						attrNames, 
143
						selectedGeom, 
144
						true);
147
				operation = new SpatiallyIndexedSpatialJoinOperation(lyr2, indexName + "_idx");
148
			} else {
149
				outFeatStore = buildSpatialJoinOutPutStore(featureType1,
150
						lyr1.getShapeType(), 
151
						Sextante.getText("SpatialJoin"), 
152
						RESULT);
153
				IDissolveRule rule = new DissolveRule(0, funcMap);
154
				Summary summary = new Summary(rule, outFeatStore.getDefaultFeatureType());
155
				//summary.loadDefaultSummarizes(this.feature);
156
				operation = new IntersectsSpatialJoinOperation(lyr2, indexName + "_idx", summary);
145 157
			}
158
			
159
			operation.setProgressModel(this);
160
			operation.computesGeometryOperation(lyr1.getFeatureStore(), 
161
					outFeatStore, 
162
					attrNames, 
163
					selectedGeom, 
164
					true);		
146 165
		} catch (DataException e) {
147 166
			Sextante.addErrorToLog(e);
148 167
		}
......
181 200
		}
182 201
	}
183 202
	
203
	/**
204
	 * Builds the output FeatureStore 
205
	 * @param featureType
206
	 * @return FeatureStore
207
	 */
208
	@SuppressWarnings("unchecked")
209
	protected FeatureStore buildSpatialJoinOutPutStore(FeatureType featureType1,
210
											int shapeType,
211
											String sextanteLayerName, 
212
											String sextanteLayerLabel) {
213
		ArrayList<Class> typesList = new ArrayList<Class>();
214
		ArrayList<String> attr = new ArrayList<String>();
215
		
216
		Iterator it = featureType1.iterator();
217
		while( it.hasNext() ) {
218
			FeatureAttributeDescriptor attribute = (FeatureAttributeDescriptor)it.next();
219
			if(attribute.getName().compareTo("GEOMETRY") != 0) {
220
				attr.add(attribute.getName());
221
				typesList.add(attribute.getObjectClass());
222
			}
223
		}
224
		
225
		for (int i = 0; i < funcList.length; i++) {
226
			if(funcList[i]) {
227
				String fieldName = funcMap.get(Summary[i]);
228
				if(fieldName.length() >= 6)
229
					fieldName = fieldName.substring(0, 7);
230
				attr.add(fieldName + "_" + Summary[i]);
231
				typesList.add(Double.class);
232
			}
233
		}
234
		
235
		attr.add("NUM_RELA");
236
		typesList.add(Integer.class);
237
		
238
		attrNames = new String[attr.size()];
239
		attr.toArray(attrNames);
240
		Class[] types = new Class[typesList.size()];
241
		typesList.toArray(types);
242
		
243
		try {
244
			IVectorLayer output = getNewVectorLayer(sextanteLayerLabel,
245
													sextanteLayerName,
246
													shapeType, types, attrNames);
247
			return ((gvVectorLayer)output).getFeatureStore();
248
		} catch (UnsupportedOutputChannelException e) {
249
			Sextante.addErrorToLog(e);
250
		}
251
		return null;
252
	}
253
	
184 254
}

Also available in: Unified diff