Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dalindex / src / org / gvsig / fmap / dal / index / spatial / jsi / JSIRTree.java @ 36190

History | View | Annotate | Download (8.51 KB)

1
/*
2
 * Created on 15-may-2006
3
 *
4
 * gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib��ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
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
 */
65
package org.gvsig.fmap.dal.index.spatial.jsi;
66

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

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

    
76
import org.gvsig.fmap.dal.exception.DataException;
77
import org.gvsig.fmap.dal.exception.InitializeException;
78
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
79
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
80
import org.gvsig.fmap.dal.feature.spi.index.AbstractFeatureIndexProvider;
81
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProvider;
82
import org.gvsig.fmap.geom.Geometry;
83
import org.gvsig.fmap.geom.primitive.Envelope;
84
import org.gvsig.fmap.geom.primitive.Point;
85

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

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

    
115
    protected RTree rtree;
116

    
117
    public JSIRTree() {
118
    }
119

    
120
    public void initialize() throws InitializeException {
121
        this.rtree = createRTree();
122
    }
123

    
124
    private RTree createRTree() {
125
        RTree rtree = new RTree();
126
        Properties props = new Properties();
127
        // props.setProperty("MaxNodeEntries", "500");
128
        // props.setProperty("MinNodeEntries", "200");
129
        rtree.init(props);
130
        return rtree;
131
    }
132

    
133
    class ListIntProcedure implements IntProcedure {
134

    
135
        ArrayList solution = new ArrayList();
136

    
137
        public boolean execute(int arg0) {
138
            solution.add(new Integer(arg0));
139
            return true;
140
        }
141

    
142
        public List getSolution() {
143
            return solution;
144
        }
145
    }
146

    
147
    protected List findNNearest(int numberOfNearest, Point point) {
148
        com.infomatiq.jsi.Point jsiPoint =
149
            new com.infomatiq.jsi.Point((float) point.getX(),
150
                (float) point.getY());
151
        return (List) rtree.nearest(jsiPoint, numberOfNearest);
152
    }
153

    
154
    public Iterator iterator() {
155
        return rtree.iterator();
156
    }
157

    
158
    public int size() {
159
        return rtree.size();
160
    }
161

    
162
    protected Rectangle toJsiRect(Envelope env) {
163
        Point min = env.getLowerCorner();
164
        Point max = env.getUpperCorner();
165

    
166
        Rectangle jsiRect =
167
            new Rectangle((float) min.getX(), (float) min.getY(),
168
                (float) max.getX(), (float) max.getY());
169
        return jsiRect;
170
    }
171

    
172
    public void insert(Object value, FeatureReferenceProviderServices fref) {
173
        Envelope env = getEnvelope(value);
174

    
175
        if (env == null) {
176
            throw new IllegalArgumentException(
177
                "value is neither Geometry or Envelope");
178
        }
179

    
180
        Object oid = fref.getOID();
181
        if (!isCompatibleOID(oid)) {
182
            throw new IllegalArgumentException("OID type not compatible: "
183
                + oid.getClass().getName());
184
        }
185

    
186
        rtree.add(toJsiRect(env), ((Number) oid).intValue());
187
    }
188

    
189
    public void delete(Object value, FeatureReferenceProviderServices fref) {
190
        Envelope env = getEnvelope(value);
191

    
192
        if (env == null) {
193
            throw new IllegalArgumentException(
194
                "value is neither Geometry or Envelope");
195
        }
196

    
197
        Object oid = fref.getOID();
198
        if (!isCompatibleOID(oid)) {
199
            throw new IllegalArgumentException("OID type not compatible: "
200
                + oid.getClass().getName());
201
        }
202

    
203
        rtree.delete(toJsiRect(env), ((Number) oid).intValue());
204
    }
205

    
206
    public List match(Object value) throws FeatureIndexException {
207
        Envelope env = getEnvelope(value);
208

    
209
        if (env == null) {
210
            throw new IllegalArgumentException(
211
                "value is neither Geometry or Envelope");
212
        }
213
        ListIntProcedure solution = new ListIntProcedure();
214
        rtree.intersects(toJsiRect(env), solution);
215
        return new LongList(solution.getSolution());
216
    }
217

    
218
    public List nearest(int count, Object value) {
219
        if (value == null) {
220
            throw new IllegalArgumentException("value is null");
221
        }
222

    
223
        if (value instanceof Point) {
224
            Point p = (Point) value;
225
            com.infomatiq.jsi.Point jsiPoint =
226
                new com.infomatiq.jsi.Point((float) p.getDirectPosition()
227
                    .getOrdinate(0), (float) p.getDirectPosition().getOrdinate(
228
                    1));
229
            return (List) rtree.nearest(jsiPoint, count);
230
        } else {
231
            Envelope env = getEnvelope(value);
232

    
233
            if (env == null) {
234
                throw new IllegalArgumentException(
235
                    "value is neither Geometry or Envelope");
236
            }
237
            return new LongList((List) rtree.nearest(toJsiRect(env), count));
238
        }
239
    }
240

    
241
    public boolean isMatchSupported() {
242
        return true;
243
    }
244

    
245
    public boolean isNearestSupported() {
246
        return true;
247
    }
248

    
249
    public boolean isNearestToleranceSupported() {
250
        return false;
251
    }
252

    
253
    public boolean isRangeSupported() {
254
        return false;
255
    }
256

    
257
    public List nearest(int count, Object value, Object tolerance)
258
        throws FeatureIndexException {
259
        throw new UnsupportedOperationException();
260
    }
261

    
262
    public List range(Object value1, Object value2)
263
        throws FeatureIndexException {
264
        throw new UnsupportedOperationException();
265
    }
266

    
267
    /**
268
     * Indicates whether the given OID's type is compatible
269
     * with this provider
270
     * 
271
     * @param oid
272
     * 
273
     * @return
274
     *         true if this index provider supports the given oid type
275
     */
276
    private boolean isCompatibleOID(Object oid) {
277
        if (!(oid instanceof Number)) {
278
            return false;
279
        }
280

    
281
        long num = ((Number) oid).longValue();
282

    
283
        if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
284
            return false;
285
        }
286

    
287
        return true;
288
    }
289

    
290
    protected Envelope getEnvelope(Object value) {
291
        Envelope env = null;
292

    
293
        if (value instanceof Envelope) {
294
            env = (Envelope) value;
295
        } else
296
            if (value instanceof Geometry) {
297
                env = ((Geometry) value).getEnvelope();
298
            }
299
        return env;
300
    }
301

    
302
    public void clear() throws DataException {
303
        rtree = createRTree();
304
    }
305
}