root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / spatialindex / RTreeSptLib.java @ 11051
History | View | Annotate | Download (6.78 KB)
1 | 4979 | azabala | 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 | 5415 | azabala | * It has the problem that spatial index file creation is a bit slowly
|
29 | * (in comparation with other indexes).
|
||
30 | 4979 | azabala | */
|
31 | public class RTreeSptLib implements IPersistentSpatialIndex, |
||
32 | 5009 | azabala | INearestNeighbourFinder{ |
33 | 5415 | azabala | /**
|
34 | * Page size of associated file
|
||
35 | */
|
||
36 | private static final int defaultPageSize = 32 * 1024; |
||
37 | 4979 | azabala | private static final double defaultFillFactor = 0.85d; |
38 | 10627 | caballero | |
39 | 5415 | azabala | /**
|
40 | * Size of memory buffer of the index
|
||
41 | */
|
||
42 | private static final int BUFFER_SIZE = 25000; |
||
43 | 4979 | azabala | 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 | 10627 | caballero | |
56 | 4979 | azabala | 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 | 5415 | azabala | load(); |
73 | 4979 | azabala | } catch (SecurityException e) { |
74 | 10627 | caballero | //throw new SpatialIndexException("No tenemos permisos de escritura?", e);
|
75 | throw new SpatialIndexException(); |
||
76 | 4979 | azabala | } catch (FileNotFoundException e) { |
77 | 10627 | caballero | //throw new SpatialIndexException("El fichero no existe", e);
|
78 | throw new SpatialIndexException(); |
||
79 | 4979 | azabala | } catch (IOException e) { |
80 | 10627 | caballero | //throw new SpatialIndexException("Error de I/O", e);
|
81 | throw new SpatialIndexException(); |
||
82 | 4979 | azabala | } |
83 | } |
||
84 | 10627 | caballero | |
85 | 4979 | azabala | /**
|
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 | 10627 | caballero | |
92 | |||
93 | 4979 | azabala | 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 | 10627 | caballero | |
106 | 4979 | azabala | 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 | 10627 | caballero | public void insert(Rectangle2D rect, int index) { |
129 | 4979 | azabala | rtree.insertData(null, createRegion(rect), index);
|
130 | } |
||
131 | 10627 | caballero | |
132 | 4979 | azabala | 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 | 10627 | caballero | |
180 | |||
181 | 4979 | azabala | public void flush(){ |
182 | rtree.flush(); |
||
183 | } |
||
184 | 10627 | caballero | |
185 | 4979 | azabala | 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 | 10627 | caballero | |
206 | 4979 | azabala | } catch (SpatialIndexException e) {
|
207 | e.printStackTrace(); |
||
208 | System.exit(-1); |
||
209 | } |
||
210 | 10627 | caballero | |
211 | 4979 | azabala | } |
212 | |||
213 | 5415 | azabala | public void load() { |
214 | 4979 | azabala | // applies a main memory random buffer on top of the persistent
|
215 | // storage manager
|
||
216 | 5415 | azabala | IBuffer buffer = new RandomEvictionsBuffer(diskfile, BUFFER_SIZE, false); |
217 | 4979 | azabala | |
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 | 5415 | azabala | public void close() { |
237 | } |
||
238 | |||
239 | 4979 | azabala | } |