Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_spatialindex / src / org / gvsig / fmap / data / index / spatial / spatialindex / RTreeSptLib.java @ 23290

History | View | Annotate | Download (5.86 KB)

1
package org.gvsig.fmap.data.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.data.index.IndexException;
10
import org.gvsig.fmap.data.index.spatial.AbstractIntBasedSpatialIndex;
11
import org.gvsig.fmap.data.index.spatial.NearestNeighbourFinder;
12
import org.gvsig.fmap.data.index.spatial.PersistentSpatialIndex;
13
import org.gvsig.fmap.geom.primitive.Envelope;
14
import org.gvsig.fmap.geom.primitive.Point2D;
15

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

    
27
/**
28
 * <p>
29
 * RTree spatial index based in spatial index library: <br>
30
 * http://u-foria.org/marioh/spatialindex/index.html <br>
31
 * marioh@cs.ucr.edu
32
 * </p>
33
 * It has the problem that spatial index file creation is a bit slowly
34
 * (in comparation with other indexes).
35
 */
36
public class RTreeSptLib extends AbstractIntBasedSpatialIndex implements PersistentSpatialIndex,
37
                                                                        NearestNeighbourFinder{
38
        /**
39
         * Page size of associated file
40
         */
41
        private static final int defaultPageSize = 32 * 1024;
42
        private static final double defaultFillFactor = 0.85d;
43

    
44
        /**
45
         * Size of memory buffer of the index
46
         */
47
        private static final int BUFFER_SIZE = 25000;
48
        RTree rtree;
49
        String rtreeFile;
50
        IStorageManager diskfile;
51
        /**
52
         * Constructor
53
         * @param overwriteFile tells if we must override existing files.
54
         * If we are goint to create a new spatial index (or if we want to overwrite
55
         * an existing one) we must to use always 'true'. If we want to load
56
         * an existing spatial index file, overwrite must be 'false'
57
         * @param fileName name of the rtree spatial index file
58
         * @throws IndexException
59
         */
60

    
61
        public RTreeSptLib(boolean overwriteFile, String fileName)
62
                        throws IndexException {
63
                try {
64
                        this.rtreeFile = fileName;
65
                        PropertySet ps = new PropertySet();
66

    
67
                        // overwrite the file if it exists.
68
                        Boolean b = new Boolean(overwriteFile);
69
                        ps.setProperty("Overwrite", b);
70

    
71
                        // .idx and .dat extensions will be added.
72
                        ps.setProperty("FileName", fileName);
73

    
74
                        Integer i = new Integer(defaultPageSize);
75
                        ps.setProperty("PageSize", i);
76
                        diskfile = new DiskStorageManager(ps);
77
                        load();
78
                } catch (SecurityException e) {
79
                        throw new IndexException(e);
80
                } catch (FileNotFoundException e) {
81
                        throw new IndexException(e);
82
                } catch (IOException e) {
83
                        throw new IndexException(e);
84
                }
85
        }
86

    
87
        /**
88
         * If the spatial index file exists and has content
89
         */
90
        public boolean exists(){
91
                return (new File(rtreeFile+".dat").length() != 0);
92
        }
93

    
94

    
95
        class RTreeVisitor implements IVisitor{
96
                ArrayList solution = new ArrayList();
97
                public void visitNode(INode n) {
98
                }
99
                public void visitData(IData d) {
100
                        solution.add(new Integer(d.getIdentifier()));
101
                }
102
                public List getSolution(){
103
                        return solution;
104
                }
105
        }
106

    
107

    
108
        public List query(Envelope env) {
109
                List solution = null;
110
                Region region = createRegion(env);
111
                RTreeVisitor visitor = new RTreeVisitor();
112
                rtree.intersectionQuery(region,visitor);
113
                solution = visitor.getSolution();
114
                return solution;
115
        }
116

    
117
        public List containtmentQuery(Envelope env) {
118
                List solution = null;
119
                Region region = createRegion(env);
120
                RTreeVisitor visitor = new RTreeVisitor();
121
                rtree.containmentQuery(region,visitor);
122
                solution = visitor.getSolution();
123
                return solution;
124
        }
125

    
126
        /**
127
         * Warn! This RTree implemention doesnt care if 'index'
128
         * entry has been indexed yet
129
         */
130
        public void insert(Envelope env, int index) {
131
                rtree.insertData(null, createRegion(env), index);
132
        }
133

    
134
        private Region createRegion(Envelope env){
135
                return new Region(env.getLowerCorner(), env.getUpperCorner());
136
        }
137

    
138
        public void delete(Envelope env, int index) {
139
                rtree.deleteData(createRegion(env), index);
140
        }
141

    
142
        /**
143
         * Looks for N indexes nearest to the specified rect.
144
         * @param numberOfNearest
145
         * @param rect
146
         * @return
147
         */
148
        public List findNNearest(int numberOfNearest, Envelope env) {
149
                List solution = null;
150
                Region region = createRegion(env);
151
                RTreeVisitor visitor = new RTreeVisitor();
152
                rtree.nearestNeighborQuery(numberOfNearest, region,visitor);
153
                solution = visitor.getSolution();
154
                return solution;
155
        }
156

    
157
        /**
158
         * Looks for the N indexes nearest to the specified point
159
         * @param numberOfNearest
160
         * @param point
161
         * @return
162
         */
163
        public List findNNearest(int numberOfNearest, Point2D point) {
164
                List solution = null;
165
                spatialindex.spatialindex.Point sptPoint = new
166
                        spatialindex.spatialindex.Point(new double[]{point.getX(), point.getY()});
167
                RTreeVisitor visitor = new RTreeVisitor();
168
                rtree.nearestNeighborQuery(numberOfNearest, sptPoint,visitor);
169
                solution = visitor.getSolution();
170
                return solution;
171
        }
172

    
173

    
174

    
175
        public void flush(){
176
                rtree.flush();
177
        }
178

    
179
        public void load() {
180
//                 applies a main memory random buffer on top of the persistent
181
                // storage manager
182
                IBuffer buffer = new RandomEvictionsBuffer(diskfile, BUFFER_SIZE, false);
183

    
184
                // Create a new, empty, RTree with dimensionality 2, minimum load
185
                // 70%, using "file" as
186
                // the StorageManager and the RSTAR splitting policy.
187
                PropertySet ps2 = new PropertySet();
188

    
189
                Double f = new Double(defaultFillFactor);
190
                ps2.setProperty("FillFactor", f);
191

    
192
                Integer i = new Integer(2);
193
                ps2.setProperty("Dimension", i);
194

    
195
                File file = new File(rtreeFile + ".dat");
196
                if(file.length() != 0){
197
                        ps2.setProperty("IndexIdentifier", new Integer(1));
198
                }
199
                rtree = new RTree(ps2, buffer);
200
        }
201
        
202
        public void load(File f) throws IndexException {
203
                load();
204
        }
205
        
206
        public void flush(File f) throws IndexException {
207
                flush();
208
        }
209

    
210
        public void close() {
211
        }
212

    
213
        public File getFile() {
214
                return new File(this.rtreeFile);
215
        }
216
}