Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / spatialindex / RTreeSptLib.java @ 5415

History | View | Annotate | Download (6.67 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
                } catch (FileNotFoundException e) {
76
                        throw new SpatialIndexException("El fichero no existe", e);
77
                } catch (IOException e) {
78
                        throw new SpatialIndexException("Error de I/O", e);
79
                }
80
        }
81
        
82
        /**
83
         * If the spatial index file exists and has content
84
         */
85
        public boolean exists(){
86
                return (new File(rtreeFile+".dat").length() != 0);
87
        }
88
        
89
        
90
        class RTreeVisitor implements IVisitor{
91
                ArrayList solution = new ArrayList();
92
                public void visitNode(INode n) {
93
                }
94
                public void visitData(IData d) {
95
                        solution.add(new Integer(d.getIdentifier()));
96
                }
97
                public List getSolution(){
98
                        return solution;
99
                }
100
        }
101

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

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

    
121
        /**
122
         * Warn! This RTree implemention doesnt care if 'index'
123
         * entry has been indexed yet
124
         */
125
        public void insert(Rectangle2D rect, int index) {        
126
                rtree.insertData(null, createRegion(rect), index);
127
        }
128
        
129
        private Region createRegion(Rectangle2D rect){
130
                Region region = null;
131
                double xmin = rect.getMinX();
132
                double ymin = rect.getMinY();
133
                double xmax = rect.getMaxX();
134
                double ymax = rect.getMaxY();
135
                double[] p1 = new double[]{xmin, ymin};
136
                double[] p2 = new double[]{xmax, ymax};
137
                region = new Region(p1, p2);
138
                return region;
139
        }
140

    
141
        public void delete(Rectangle2D rect, int index) {
142
                rtree.deleteData(createRegion(rect), index);
143
        }
144

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

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

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

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

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

    
220
                Double f = new Double(defaultFillFactor);
221
                ps2.setProperty("FillFactor", f);
222

    
223
                Integer i = new Integer(2);
224
                ps2.setProperty("Dimension", i);
225

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

    
233
        public void close() {
234
        }
235

    
236
}