Revision 960 org.gvsig.geoprocess/trunk/org.gvsig.geoprocess/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.spatialjoin/src/main/java/org/gvsig/geoprocess/algorithm/spatialjoin/SpatiallyIndexedSpatialJoinOperation.java

View differences:

SpatiallyIndexedSpatialJoinOperation.java
23 23
 */
24 24
package org.gvsig.geoprocess.algorithm.spatialjoin;
25 25

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

  
30
import com.vividsolutions.jts.geom.Geometry;
28
import org.apache.commons.lang3.mutable.MutableDouble;
29
import org.apache.commons.lang3.mutable.MutableObject;
31 30

  
32 31
import es.unex.sextante.core.Sextante;
33 32

  
......
36 35
import org.gvsig.fmap.dal.feature.Feature;
37 36
import org.gvsig.fmap.dal.feature.FeatureIndex;
38 37
import org.gvsig.fmap.dal.feature.FeatureIndexes;
38
import org.gvsig.fmap.dal.feature.FeatureReference;
39 39
import org.gvsig.fmap.dal.feature.FeatureSelection;
40 40
import org.gvsig.fmap.dal.feature.FeatureSet;
41 41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
42
import org.gvsig.fmap.geom.Geometry;
43
import org.gvsig.fmap.geom.GeometryLocator;
44
import org.gvsig.fmap.geom.GeometryManager;
45
import org.gvsig.fmap.geom.SpatialIndex;
43 46
import org.gvsig.fmap.geom.exception.CreateGeometryException;
44 47
import org.gvsig.fmap.geom.primitive.Envelope;
45 48
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation;
46
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil;
47 49
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess;
48 50
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer;
49
import org.gvsig.tools.dispose.DisposableIterator;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.visitor.VisitCanceledException;
53
import org.gvsig.tools.visitor.Visitor;
50 54

  
51 55
/**
52 56
 *
......
72 76
	/**
73 77
	 * Specialized instance in nearest neighbor search.
74 78
	 */
75
	private FeatureIndex              index                 = null;
79
	private SpatialIndex              index                 = null;
76 80

  
77
	public SpatiallyIndexedSpatialJoinOperation(FlyrVectIVectorLayer targetLayer, String indexName, AbstractSextanteGeoProcess p) {
81
	public SpatiallyIndexedSpatialJoinOperation(FlyrVectIVectorLayer targetLayer, SpatialIndex index, AbstractSextanteGeoProcess p) {
78 82
		super(p);
79
		FeatureIndexes indexes = targetLayer.getFeatureStore().getIndexes();
80
		index = indexes.getFeatureIndex(indexName);
83
		this.index = index;
81 84
		storeOverlay = targetLayer.getFeatureStore();
82 85
	}
83 86

  
......
86 89
	 * @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature)
87 90
	 */
88 91
	@SuppressWarnings({ "unchecked", "deprecation" })
89
	public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature featureInput) {
90
	    boolean addedFeature = false;
91
		if(g == null)
92
			return lastEditFeature;
92
    public EditableFeature invoke(final org.gvsig.fmap.geom.Geometry g, Feature featureInput) {
93
	    final MutableObject<Feature> foundFeature = new MutableObject<Feature>(null);
94
        boolean addedFeature = false;
95
        if (g == null)
96
            return lastEditFeature;
93 97

  
94
		if(featureSelection == null) {
95
			try {
96
				featureSelection = storeOverlay.getFeatureSelection();
97
			} catch (DataException e1) {
98
				//Sin selecci?n tiramos
99
			}
100
		}
98
        try {
99
            final MutableDouble nearestDistance = new MutableDouble(Double.POSITIVE_INFINITY);
101 100

  
102
		try {
103
			Geometry gJts = GeometryUtil.geomToJTS(g);
104
            Envelope rect = null;
105
		    rect = g.getEnvelope();
106
			FeatureSet featSetMatch = index.getMatchFeatureSet(rect);
107
			FeatureSet featSetNearest = index.getNearestFeatureSet(numOfNeighbours, rect);
108
			double nearestDistance = Double.MAX_VALUE;
109
            Iterator it = featSetMatch.iterator();
101
            index.query(g, new Visitor() {
110 102

  
111
            //Recorremos el featSetMatch para calcular la nearestDistance
112
            while(it.hasNext()) {
113
                Feature feat = (Feature)it.next();
114
                if( featureSelection != null &&
115
                    !featureSelection.isEmpty() &&
116
                    !featureSelection.isSelected(feat))
117
                    continue;
118
                List geomList = feat.getGeometries();
119

  
120
                if(geomList == null) {
121
                    org.gvsig.fmap.geom.Geometry g2 = feat.getDefaultGeometry();
122
                    Geometry g2Jts = GeometryUtil.geomToJTS(g2);
123
                    double dist = gJts.distance(g2Jts);
124
                    if (dist <= nearestDistance) {
125
                        nearestDistance = dist;
103
                @Override
104
                public void visit(Object obj) throws VisitCanceledException, BaseException {
105
                    FeatureReference ref = (FeatureReference) obj;
106
                    Feature feat = ref.getFeature();
107
                    Geometry g2 = feat.getDefaultGeometry();
108
                    double dist = g.distance(g2);
109
                    if (dist <= nearestDistance.getValue()) {
110
                        nearestDistance.setValue(dist);
111
                        foundFeature.setValue(feat.getCopy());
126 112
                    }
127
                    continue;
128 113
                }
114
            });
129 115

  
130
                Iterator<org.gvsig.fmap.geom.Geometry> itGeom = geomList.iterator();
131
                while(itGeom.hasNext()) {
132
                    org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
133
                    Geometry g2Jts = GeometryUtil.geomToJTS(g2);
134
                    double dist = gJts.distance(g2Jts);
135
                    if (dist <= nearestDistance) {
136
                        nearestDistance = dist;
137
                    }
116
            Iterator<?> iterator = index.queryNearest(g);
117
            while (iterator.hasNext()) {
118
                FeatureReference ref = (FeatureReference) iterator.next();
119
                Feature feat = ref.getFeature();
120
                Geometry g2 = feat.getDefaultGeometry();
121
                double dist = g.distance(g2);
122
                if (dist <= nearestDistance.getValue()) {
123
                    nearestDistance.setValue(dist);
124
                    foundFeature.setValue(feat.getCopy());
138 125
                }
139 126
            }
140
//            it.dispose();
141 127

  
142
            //Recorremos el featSetNearest para calcular la nearestDistance
143
            it = featSetNearest.iterator();
144
            while(it.hasNext()) {
145
                Feature feat = (Feature)it.next();
146
                if( featureSelection != null &&
147
                    !featureSelection.isEmpty() &&
148
                    !featureSelection.isSelected(feat))
149
                    continue;
150
                List geomList = feat.getGeometries();
151

  
152
                if(geomList == null) {
153
                    org.gvsig.fmap.geom.Geometry g2 = feat.getDefaultGeometry();
154
                    Geometry g2Jts = GeometryUtil.geomToJTS(g2);
155
                    double dist = gJts.distance(g2Jts);
156
                    if (dist <= nearestDistance) {
157
                        nearestDistance = dist;
158
                    }
159
                    continue;
160
                }
161

  
162
                Iterator<org.gvsig.fmap.geom.Geometry> itGeom = geomList.iterator();
163
                while(itGeom.hasNext()) {
164
                    org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
165
                    Geometry g2Jts = GeometryUtil.geomToJTS(g2);
166
                    double dist = gJts.distance(g2Jts);
167
                    if (dist <= nearestDistance) {
168
                        nearestDistance = dist;
169
                    }
170
                }
128
            if(foundFeature!=null){
129
                buildFeature(featureInput, foundFeature.getValue(), new Double(nearestDistance.getValue()), g);
130
                addedFeature = true;
171 131
            }
172
//            it.dispose();
173 132

  
174
            //Recorremos el featSetMatch para obtener las geometr?as que est?n a una distancia igual o menor a la nearestDistance
133
        } catch (Exception e) {
134
            Sextante.addErrorToLog(e);
135
        }
175 136

  
176
            it = featSetMatch.iterator();
177
            while (it.hasNext()) {
178
                Feature feat = (Feature) it.next();
179
                if (featureSelection != null && !featureSelection.isEmpty()
180
                    && !featureSelection.isSelected(feat))
181
                    continue;
182
                List geomList = feat.getGeometries();
137
        return lastEditFeature;
138
    }
183 139

  
184
                if (geomList == null) {
185
                    org.gvsig.fmap.geom.Geometry g2 = feat.getDefaultGeometry();
186
                    Geometry g2Jts = GeometryUtil.geomToJTS(g2);
187
                    double dist = gJts.distance(g2Jts);
188
                    if (dist <= nearestDistance) {
189
                        buildFeature(featureInput, feat, new Double(
190
                            nearestDistance), g);
191
                        addedFeature= true;
192
                    }
193
                     continue;
194
                }
195

  
196
                Iterator<org.gvsig.fmap.geom.Geometry> itGeom =
197
                    geomList.iterator();
198
                while (itGeom.hasNext()) {
199
                    org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
200
                    Geometry g2Jts = GeometryUtil.geomToJTS(g2);
201
                    double dist = gJts.distance(g2Jts);
202
                    if (dist <= nearestDistance) {
203
                        buildFeature(featureInput, feat, new Double(
204
                            nearestDistance), g);
205
                        addedFeature= true;
206
                    }
207
                }
208
            }
209
//            it.dispose();
210

  
211

  
212
            //Recorremos el featSetNearest para obtener las geometr?as que est?n a una distancia igual o menor a la nearestDistance
213
            //si no se ha a?adido todav?a ninguna feature
214

  
215
            if (!addedFeature) {
216
                it = featSetNearest.iterator();
217
                while (it.hasNext()) {
218
                    Feature feat = (Feature) it.next();
219

  
220
                    if (featureSelection != null && !featureSelection.isEmpty()
221
                        && !featureSelection.isSelected(feat))
222
                        continue;
223
                    List geomList = feat.getGeometries();
224

  
225
                    if (geomList == null) {
226
                        org.gvsig.fmap.geom.Geometry g2 =
227
                            feat.getDefaultGeometry();
228
                        Geometry g2Jts = GeometryUtil.geomToJTS(g2);
229
                        double dist = gJts.distance(g2Jts);
230
                        if (dist <= nearestDistance) {
231
                            buildFeature(featureInput, feat, new Double(
232
                                nearestDistance), g);
233
                            addedFeature = true;
234
                        }
235
                        continue;
236
                    }
237

  
238
                    Iterator<org.gvsig.fmap.geom.Geometry> itGeom =
239
                        geomList.iterator();
240
                    while (itGeom.hasNext()) {
241
                        org.gvsig.fmap.geom.Geometry g2 = itGeom.next();
242
                        Geometry g2Jts = GeometryUtil.geomToJTS(g2);
243
                        double dist = gJts.distance(g2Jts);
244
                        if (dist <= nearestDistance && !addedFeature) {
245
                            buildFeature(featureInput, feat, new Double(
246
                                nearestDistance), g);
247
                            addedFeature = true;
248
                        }
249
                    }
250
                }
251
//                it.dispose();
252
            }
253

  
254
		} catch(FeatureIndexException e) {
255
			Sextante.addErrorToLog(e);
256
		} catch (DataException e) {
257
			Sextante.addErrorToLog(e);
258
		}
259

  
260
		return lastEditFeature;
261
	}
262

  
263 140
	/**
264 141
	 * Builds a feature and adds it to the output file
265 142
	 * @param feat1

Also available in: Unified diff