Revision 36187 branches/v2_0_0_prep/libraries/libFMap_dalindex/src/org/gvsig/fmap/dal/index/spatial/jsi/JSIRTree.java

View differences:

JSIRTree.java
42 42
 *   dac@iver.es
43 43
 */
44 44
/* CVS MESSAGES:
45
*
46
* $Id: RTreeJsi.java 13884 2007-09-19 16:26:04Z jaume $
47
* $Log$
48
* Revision 1.5  2007-09-19 16:25:39  jaume
49
* ReadExpansionFileException removed from this context and removed unnecessary imports
50
*
51
* Revision 1.4  2007/06/27 20:17:30  azabala
52
* new spatial index (rix)
53
*
54
* Revision 1.3  2007/03/06 17:08:59  caballero
55
* Exceptions
56
*
57
* Revision 1.2  2006/06/05 16:59:08  azabala
58
* implementada busqueda de vecino mas proximo a partir de rectangulos
59
*
60
* Revision 1.1  2006/05/24 21:58:04  azabala
61
* *** empty log message ***
62
*
63
*
64
*/
45
 *
46
 * $Id: RTreeJsi.java 13884 2007-09-19 16:26:04Z jaume $
47
 * $Log$
48
 * Revision 1.5  2007-09-19 16:25:39  jaume
49
 * ReadExpansionFileException removed from this context and removed unnecessary imports
50
 *
51
 * Revision 1.4  2007/06/27 20:17:30  azabala
52
 * new spatial index (rix)
53
 *
54
 * Revision 1.3  2007/03/06 17:08:59  caballero
55
 * Exceptions
56
 *
57
 * Revision 1.2  2006/06/05 16:59:08  azabala
58
 * implementada busqueda de vecino mas proximo a partir de rectangulos
59
 *
60
 * Revision 1.1  2006/05/24 21:58:04  azabala
61
 * *** empty log message ***
62
 *
63
 *
64
 */
65 65
package org.gvsig.fmap.dal.index.spatial.jsi;
66 66

  
67 67
import java.util.ArrayList;
......
69 69
import java.util.List;
70 70
import java.util.Properties;
71 71

  
72
import com.infomatiq.jsi.IntProcedure;
73
import com.infomatiq.jsi.Rectangle;
74
import com.infomatiq.jsi.rtree.RTree;
75

  
72 76
import org.gvsig.fmap.dal.exception.InitializeException;
73 77
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
74 78
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
......
78 82
import org.gvsig.fmap.geom.primitive.Envelope;
79 83
import org.gvsig.fmap.geom.primitive.Point;
80 84

  
81
import com.infomatiq.jsi.IntProcedure;
82
import com.infomatiq.jsi.Rectangle;
83
import com.infomatiq.jsi.rtree.RTree;
84

  
85 85
/**
86 86
 * RTree spatial index implementation based in library
87 87
 * JSI (java spatial index).
88
 *
88
 * 
89 89
 * http://jsi.sourceforge.net/
90
 *
90
 * 
91 91
 * This RTree has better performance that Spatial Index Library
92 92
 * RTree, and that JTS'RTree, because
93 93
 * it uses the GNU's Trove Collections API.
94
 *
94
 * 
95 95
 * We are doing some probes with it, because it offers
96 96
 * a Nearest Neighbour algorithm implementation
97 97
 * (useful for Spatial Join geoprocess, for example).
98
 *
98
 * 
99 99
 * It isnt persistent, and We've found some problems
100 100
 * with delete operations.
101
 *
102
 *
103
 *
104
 *
101
 * 
102
 * 
103
 * 
104
 * 
105 105
 * @author azabala
106 106
 * @author jyarza
107
 *
107
 * 
108 108
 */
109
public class JSIRTree extends AbstractFeatureIndexProvider implements FeatureIndexProvider {
109
public class JSIRTree extends AbstractFeatureIndexProvider implements
110
    FeatureIndexProvider {
110 111

  
111
	public static final String NAME = JSIRTree.class.getSimpleName();
112
    public static final String NAME = JSIRTree.class.getSimpleName();
112 113

  
113
	protected RTree rtree;
114
    protected RTree rtree;
114 115

  
115
	public JSIRTree() {
116
		rtree = new RTree();
117
	}
116
    public JSIRTree() {
117
        rtree = new RTree();
118
    }
118 119

  
120
    public void initialize() throws InitializeException {
121
        Properties props = new Properties();
122
        // props.setProperty("MaxNodeEntries", "500");
123
        // props.setProperty("MinNodeEntries", "200");
124
        rtree.init(props);
125
    }
119 126

  
120
	public void initialize() throws InitializeException {
121
		Properties props = new Properties();
122
//		props.setProperty("MaxNodeEntries", "500");
123
//		props.setProperty("MinNodeEntries", "200");
124
		rtree.init(props);
125
	}
127
    class ListIntProcedure implements IntProcedure {
126 128

  
127
	class ListIntProcedure implements IntProcedure{
128
		ArrayList solution = new ArrayList();
129
        ArrayList solution = new ArrayList();
129 130

  
130
		public boolean execute(int arg0) {
131
			solution.add(new Integer(arg0));
132
			return true;
133
		}
131
        public boolean execute(int arg0) {
132
            solution.add(new Integer(arg0));
133
            return true;
134
        }
134 135

  
135
		public List getSolution(){
136
			return solution;
137
		}
138
	}
136
        public List getSolution() {
137
            return solution;
138
        }
139
    }
139 140

  
140
	protected List findNNearest(int numberOfNearest, Point point){
141
		com.infomatiq.jsi.Point jsiPoint =
142
			new com.infomatiq.jsi.Point((float)point.getX(), (float)point.getY());
143
		return (List) rtree.nearest(jsiPoint, numberOfNearest);
144
	}
141
    protected List findNNearest(int numberOfNearest, Point point) {
142
        com.infomatiq.jsi.Point jsiPoint =
143
            new com.infomatiq.jsi.Point((float) point.getX(),
144
                (float) point.getY());
145
        return (List) rtree.nearest(jsiPoint, numberOfNearest);
146
    }
145 147

  
146
	public Iterator iterator(){
147
		return rtree.iterator();
148
	}
148
    public Iterator iterator() {
149
        return rtree.iterator();
150
    }
149 151

  
150
	public int size(){
151
		return rtree.size();
152
	}
152
    public int size() {
153
        return rtree.size();
154
    }
153 155

  
154
	protected Rectangle toJsiRect(Envelope env){
155
		Point min = env.getLowerCorner();
156
		Point max = env.getUpperCorner();
156
    protected Rectangle toJsiRect(Envelope env) {
157
        Point min = env.getLowerCorner();
158
        Point max = env.getUpperCorner();
157 159

  
158
		Rectangle jsiRect = new Rectangle((float)min.getX(),
159
				(float)min.getY(),
160
				(float)max.getX(),
161
				(float)max.getY());
162
		return jsiRect;
163
	}
160
        Rectangle jsiRect =
161
            new Rectangle((float) min.getX(), (float) min.getY(),
162
                (float) max.getX(), (float) max.getY());
163
        return jsiRect;
164
    }
164 165

  
165
	public void insert(Object value, FeatureReferenceProviderServices fref) {
166
		Envelope env = getEnvelope(value);
166
    public void insert(Object value, FeatureReferenceProviderServices fref) {
167
        Envelope env = getEnvelope(value);
167 168

  
168
		if (env == null) {
169
			throw new IllegalArgumentException("value is neither Geometry or Envelope");
170
		}
171
		
172
		Object oid = fref.getOID();
173
		if (!isCompatibleOID(oid)) {
174
			throw new IllegalArgumentException("OID type not compatible: " + oid.getClass().getName());
175
		}		
169
        if (env == null) {
170
            throw new IllegalArgumentException(
171
                "value is neither Geometry or Envelope");
172
        }
176 173

  
177
		rtree.add(toJsiRect(env), ((Number) oid).intValue());
178
	}
174
        Object oid = fref.getOID();
175
        if (!isCompatibleOID(oid)) {
176
            throw new IllegalArgumentException("OID type not compatible: "
177
                + oid.getClass().getName());
178
        }
179 179

  
180
	public void delete(Object value, FeatureReferenceProviderServices fref) {
181
		Envelope env = getEnvelope(value);
180
        rtree.add(toJsiRect(env), ((Number) oid).intValue());
181
    }
182 182

  
183
		if (env == null) {
184
			throw new IllegalArgumentException("value is neither Geometry or Envelope");
185
		}
186
		
187
		Object oid = fref.getOID();
188
		if (!isCompatibleOID(oid)) {
189
			throw new IllegalArgumentException("OID type not compatible: " + oid.getClass().getName());
190
		}
191
		
192
		rtree.delete(toJsiRect(env), ((Number) oid).intValue());
193
	}
183
    public void delete(Object value, FeatureReferenceProviderServices fref) {
184
        Envelope env = getEnvelope(value);
194 185

  
195
	public List match(Object value) throws FeatureIndexException {
196
		Envelope env = getEnvelope(value);
186
        if (env == null) {
187
            throw new IllegalArgumentException(
188
                "value is neither Geometry or Envelope");
189
        }
197 190

  
198
		if (env == null) {
199
			throw new IllegalArgumentException("value is neither Geometry or Envelope");
200
		}
201
		ListIntProcedure solution = new ListIntProcedure();
202
		rtree.intersects(toJsiRect(env), solution);
203
		return new LongList(solution.getSolution());
204
	}
191
        Object oid = fref.getOID();
192
        if (!isCompatibleOID(oid)) {
193
            throw new IllegalArgumentException("OID type not compatible: "
194
                + oid.getClass().getName());
195
        }
205 196

  
206
	public List nearest(int count, Object value) {
207
		if (value == null) {
208
			throw new IllegalArgumentException("value is null");
209
		}
210
		
211
		if (value instanceof Point) {
212
			Point p = (Point) value;
213
			com.infomatiq.jsi.Point jsiPoint =
214
				new com.infomatiq.jsi.Point((float) p.getDirectPosition().getOrdinate(0), (float) p.getDirectPosition().getOrdinate(1));
215
			return (List) rtree.nearest(jsiPoint, count);
216
		} else {
217
			Envelope env = getEnvelope(value);
197
        rtree.delete(toJsiRect(env), ((Number) oid).intValue());
198
    }
218 199

  
219
			if (env == null) {
220
				throw new IllegalArgumentException("value is neither Geometry or Envelope");
221
			}
222
			return new LongList((List) rtree.nearest(toJsiRect(env), count));
223
		}
224
	}
200
    public List match(Object value) throws FeatureIndexException {
201
        Envelope env = getEnvelope(value);
225 202

  
203
        if (env == null) {
204
            throw new IllegalArgumentException(
205
                "value is neither Geometry or Envelope");
206
        }
207
        ListIntProcedure solution = new ListIntProcedure();
208
        rtree.intersects(toJsiRect(env), solution);
209
        return new LongList(solution.getSolution());
210
    }
226 211

  
227
	public boolean isMatchSupported() {
228
		return true;
229
	}
212
    public List nearest(int count, Object value) {
213
        if (value == null) {
214
            throw new IllegalArgumentException("value is null");
215
        }
230 216

  
231
	public boolean isNearestSupported() {
232
		return true;
233
	}
217
        if (value instanceof Point) {
218
            Point p = (Point) value;
219
            com.infomatiq.jsi.Point jsiPoint =
220
                new com.infomatiq.jsi.Point((float) p.getDirectPosition()
221
                    .getOrdinate(0), (float) p.getDirectPosition().getOrdinate(
222
                    1));
223
            return (List) rtree.nearest(jsiPoint, count);
224
        } else {
225
            Envelope env = getEnvelope(value);
234 226

  
235
	public boolean isNearestToleranceSupported() {
236
		return false;
237
	}
227
            if (env == null) {
228
                throw new IllegalArgumentException(
229
                    "value is neither Geometry or Envelope");
230
            }
231
            return new LongList((List) rtree.nearest(toJsiRect(env), count));
232
        }
233
    }
238 234

  
239
	public boolean isRangeSupported() {
240
		return false;
241
	}
235
    public boolean isMatchSupported() {
236
        return true;
237
    }
242 238

  
243
	public List nearest(int count, Object value, Object tolerance)
244
			throws FeatureIndexException {
245
		throw new UnsupportedOperationException();
246
	}
239
    public boolean isNearestSupported() {
240
        return true;
241
    }
247 242

  
248
	public List range(Object value1, Object value2) throws FeatureIndexException {
249
		throw new UnsupportedOperationException();
250
	}
251
	
252
	/**
253
	 * Indicates whether the given OID's type is compatible
254
	 * with this provider
255
	 * 
256
	 * @param oid
257
	 * 
258
	 * @return
259
	 * 		true if this index provider supports the given oid type
260
	 */
261
	private boolean isCompatibleOID(Object oid) {
262
		if (!(oid instanceof Number)) {
263
			return false;
264
		}
265
		
266
		long num = ((Number) oid).longValue();
267
				 
268
		if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
269
			return false;
270
		}
271
		
272
		return true;
273
	}
274
	
275
	protected Envelope getEnvelope(Object value) {
276
		Envelope env = null;
277
		
278
		if (value instanceof Envelope) {
279
			env = (Envelope) value;
280
		} else if (value instanceof Geometry) {
281
			env = ((Geometry) value).getEnvelope();
282
		}
283
		return env;
284
	}	
243
    public boolean isNearestToleranceSupported() {
244
        return false;
245
    }
285 246

  
247
    public boolean isRangeSupported() {
248
        return false;
249
    }
250

  
251
    public List nearest(int count, Object value, Object tolerance)
252
        throws FeatureIndexException {
253
        throw new UnsupportedOperationException();
254
    }
255

  
256
    public List range(Object value1, Object value2)
257
        throws FeatureIndexException {
258
        throw new UnsupportedOperationException();
259
    }
260

  
261
    /**
262
     * Indicates whether the given OID's type is compatible
263
     * with this provider
264
     * 
265
     * @param oid
266
     * 
267
     * @return
268
     *         true if this index provider supports the given oid type
269
     */
270
    private boolean isCompatibleOID(Object oid) {
271
        if (!(oid instanceof Number)) {
272
            return false;
273
        }
274

  
275
        long num = ((Number) oid).longValue();
276

  
277
        if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
278
            return false;
279
        }
280

  
281
        return true;
282
    }
283

  
284
    protected Envelope getEnvelope(Object value) {
285
        Envelope env = null;
286

  
287
        if (value instanceof Envelope) {
288
            env = (Envelope) value;
289
        } else
290
            if (value instanceof Geometry) {
291
                env = ((Geometry) value).getEnvelope();
292
            }
293
        return env;
294
    }
295

  
286 296
}
287

  

Also available in: Unified diff