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 |
} |