Revision 10626 trunk/extensions/extGeoProcessing/src/com/iver/cit/gvsig/geoprocess/impl/spatialjoin/fmap/NearestHeuristicSpatialJoinVisitor.java

View differences:

NearestHeuristicSpatialJoinVisitor.java
45 45
*
46 46
* $Id$
47 47
* $Log$
48
* Revision 1.1  2006-06-20 18:20:45  azabala
48
* Revision 1.2  2007-03-06 16:47:58  caballero
49
* Exceptions
50
*
51
* Revision 1.1  2006/06/20 18:20:45  azabala
49 52
* first version in cvs
50 53
*
51 54
* Revision 1.2  2006/06/02 18:21:28  azabala
......
64 67
import java.awt.geom.Rectangle2D;
65 68
import java.util.Stack;
66 69

  
67
import com.iver.cit.gvsig.fmap.DriverException;
70
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
71
import com.hardcode.gdbms.engine.data.driver.DriverException;
72
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
73
import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException;
74
import com.iver.cit.gvsig.exceptions.visitors.StartVisitorException;
75
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
68 76
import com.iver.cit.gvsig.fmap.core.IFeature;
69 77
import com.iver.cit.gvsig.fmap.core.IGeometry;
70 78
import com.iver.cit.gvsig.fmap.layers.FBitSet;
71 79
import com.iver.cit.gvsig.fmap.layers.FLayer;
72 80
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
73 81
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
74
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
75 82
import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureProcessor;
76 83
import com.vividsolutions.jts.geom.Envelope;
77 84
import com.vividsolutions.jts.geom.Geometry;
......
96 103
 * the parent node in the quad-tree structure).
97 104
 * <br>
98 105
 * A critical aspect is optimization of the number of levels of quad-tree.
99
 * 
106
 *
100 107
 * If we take very few levels, the spatial query will return a lot of
101 108
 * candidates to nearest, so we wont get advantage of this stuff.
102
 *  
109
 *
103 110
 * If we take a lot of levels, we wont get result in the spatial queries,
104 111
 * and we'll have to do a lot of querys.
105
 * 
112
 *
106 113
 * @author azabala
107
 * 
114
 *
108 115
 * FIXME EL ALGORITMO FALLA!!!!!!!! EL QUADTREE ES UNA ESTRUCTURA
109 116
 * BUENA PARA RECTANGULOS, PERO PARA PUNTOS CREO QUE NO FUNCIONA.
110 117
 * NO TIENE EN CUENTA LOS EXTREMOS DE LOS RECTANGULOS
111 118
 *
112 119
 */
113 120
public class NearestHeuristicSpatialJoinVisitor extends NearestSpatialJoinVisitor {
114
	
121

  
115 122
	private QuadTreeUtil quadTree = new QuadTreeUtil();
116 123
	/**
117 124
	 * Full extent of the layer where we are looking for
......
119 126
	 */
120 127
	private Envelope targetLayerEnv = null;
121 128
	/**
122
	 * 
129
	 *
123 130
	 * @param sourceLayer
124 131
	 * @param targetLayer
125 132
	 * @param processor
126 133
	 * @throws DriverException
127 134
	 */
128
	public NearestHeuristicSpatialJoinVisitor(FLyrVect sourceLayer, 
129
			FLyrVect targetLayer, 
130
			FeatureProcessor processor) throws DriverException {
135
	public NearestHeuristicSpatialJoinVisitor(FLyrVect sourceLayer,
136
			FLyrVect targetLayer,
137
			FeatureProcessor processor) throws ReadDriverException {
131 138
		super(sourceLayer, targetLayer, processor);
132
		
133
		Rectangle2D rect = targetLayer.getFullExtent();
134
		targetLayerEnv = new Envelope(rect.getMinX(), 
139

  
140
		Rectangle2D rect;
141
		try {
142
			rect = targetLayer.getFullExtent();
143
		} catch (ExpansionFileReadException e) {
144
			throw new ReadDriverException(sourceLayer.getName(),e);
145
		}
146
		targetLayerEnv = new Envelope(rect.getMinX(),
135 147
				rect.getMaxX(),
136 148
				rect.getMinY(),
137 149
				rect.getMaxY());
138
		
150

  
139 151
	}
140 152
	//	TODO If we need a class to look for nearest feature to a given
141 153
	//feature, move to a public class
......
158 170
		 * consideer features selected.
159 171
		 */
160 172
		FBitSet selection;
161
		
173

  
162 174
		public boolean hasFoundShortest(){
163 175
			return nearestFeatureIndex != -1;
164 176
		}
165
		
177

  
166 178
		public int getNearestFeatureIndex(){
167 179
			return nearestFeatureIndex;
168 180
		}
169
		
181

  
170 182
		public void setSelection(FBitSet bitSet){
171 183
			this.selection = bitSet;
172 184
		}
173
		
185

  
174 186
		public void setGeometry(Geometry firstG){
175 187
			this.firstG = firstG;
176 188
		}
177
		
178
		public void visit(IGeometry g, int index) throws VisitException {
189

  
190
		public void visit(IGeometry g, int index) throws VisitorException, ProcessVisitorException {
179 191
			if(selection != null){
180 192
				if(! selection.get(index)){
181 193
					return;
......
190 202
		public String getProcessDescription() {
191 203
			return "";
192 204
		}
193
		public void stop(FLayer layer) {
205
		public void stop(FLayer layer) throws VisitorException {
194 206
		}
195
		public boolean start(FLayer layer) {
207
		public boolean start(FLayer layer) throws StartVisitorException {
196 208
			return true;
197 209
		}
198 210
	};
......
200 212
	 * Processes a Feature of source layer, looking for its nearest feature of
201 213
	 * target layer and taking attributes from it
202 214
	 */
203
	public void visit(IGeometry g, int sourceIndex) throws VisitException {
215
	public void visit(IGeometry g, int sourceIndex) throws VisitorException, ProcessVisitorException {
204 216
		if(g == null)
205 217
			return;
206
		final Geometry geometry = g.toJTSGeometry();	
218
		final Geometry geometry = g.toJTSGeometry();
207 219
		Stack stackOfEnvelopes = quadTree.getNearestEnvelopeOfIdealDimension(geometry,
208 220
				targetLayerEnv);
209 221
		LookForNearest visitor = new LookForNearest();
210 222
		visitor.setGeometry(geometry);
211 223
		while((stackOfEnvelopes.size() > 0) ) {
212 224
			Envelope envelope = (Envelope) stackOfEnvelopes.pop();
213
			Rectangle2D.Double rect = new Rectangle2D.Double(envelope.getMinX(), 
225
			Rectangle2D.Double rect = new Rectangle2D.Double(envelope.getMinX(),
214 226
					envelope.getMinY(),
215 227
					envelope.getWidth(),
216 228
					envelope.getHeight());
......
221 233
				strategy.process(visitor, rect);
222 234
				if(visitor.hasFoundShortest()){
223 235
					int targetIndex = visitor.getNearestFeatureIndex();
224
					IFeature joinedFeature = createFeature(g, 
225
														sourceIndex, 
236
					IFeature joinedFeature = createFeature(g,
237
														sourceIndex,
226 238
														targetIndex, -1);
227 239
					this.featureProcessor.processFeature(joinedFeature);
228 240
					return;
229 241
				}
230
			} catch (DriverException e) {
231
				throw new VisitException("Error accediendo a los datos buscando el feature mas proximo", e);
232
			} catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
233
				throw new VisitException("Error accediendo a los datos buscando el feature mas proximo", e);
234
			} 	
242
			} catch (ReadDriverException e) {
243
				throw new ProcessVisitorException(targetRecordset.getName(),e,"Error accediendo a los datos buscando el feature mas proximo");
244
			} catch (ExpansionFileReadException e) {
245
				throw new ProcessVisitorException(targetRecordset.getName(),e,"Error accediendo a los datos buscando el feature mas proximo");
246
			}
235 247
		}//while
236
		
248

  
237 249
	}
238
	
250

  
239 251
	/**
240 252
	 * FIXME Refinar muy mucho, pero de momento me vale para hacer la busqueda
241 253
	 * de la geometria mas proxima a una dada mediante subdivisi?n del espacio.
242
	 *  
254
	 *
243 255
	 * @author azabala
244 256
	 *
245 257
	 */
246 258
	class QuadTreeUtil{
247 259
		double DEFAULT_IDEAL_DIMENSION = 500d;
248
		
260

  
249 261
		double idealDimension = DEFAULT_IDEAL_DIMENSION;
250 262

  
251 263
		public void setIdealDimension(double idealDimension){
252 264
			this.idealDimension = idealDimension;
253 265
		}
254
		
266

  
255 267
		public double distance(Geometry geo, Envelope rect){
256 268
			GeometryFactory geoFact = new GeometryFactory();
257 269
			Geometry poly = geoFact.toGeometry(rect);
258 270
			return DistanceOp.distance(geo, poly);
259 271
		}
260
		
272

  
261 273
		public double getMaxDimension(Envelope env){
262 274
			double w = env.getWidth();
263 275
			double h = env.getHeight();
264 276
			return (w > h ? w : h);
265 277
		}
266
		
267
		
278

  
279

  
268 280
		public Stack getNearestEnvelopeOfIdealDimension(Geometry nearest,
269 281
				Envelope originalEnvelope){
270 282
			//stack with all the hierarchical envelopes of the solution quad
......
285 297
					firstsolution = quads[1];
286 298
				else if(d2 <= d0 && d2 <= d1 && d2 <= d3)
287 299
					firstsolution = quads[2];
288
				else 
300
				else
289 301
					firstsolution = quads[3];
290 302
				solution.push(firstsolution);
291 303
				maxDimension = getMaxDimension(firstsolution);
292 304
			}
293 305
			return solution;
294
			
306

  
295 307
		}
296
		
308

  
297 309
		public  Envelope[] getNextQtreeLevel(Envelope rect){
298 310
			Envelope[] solution = new Envelope[4];
299 311
			int SW = 0;

Also available in: Unified diff