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