Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / JSIRSpatialIndexProvider.java @ 44111

History | View | Annotate | Download (6.72 KB)

1 41239 nbrodin
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.feature.impl;
25
26
import java.util.ArrayList;
27
import java.util.List;
28
import java.util.Properties;
29
30
import org.gvsig.fmap.dal.exception.DataException;
31
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
32
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
33
import org.gvsig.fmap.dal.feature.spi.index.AbstractFeatureIndexProvider;
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.primitive.Envelope;
36
import org.gvsig.fmap.geom.primitive.Point;
37
38
import com.infomatiq.jsi.IntProcedure;
39
import com.infomatiq.jsi.Rectangle;
40
import com.infomatiq.jsi.rtree.RTree;
41
42
public class JSIRSpatialIndexProvider extends AbstractFeatureIndexProvider {
43
44
        public static final String NAME = "JSIRSpatialIndexProvider";
45
46
        private RTree rtree = null;
47
48
        class ListIntProcedure implements IntProcedure {
49
50
        List solution = new ArrayList();
51
52
        public boolean execute(int arg0) {
53
            solution.add(new Integer(arg0));
54
            return true;
55
        }
56
57
        public List getSolution() {
58
            return solution;
59
        }
60
    }
61
62
        public JSIRSpatialIndexProvider() {
63
64
        }
65
66
    public void initialize() {
67
            try {
68
                    this.rtree = createRTree();
69
                } catch (Exception e) {
70
                        throw new RuntimeException();
71
                }
72
    }
73
74
    private RTree createRTree() {
75
        RTree rtree = new RTree();
76
        Properties props = new Properties();
77
        // props.setProperty("MaxNodeEntries", "500");
78
        // props.setProperty("MinNodeEntries", "200");
79
        rtree.init(props);
80
        return rtree;
81
    }
82
83
    public void insert(Object value, FeatureReferenceProviderServices fref) {
84
        Envelope env = getEnvelope(value);
85
86
        if (env == null) {
87
            throw new IllegalArgumentException(
88
                "value is neither Geometry or Envelope");
89
        }
90
91
        Object oid = fref.getOID();
92
        if (!isCompatibleOID(oid)) {
93
            throw new IllegalArgumentException("OID type not compatible: "
94
                + oid.getClass().getName());
95
        }
96
97
        rtree.add(toJsiRect(env), ((Number) oid).intValue());
98
    }
99
100
    public void delete(Object value, FeatureReferenceProviderServices fref) {
101
        Envelope env = getEnvelope(value);
102
103
        if (env == null) {
104
            throw new IllegalArgumentException(
105
                "value is neither Geometry or Envelope");
106
        }
107
108
        Object oid = fref.getOID();
109
        if (!isCompatibleOID(oid)) {
110
            throw new IllegalArgumentException("OID type not compatible: "
111
                + oid.getClass().getName());
112
        }
113
114
        rtree.delete(toJsiRect(env), ((Number) oid).intValue());
115
    }
116
117
    public List match(Object value) throws FeatureIndexException {
118
        Envelope env = getEnvelope(value);
119
120
        if (env == null) {
121
            throw new IllegalArgumentException(
122
                "value is neither Geometry or Envelope");
123
        }
124
        ListIntProcedure solution = new ListIntProcedure();
125
        rtree.intersects(toJsiRect(env), solution);
126
        return new LongList(solution.getSolution());
127
    }
128
129
    public List match(Object min, Object max) {
130
        throw new UnsupportedOperationException(
131
            "Can't perform this kind of search.");
132
    }
133
134
    public List nearest(int count, Object value) {
135
        if (value == null) {
136
            throw new IllegalArgumentException("value is null");
137
        }
138
139
        if (value instanceof Point) {
140
            Point p = (Point) value;
141
            com.infomatiq.jsi.Point jsiPoint =
142
                new com.infomatiq.jsi.Point((float) p.getDirectPosition()
143
                    .getOrdinate(0), (float) p.getDirectPosition().getOrdinate(
144
                    1));
145
            return (List) rtree.nearest(jsiPoint, count);
146
        } else {
147
            Envelope env = getEnvelope(value);
148
149
            if (env == null) {
150
                throw new IllegalArgumentException(
151
                    "value is neither Geometry or Envelope");
152
            }
153
            return new LongList((List) rtree.nearest(toJsiRect(env), count));
154
        }
155
    }
156
157
    public boolean isMatchSupported() {
158
        return true;
159
    }
160
161
    public boolean isNearestSupported() {
162
        return true;
163
    }
164
165
    public boolean isNearestToleranceSupported() {
166
        return false;
167
    }
168
169
    public boolean isRangeSupported() {
170
        return false;
171
    }
172
173
    public List nearest(int count, Object value, Object tolerance)
174
        throws FeatureIndexException {
175
        throw new UnsupportedOperationException();
176
    }
177
178
    public List range(Object value1, Object value2)
179
        throws FeatureIndexException {
180
        throw new UnsupportedOperationException();
181
    }
182
183
    /**
184
     * Indicates whether the given OID's type is compatible
185
     * with this provider
186
     *
187
     * @param oid
188
     *
189
     * @return
190
     *         true if this index provider supports the given oid type
191
     */
192
    private boolean isCompatibleOID(Object oid) {
193
        if (!(oid instanceof Number)) {
194
            return false;
195
        }
196
197
        long num = ((Number) oid).longValue();
198
199
        if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
200
            return false;
201
        }
202
203
        return true;
204
    }
205
206
    protected Envelope getEnvelope(Object value) {
207
        Envelope env = null;
208
209
        if (value instanceof Envelope) {
210
            env = (Envelope) value;
211
        } else
212
            if (value instanceof Geometry) {
213
                env = ((Geometry) value).getEnvelope();
214
            }
215
        return env;
216
    }
217
218
    protected Rectangle toJsiRect(Envelope env) {
219
        Point min = env.getLowerCorner();
220
        Point max = env.getUpperCorner();
221
222
        Rectangle jsiRect =
223
            new Rectangle((float) min.getX(), (float) min.getY(),
224
                (float) max.getX(), (float) max.getY());
225
        return jsiRect;
226
    }
227
228
    public void clear() throws DataException {
229
        rtree = createRTree();
230
    }
231
 }