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 / indexes / jsir / JSIRSpatialIndexProvider.java @ 44158

History | View | Annotate | Download (6.67 KB)

1
/**
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.indexes.jsir;
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
        private RTree rtree = null;
45
        
46
        class ListIntProcedure implements IntProcedure {
47

    
48
        List solution = new ArrayList();
49

    
50
        public boolean execute(int arg0) {
51
            solution.add(new Integer(arg0));
52
            return true;
53
        }
54

    
55
        public List getSolution() {
56
            return solution;
57
        }
58
    }
59
        
60
        public JSIRSpatialIndexProvider() {
61
                
62
        }
63
        
64
    public void initialize() {
65
            try {
66
                    this.rtree = createRTree();
67
                } catch (Exception e) {
68
                        throw new RuntimeException();
69
                }
70
    }
71
    
72
    private RTree createRTree() {
73
        RTree rtree = new RTree();
74
        Properties props = new Properties();
75
        // props.setProperty("MaxNodeEntries", "500");
76
        // props.setProperty("MinNodeEntries", "200");
77
        rtree.init(props);
78
        return rtree;
79
    }
80

    
81
    public void insert(Object value, FeatureReferenceProviderServices fref) {
82
        Envelope env = getEnvelope(value);
83

    
84
        if (env == null) {
85
            throw new IllegalArgumentException(
86
                "value is neither Geometry or Envelope");
87
        }
88

    
89
        Object oid = fref.getOID();
90
        if (!isCompatibleOID(oid)) {
91
            throw new IllegalArgumentException("OID type not compatible: "
92
                + oid.getClass().getName());
93
        }
94

    
95
        rtree.add(toJsiRect(env), ((Number) oid).intValue());
96
    }
97

    
98
    public void delete(Object value, FeatureReferenceProviderServices fref) {
99
        Envelope env = getEnvelope(value);
100

    
101
        if (env == null) {
102
            throw new IllegalArgumentException(
103
                "value is neither Geometry or Envelope");
104
        }
105

    
106
        Object oid = fref.getOID();
107
        if (!isCompatibleOID(oid)) {
108
            throw new IllegalArgumentException("OID type not compatible: "
109
                + oid.getClass().getName());
110
        }
111

    
112
        rtree.delete(toJsiRect(env), ((Number) oid).intValue());
113
    }
114

    
115
    public List match(Object value) throws FeatureIndexException {
116
        Envelope env = getEnvelope(value);
117

    
118
        if (env == null) {
119
            throw new IllegalArgumentException(
120
                "value is neither Geometry or Envelope");
121
        }
122
        ListIntProcedure solution = new ListIntProcedure();
123
        rtree.intersects(toJsiRect(env), solution);
124
        return new LongList(solution.getSolution());
125
    }
126

    
127
    public List match(Object min, Object max) {
128
        throw new UnsupportedOperationException(
129
            "Can't perform this kind of search.");
130
    }
131

    
132
    public List nearest(int count, Object value) {
133
        if (value == null) {
134
            throw new IllegalArgumentException("value is null");
135
        }
136

    
137
        if (value instanceof Point) {
138
            Point p = (Point) value;
139
            com.infomatiq.jsi.Point jsiPoint =
140
                new com.infomatiq.jsi.Point((float) p.getDirectPosition()
141
                    .getOrdinate(0), (float) p.getDirectPosition().getOrdinate(
142
                    1));
143
            return (List) rtree.nearest(jsiPoint, count);
144
        } else {
145
            Envelope env = getEnvelope(value);
146

    
147
            if (env == null) {
148
                throw new IllegalArgumentException(
149
                    "value is neither Geometry or Envelope");
150
            }
151
            return new LongList((List) rtree.nearest(toJsiRect(env), count));
152
        }
153
    }
154

    
155
    public boolean isMatchSupported() {
156
        return true;
157
    }
158

    
159
    public boolean isNearestSupported() {
160
        return true;
161
    }
162

    
163
    public boolean isNearestToleranceSupported() {
164
        return false;
165
    }
166

    
167
    public boolean isRangeSupported() {
168
        return false;
169
    }
170

    
171
    public List nearest(int count, Object value, Object tolerance)
172
        throws FeatureIndexException {
173
        throw new UnsupportedOperationException();
174
    }
175

    
176
    public List range(Object value1, Object value2)
177
        throws FeatureIndexException {
178
        throw new UnsupportedOperationException();
179
    }
180

    
181
    /**
182
     * Indicates whether the given OID's type is compatible
183
     * with this provider
184
     * 
185
     * @param oid
186
     * 
187
     * @return
188
     *         true if this index provider supports the given oid type
189
     */
190
    private boolean isCompatibleOID(Object oid) {
191
        if (!(oid instanceof Number)) {
192
            return false;
193
        }
194

    
195
        long num = ((Number) oid).longValue();
196

    
197
        if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
198
            return false;
199
        }
200

    
201
        return true;
202
    }
203

    
204
    protected Envelope getEnvelope(Object value) {
205
        Envelope env = null;
206

    
207
        if (value instanceof Envelope) {
208
            env = (Envelope) value;
209
        } else
210
            if (value instanceof Geometry) {
211
                env = ((Geometry) value).getEnvelope();
212
            }
213
        return env;
214
    }
215
    
216
    protected Rectangle toJsiRect(Envelope env) {
217
        Point min = env.getLowerCorner();
218
        Point max = env.getUpperCorner();
219

    
220
        Rectangle jsiRect =
221
            new Rectangle((float) min.getX(), (float) min.getY(),
222
                (float) max.getX(), (float) max.getY());
223
        return jsiRect;
224
    }
225

    
226
    public void clear() throws DataException {
227
        rtree = createRTree();
228
    }
229
 }