Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dalindex / src / org / gvsig / fmap / dal / index / spatial / spatialindex / SPTLIBRTree.java @ 25590

History | View | Annotate | Download (7.19 KB)

1
package org.gvsig.fmap.dal.index.spatial.spatialindex;
2

    
3
import java.io.File;
4
import java.io.FileNotFoundException;
5
import java.io.IOException;
6
import java.util.ArrayList;
7
import java.util.List;
8

    
9
import org.gvsig.fmap.dal.exception.InitializeException;
10
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
11
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
12
import org.gvsig.fmap.dal.feature.spi.index.AbstractFeatureIndexProvider;
13
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProvider;
14
import org.gvsig.fmap.geom.Geometry;
15
import org.gvsig.fmap.geom.primitive.Envelope;
16
import org.gvsig.fmap.geom.primitive.Point2D;
17

    
18
import spatialindex.rtree.RTree;
19
import spatialindex.spatialindex.IData;
20
import spatialindex.spatialindex.INode;
21
import spatialindex.spatialindex.IVisitor;
22
import spatialindex.spatialindex.Region;
23
import spatialindex.storagemanager.DiskStorageManager;
24
import spatialindex.storagemanager.IBuffer;
25
import spatialindex.storagemanager.IStorageManager;
26
import spatialindex.storagemanager.PropertySet;
27
import spatialindex.storagemanager.RandomEvictionsBuffer;
28

    
29
/**
30
 * <p>
31
 * RTree spatial index based in spatial index library: <br>
32
 * http://u-foria.org/marioh/spatialindex/index.html <br>
33
 * marioh@cs.ucr.edu
34
 * </p>
35
 * It has the problem that spatial index file creation is a bit slowly (in
36
 * comparation with other indexes).
37
 */
38
public class SPTLIBRTree extends AbstractFeatureIndexProvider implements
39
                FeatureIndexProvider {
40

    
41
        public static final String NAME = "RTreeSptLib";
42
        /**
43
         * Page size of associated file
44
         */
45
        private static final int defaultPageSize = 32 * 1024;
46
        private static final double defaultFillFactor = 0.85d;
47

    
48
        /**
49
         * Size of memory buffer of the index
50
         */
51
        private static final int BUFFER_SIZE = 25000;
52
        RTree rtree;
53
        String fileName;
54
        IStorageManager diskfile;
55

    
56
        public SPTLIBRTree() {
57

    
58
        }
59

    
60
        public void initialize() throws InitializeException {
61
                try {
62
                        PropertySet ps = new PropertySet();
63
                        ps.setProperty("Overwrite", new Boolean(false));
64
                        // .idx and .dat extensions will be added.
65
                        fileName = getFeatureIndexProviderServices().getNewFileName(null, null);
66
                        ps.setProperty("FileName", fileName);
67
                        ps.setProperty("PageSize", new Integer(defaultPageSize));
68
                        diskfile = new DiskStorageManager(ps);
69
                        load();
70
                } catch (SecurityException e) {
71
                        throw new InitializeException(e);
72
                } catch (FileNotFoundException e) {
73
                        throw new InitializeException(e);
74
                } catch (IOException e) {
75
                        throw new InitializeException(e);
76
                }
77
        }
78

    
79
        /**
80
         * If the spatial index file exists and has content
81
         */
82
        public boolean exists() {
83
                return (new File(fileName + ".dat").length() != 0);
84
        }
85

    
86
        class RTreeVisitor implements IVisitor {
87
                ArrayList solution = new ArrayList();
88

    
89
                public void visitNode(INode n) {
90
                }
91

    
92
                public void visitData(IData d) {
93
                        solution.add(new Integer(d.getIdentifier()));
94
                }
95

    
96
                public List getSolution() {
97
                        return solution;
98
                }
99
        }
100

    
101
        public List containtmentQuery(Envelope env) {
102
                List solution = null;
103
                Region region = createRegion(env);
104
                RTreeVisitor visitor = new RTreeVisitor();
105
                rtree.containmentQuery(region, visitor);
106
                solution = visitor.getSolution();
107
                return solution;
108
        }
109

    
110
        /**
111
         * Warn! This RTree implemention doesnt care if 'index' entry has been
112
         * indexed yet
113
         */
114
        public void insert(Envelope env, int index) {
115
                rtree.insertData(null, createRegion(env), index);
116
        }
117

    
118
        private Region createRegion(Envelope env) {
119
                return new Region(env.getLowerCorner(), env.getUpperCorner());
120
        }
121

    
122
        /**
123
         * Looks for N indexes nearest to the specified rect.
124
         *
125
         * @param numberOfNearest
126
         * @param rect
127
         * @return
128
         */
129
        public List findNNearest(int numberOfNearest, Envelope env) {
130
                List solution = null;
131
                Region region = createRegion(env);
132
                RTreeVisitor visitor = new RTreeVisitor();
133
                rtree.nearestNeighborQuery(numberOfNearest, region, visitor);
134
                solution = visitor.getSolution();
135
                return solution;
136
        }
137

    
138
        /**
139
         * Looks for the N indexes nearest to the specified point
140
         *
141
         * @param numberOfNearest
142
         * @param point
143
         * @return
144
         */
145
        public List findNNearest(int numberOfNearest, Point2D point) {
146
                List solution = null;
147
                spatialindex.spatialindex.Point sptPoint = new spatialindex.spatialindex.Point(
148
                                new double[] { point.getX(), point.getY() });
149
                RTreeVisitor visitor = new RTreeVisitor();
150
                rtree.nearestNeighborQuery(numberOfNearest, sptPoint, visitor);
151
                solution = visitor.getSolution();
152
                return solution;
153
        }
154

    
155
        public void flush() {
156
                rtree.flush();
157
        }
158

    
159
        public void load() {
160
                // applies a main memory random buffer on top of the persistent
161
                // storage manager
162
                IBuffer buffer = new RandomEvictionsBuffer(diskfile, BUFFER_SIZE, false);
163

    
164
                // Create a new, empty, RTree with dimensionality 2, minimum load
165
                // 70%, using "file" as
166
                // the StorageManager and the RSTAR splitting policy.
167
                PropertySet ps2 = new PropertySet();
168

    
169
                Double f = new Double(defaultFillFactor);
170
                ps2.setProperty("FillFactor", f);
171

    
172
                Integer i = new Integer(2);
173
                ps2.setProperty("Dimension", i);
174

    
175
                File file = new File(fileName + ".dat");
176
                if (file.length() != 0) {
177
                        ps2.setProperty("IndexIdentifier", new Integer(1));
178
                }
179
                rtree = new RTree(ps2, buffer);
180
        }
181

    
182
        public void load(File f) throws FeatureIndexException {
183
                load();
184
        }
185

    
186
        public void flush(File f) throws FeatureIndexException {
187
                flush();
188
        }
189

    
190
        public void close() {
191
        }
192

    
193
        public File getFile() {
194
                return new File(fileName + ".dat");
195
        }
196

    
197
        public void delete(Object value, FeatureReferenceProviderServices fref) {
198
                rtree.deleteData(createRegion((Envelope) value), ((Integer) fref
199
                                .getOID()).intValue());
200
        }
201

    
202
        public void insert(Object value, FeatureReferenceProviderServices fref) {
203
                Envelope env = null;
204
                if (value instanceof Envelope) {
205
                        env = (Envelope) value;
206
                } else if (value instanceof Geometry) {
207
                        env = ((Geometry) value).getEnvelope();
208
                }
209
                rtree.insertData(null, createRegion(env), ((Integer) fref
210
                                .getOID()).intValue());
211
        }
212
        
213
        public List match(Object value) throws FeatureIndexException {
214
                List solution = null;
215
                Region region = createRegion((Envelope) value);
216
                RTreeVisitor visitor = new RTreeVisitor();
217
                rtree.intersectionQuery(region, visitor);
218
                solution = visitor.getSolution();
219
                return solution;
220
        }
221

    
222
        public List match(Object min, Object max) {
223
                throw new UnsupportedOperationException();
224
        }
225

    
226
        public List nearest(int count, Object value) throws FeatureIndexException {
227
                if (value instanceof Envelope) {
228
                        return this.findNNearest(count, (Envelope) value);
229
                } else if (value instanceof Point2D) {
230
                        return this.findNNearest(count, (Point2D) value);
231
                } else if (value instanceof Geometry) {
232
                        return this.findNNearest(count, ((Geometry) value).getEnvelope());
233
                } else {
234
                        throw new IllegalArgumentException ("value must be either an Envelope or either a Point2D");
235
                }
236
        }
237

    
238
        public boolean isMatchSupported() {
239
                return true;
240
        }
241

    
242
        public boolean isNearestSupported() {
243
                return true;
244
        }
245

    
246
        public boolean isNearestToleranceSupported() {
247
                return false;
248
        }
249

    
250
        public boolean isRangeSupported() {
251
                // TODO Auto-generated method stub
252
                return false;
253
        }
254

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

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