Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dalindex / src / org / gvsig / fmap / dal / index / spatial / jsi / JSIRTree.java @ 25763

History | View | Annotate | Download (7.4 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 org.gvsig.fmap.dal.exception.InitializeException;
73
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
74
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
75
import org.gvsig.fmap.dal.feature.spi.index.AbstractFeatureIndexProvider;
76
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProvider;
77
import org.gvsig.fmap.geom.Geometry;
78
import org.gvsig.fmap.geom.primitive.Envelope;
79
import org.gvsig.fmap.geom.primitive.Point;
80
import org.gvsig.fmap.geom.primitive.Point2D;
81

    
82
import com.infomatiq.jsi.IntProcedure;
83
import com.infomatiq.jsi.Rectangle;
84
import com.infomatiq.jsi.rtree.RTree;
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 FeatureIndexProvider {
111

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

    
114
        private RTree rtree;
115

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

    
120

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

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

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

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

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

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

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

    
155
        protected Rectangle toJsiRect(Envelope env){
156
                double[] min = env.getLowerCorner();
157
                double[] max = env.getUpperCorner();
158

    
159
                Rectangle jsiRect = new Rectangle((float)min[0],
160
                                (float)min[1],
161
                                (float)max[0],
162
                                (float)max[1]);
163
                return jsiRect;
164
        }
165

    
166
        public void insert(Object value, FeatureReferenceProviderServices fref) {
167
                if (value == null) {
168
                        throw new IllegalArgumentException("value is null");
169
                }
170
                if (!(value instanceof Geometry)) {
171
                        throw new IllegalArgumentException("Received " + value.getClass().getName() + " but expected org.gvsig.fmap.geom.Geometry.");
172
                }
173
                if (!(fref.getOID() instanceof Integer)) {
174
                        throw new IllegalArgumentException("Reference Id is of type "
175
                                        + fref.getOID().getClass().getName()
176
                                        + " but expected an Integer.");
177
                }
178

    
179
                Envelope env = null;
180

    
181
                if (value instanceof Envelope) {
182
                        env = (Envelope) value;
183
                } else {
184
                        env = ((Geometry) value).getEnvelope();
185
                }
186
                rtree.add(toJsiRect(env), ((Integer) fref.getOID())
187
                                .intValue());
188
        }
189

    
190
        public void delete(Object value, FeatureReferenceProviderServices fref) {
191
                if (value == null) {
192
                        throw new IllegalArgumentException("value is null");
193
                }
194
                if (!(value instanceof Envelope)) {
195
                        throw new IllegalArgumentException("Received " + value.getClass().getName() + " but expected org.gvsig.fmap.geom.primitive.Envelope.");
196
                }
197
                rtree.delete(toJsiRect(((org.gvsig.fmap.geom.Geometry) value).getEnvelope()), ((Integer) fref.getOID())
198
                                .intValue());
199
        }
200

    
201
        public List match(Object value) throws FeatureIndexException {
202
                if (value == null) {
203
                        throw new IllegalArgumentException("value is null");
204
                }
205
                if (!(value instanceof Envelope)) {
206
                        throw new IllegalArgumentException("Received " + value.getClass().getName() + " but expected org.gvsig.fmap.geom.primitive.Envelope.");
207
                }
208
                ListIntProcedure solution = new ListIntProcedure();
209
                Envelope env = null;
210
                if (value instanceof Envelope) {
211
                        env = (Envelope) value;
212
                } else if (value instanceof Geometry) {
213
                        env = ((Geometry) value).getEnvelope();
214
                }
215
                rtree.intersects(toJsiRect(env), solution);
216
                return new LongList(solution.getSolution());
217
        }
218

    
219
        public List match(Object min, Object max) {
220
                throw new UnsupportedOperationException();
221
        }
222

    
223
        public List nearest(int count, Object value) {
224
                if (value == null) {
225
                        throw new IllegalArgumentException("value is null");
226
                }
227
                if (value instanceof Envelope) {
228
                        return (List) rtree.nearest(toJsiRect((Envelope) value), count);
229

    
230
                } else if (value instanceof Point) {
231
                        Point p = (Point) value;
232
                        com.infomatiq.jsi.Point jsiPoint =
233
                                new com.infomatiq.jsi.Point((float) p.getDirectPosition().getOrdinate(0), (float) p.getDirectPosition().getOrdinate(1));
234
                        return (List) rtree.nearest(jsiPoint, count);
235
                }
236
                throw new IllegalArgumentException("Received " + value.getClass().getName() + " but expected org.gvsig.fmap.geom.primitive.Envelope.");
237
        }
238

    
239

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

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

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

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

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

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

    
265
}
266