Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / spatialindex / RTreeSptLib.java @ 10627

History | View | Annotate | Download (6.78 KB)

1
package com.iver.cit.gvsig.fmap.spatialindex;
2

    
3
import java.awt.Point;
4
import java.awt.geom.Rectangle2D;
5
import java.io.File;
6
import java.io.FileNotFoundException;
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.List;
10

    
11
import spatialindex.rtree.RTree;
12
import spatialindex.spatialindex.IData;
13
import spatialindex.spatialindex.INode;
14
import spatialindex.spatialindex.IVisitor;
15
import spatialindex.spatialindex.Region;
16
import spatialindex.storagemanager.DiskStorageManager;
17
import spatialindex.storagemanager.IBuffer;
18
import spatialindex.storagemanager.IStorageManager;
19
import spatialindex.storagemanager.PropertySet;
20
import spatialindex.storagemanager.RandomEvictionsBuffer;
21

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

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

    
56
        public RTreeSptLib(boolean overwriteFile, String fileName)
57
                        throws SpatialIndexException {
58
                try {
59
                        this.rtreeFile = fileName;
60
                        PropertySet ps = new PropertySet();
61

    
62
                        // overwrite the file if it exists.
63
                        Boolean b = new Boolean(overwriteFile);
64
                        ps.setProperty("Overwrite", b);
65

    
66
                        // .idx and .dat extensions will be added.
67
                        ps.setProperty("FileName", fileName);
68

    
69
                        Integer i = new Integer(defaultPageSize);
70
                        ps.setProperty("PageSize", i);
71
                        diskfile = new DiskStorageManager(ps);
72
                        load();
73
                } catch (SecurityException e) {
74
                        //throw new SpatialIndexException("No tenemos permisos de escritura?", e);
75
                        throw new SpatialIndexException();
76
                } catch (FileNotFoundException e) {
77
                        //throw new SpatialIndexException("El fichero no existe", e);
78
                        throw new SpatialIndexException();
79
                } catch (IOException e) {
80
                        //throw new SpatialIndexException("Error de I/O", e);
81
                        throw new SpatialIndexException();
82
                }
83
        }
84

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

    
92

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

    
105

    
106
        public List query(Rectangle2D rect) {
107
                List solution = null;
108
                Region region = createRegion(rect);
109
                RTreeVisitor visitor = new RTreeVisitor();
110
                rtree.intersectionQuery(region,visitor);
111
                solution = visitor.getSolution();
112
                return solution;
113
        }
114

    
115
        public List containtmentQuery(Rectangle2D rect) {
116
                List solution = null;
117
                Region region = createRegion(rect);
118
                RTreeVisitor visitor = new RTreeVisitor();
119
                rtree.containmentQuery(region,visitor);
120
                solution = visitor.getSolution();
121
                return solution;
122
        }
123

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

    
132
        private Region createRegion(Rectangle2D rect){
133
                Region region = null;
134
                double xmin = rect.getMinX();
135
                double ymin = rect.getMinY();
136
                double xmax = rect.getMaxX();
137
                double ymax = rect.getMaxY();
138
                double[] p1 = new double[]{xmin, ymin};
139
                double[] p2 = new double[]{xmax, ymax};
140
                region = new Region(p1, p2);
141
                return region;
142
        }
143

    
144
        public void delete(Rectangle2D rect, int index) {
145
                rtree.deleteData(createRegion(rect), index);
146
        }
147

    
148
        /**
149
         * Looks for N indexes nearest to the specified rect.
150
         * @param numberOfNearest
151
         * @param rect
152
         * @return
153
         */
154
        public List findNNearest(int numberOfNearest, Rectangle2D rect) {
155
                List solution = null;
156
                Region region = createRegion(rect);
157
                RTreeVisitor visitor = new RTreeVisitor();
158
                rtree.nearestNeighborQuery(numberOfNearest, region,visitor);
159
                solution = visitor.getSolution();
160
                return solution;
161
        }
162

    
163
        /**
164
         * Looks for the N indexes nearest to the specified point
165
         * @param numberOfNearest
166
         * @param point
167
         * @return
168
         */
169
        public List findNNearest(int numberOfNearest, Point point) {
170
                List solution = null;
171
                spatialindex.spatialindex.Point sptPoint = new
172
                        spatialindex.spatialindex.Point(new double[]{point.x, point.y});
173
                RTreeVisitor visitor = new RTreeVisitor();
174
                rtree.nearestNeighborQuery(numberOfNearest, sptPoint,visitor);
175
                solution = visitor.getSolution();
176
                return solution;
177
        }
178

    
179

    
180

    
181
        public void flush(){
182
                rtree.flush();
183
        }
184

    
185
        public static void main(String[] args){
186
                try {
187
                        File file = new File("c:/kk/pruebartree.idx");
188
                        System.out.println(file.getName());
189
                        RTreeSptLib rtree = new RTreeSptLib(false, "c:/pruebartree");
190
                        if(rtree.exists()){
191
                                System.out.println("Fichero ya creado");
192
                                List items = rtree.query(new Rectangle2D.Double(399,0,400,4000));
193
                                for(int i = 0; i < items.size(); i++){
194
                                        System.out.println((Integer)items.get(i));
195
                                }
196
                        }
197
                        rtree.insert(new Rectangle2D.Double(0,0, 400, 4000), 1);
198
                        rtree.insert(new Rectangle2D.Double(0,110, 2000, 5000), 2);
199
                        rtree.insert(new Rectangle2D.Double(110,0, 4000, 4000), 3);
200
                        rtree.insert(new Rectangle2D.Double(10,110, 8000, 111000), 4);
201
                        rtree.insert(new Rectangle2D.Double(1110,1110, 40, 22200), 5);
202
                        rtree.insert(new Rectangle2D.Double(0,0, 40, 48540), 6);
203
                        rtree.insert(new Rectangle2D.Double(0,0, 6330, 56400), 7);
204
                        rtree.flush();
205

    
206
                } catch (SpatialIndexException e) {
207
                        e.printStackTrace();
208
                        System.exit(-1);
209
                }
210

    
211
        }
212

    
213
        public void load() {
214
//                 applies a main memory random buffer on top of the persistent
215
                // storage manager
216
                IBuffer buffer = new RandomEvictionsBuffer(diskfile, BUFFER_SIZE, false);
217

    
218
                // Create a new, empty, RTree with dimensionality 2, minimum load
219
                // 70%, using "file" as
220
                // the StorageManager and the RSTAR splitting policy.
221
                PropertySet ps2 = new PropertySet();
222

    
223
                Double f = new Double(defaultFillFactor);
224
                ps2.setProperty("FillFactor", f);
225

    
226
                Integer i = new Integer(2);
227
                ps2.setProperty("Dimension", i);
228

    
229
                File file = new File(rtreeFile + ".dat");
230
                if(file.length() != 0){
231
                        ps2.setProperty("IndexIdentifier", new Integer(1));
232
                }
233
                rtree = new RTree(ps2, buffer);
234
        }
235

    
236
        public void close() {
237
        }
238

    
239
}