Revision 43513

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.api/src/main/java/org/gvsig/fmap/geom/GeometryManager.java
75 75
 */
76 76
public interface GeometryManager extends Manager, ServiceManager {
77 77

  
78
//    
79
//  Spatial index "Quadtree" is faster in creation but don't 
80
//  support of nearest query.
81
//    
82
//  Spatial index "RTree" is faster in queries and support 
83
//  nearest queries.
84
//  
85
//  The library expose a default implementation for RTree and QuadTree
86
//    
87
    public static final String SPATIALINDEX_DEFAULT_RTREE = "JSIRTree";
88
    public static final String SPATIALINDEX_DEFAULT_QUADTREE = "JTSQuadtree";
89
    
90
    
78 91
    public interface OPERATIONS {
79 92

  
80 93
        public final static String FROMWKT = "FromWKT";
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/DefaultGeometryManager.java
55 55
import org.gvsig.fmap.geom.jts.primitive.DefaultNullGeometry;
56 56
import org.gvsig.fmap.geom.jts.primitive.Envelope2D;
57 57
import org.gvsig.fmap.geom.jts.primitive.Envelope3D;
58
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJSI;
59
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJTS;
58
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJSIRTree;
59
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJTSQuadtree;
60 60
import org.gvsig.fmap.geom.jts.util.JTSUtils;
61 61
import org.gvsig.fmap.geom.operation.GeometryOperation;
62 62
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
......
135 135

  
136 136
    public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) throws GeometryException {
137 137
        geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
138
        this.addServiceFactory(new SpatialIndexFactoryJTS());
139
        this.addServiceFactory(new SpatialIndexFactoryJSI());
138
        this.addServiceFactory(new SpatialIndexFactoryJTSQuadtree());
139
        this.addServiceFactory(new SpatialIndexFactoryJSIRTree());
140 140
    }
141 141

  
142 142
    public int registerGeometryOperation(String geomOpName, GeometryOperation geomOp, GeometryType geomType) {
......
788 788
    }
789 789

  
790 790
    public SpatialIndex createDefaultMemorySpatialIndex() throws ServiceException {
791
        return this.createSpatialIndex(SpatialIndexFactoryJTS.NAME, null);
791
        return this.createSpatialIndex(SpatialIndexFactoryJTSQuadtree.NAME, null);
792 792
    }
793 793

  
794 794
    public SpatialIndex createSpatialIndex(String name, DynObject parameters) throws ServiceException {
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexFactoryJSI.java
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

  
25

  
26
package org.gvsig.fmap.geom.jts.spatialindex;
27

  
28
import org.gvsig.fmap.geom.DataTypes;
29
import org.gvsig.fmap.geom.GeometryManager;
30
import org.gvsig.fmap.geom.SpatialIndexFactory;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dynobject.DynObject;
33
import org.gvsig.tools.dynobject.DynObjectManager;
34
import org.gvsig.tools.service.Service;
35
import org.gvsig.tools.service.ServiceException;
36
import org.gvsig.tools.service.spi.ServiceManager;
37

  
38

  
39
public class SpatialIndexFactoryJSI extends AbstractSpatialIndexFactory implements SpatialIndexFactory {
40

  
41
    public static final String NAME = "JSIRTree";
42
    
43
    //
44
    // https://github.com/aled/jsi/issues/31
45
    // RTree only supports 2 dimensions 
46
    //
47
    
48
    public String getName() {
49
        return NAME;
50
    }
51

  
52
    public boolean isNearestQuerySupported() {
53
        return true;
54
    }
55

  
56
    public boolean canLimitResults() {
57
        return true;
58
    }
59

  
60
    public int getDataTypeSupported() {
61
        return DataTypes.INT;
62
    }
63

  
64
    public Service create(DynObject parameters, ServiceManager serviceManager) throws ServiceException {
65
        return new SpatialIndexJSI((GeometryManager) serviceManager, this, parameters);
66
    }
67

  
68
    public DynObject createParameters() {
69
        DynObjectManager manager = ToolsLocator.getDynObjectManager();
70
        return manager.createDynObject(this.parametersDefinition);
71
    }
72

  
73
    public void initialize() {
74
        super.initialize(); 
75
        if( this.parametersDefinition == null ) {
76
            this.parametersDefinition = this.getBaseParametersDefinition();
77
            this.parametersDefinition.addDynFieldInt("MaxNodeEntries")
78
                    .setDefaultFieldValue(null)
79
                    .setMandatory(false);
80
            this.parametersDefinition.addDynFieldInt("MinNodeEntries")
81
                    .setDefaultFieldValue(null)
82
                    .setMandatory(false);
83
        }
84
    }
85
    
86
    
87
    
88
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexJTS.java
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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.geom.jts.spatialindex;
24

  
25
import com.vividsolutions.jts.index.quadtree.Quadtree;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileNotFoundException;
29
import java.io.FileOutputStream;
30
import java.util.Iterator;
31
import java.util.List;
32
import org.apache.commons.lang3.SerializationUtils;
33

  
34
import org.gvsig.fmap.geom.GeometryManager;
35
import org.gvsig.fmap.geom.SpatialIndex;
36
import org.gvsig.fmap.geom.SpatialIndexFactory;
37
import org.gvsig.fmap.geom.jts.GeometryJTS;
38
import org.gvsig.tools.dynobject.DynObject;
39
import org.gvsig.tools.visitor.Visitor;
40

  
41
public class SpatialIndexJTS extends AbstractSpatialIndex implements SpatialIndex {
42

  
43
    private com.vividsolutions.jts.index.quadtree.Quadtree index = null;
44
    private boolean modified;
45

  
46
    public SpatialIndexJTS(GeometryManager geometryManager, SpatialIndexFactory factory, DynObject parameters) {
47
        super(geometryManager, factory, parameters);
48
        this.index = null;
49
        this.modified = false;
50
        open();
51
    }
52
    
53
    @Override
54
    public void open() {
55
        this.index = new com.vividsolutions.jts.index.quadtree.Quadtree();
56
        File f = (File) this.getParameter("file");
57
        if( f!=null && f.exists() ) {
58
            try {
59
                this.load(f);
60
            } catch (FileNotFoundException ex) {
61
                throw new RuntimeException("Can't load spatial index from '"+f.getAbsolutePath()+"'.");
62
            }
63
        }
64
    }
65

  
66
    @Override
67
    public void close() {
68
        File f = (File) this.getParameter("file");
69
        if( f!=null && modified ) {
70
            try {
71
                this.save(f);
72
            } catch (FileNotFoundException ex) {
73
                throw new RuntimeException("Can't save spatial index to '"+f.getAbsolutePath()+"'.");
74
            }
75
        }
76
        this.index = null;
77
    }
78

  
79
    private void load(File fname) throws FileNotFoundException {
80
        FileInputStream is = new FileInputStream(fname);
81
        Object x = SerializationUtils.deserialize(is);
82
        this.index = (Quadtree) x;
83
        this.modified = false;
84
    }
85
    
86
    private void save(File fname) throws FileNotFoundException {
87
        FileOutputStream os = new FileOutputStream(fname);
88
        SerializationUtils.serialize(this.index, os);
89
        this.modified = false;
90
    }
91
    
92
    private com.vividsolutions.jts.geom.Geometry asJTS(org.gvsig.fmap.geom.Geometry geom) {
93
        return ((GeometryJTS)geom).getJTS();
94
    }
95

  
96
    @Override
97
    public long size() {
98
        return this.index.size();
99
    }
100

  
101
    @Override
102
    public void query(org.gvsig.fmap.geom.primitive.Envelope envelope,
103
            Visitor visitor) {
104
        com.vividsolutions.jts.index.ItemVisitor visitor_jts = new JTSVisitorWrapper(visitor);
105
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
106
        this.index.query(env_jts, visitor_jts);
107

  
108
    }
109

  
110
    @Override
111
    public Iterator query(org.gvsig.fmap.geom.primitive.Envelope envelope,long limit) {
112
        if( limit!=0 ) {
113
            throw new UnsupportedOperationException("Not supported yet.");
114
        }
115
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
116
        List result = this.index.query(env_jts);
117
        return result.iterator();
118
    }
119

  
120
    @Override
121
    public Iterator queryNearest(org.gvsig.fmap.geom.primitive.Envelope envelope, long limit) {
122
        throw new UnsupportedOperationException("Not supported yet.");
123
    }
124

  
125
    @Override
126
    public Iterator queryAll() {
127
        List result = this.index.queryAll();
128
        return result.iterator();
129
    }
130

  
131
    @Override
132
    public void insert(org.gvsig.fmap.geom.primitive.Envelope envelope, Object data) {
133
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
134
        index.insert(env_jts, data);
135
        this.modified = true;
136
    }
137

  
138
    @Override
139
    public boolean remove(org.gvsig.fmap.geom.primitive.Envelope envelope, Object data) {
140
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
141
        this.modified = true;
142
        return index.remove(env_jts, data);
143
    }
144

  
145
    @Override
146
    public void removeAll() {
147
        index = new com.vividsolutions.jts.index.quadtree.Quadtree();
148
        this.modified = true;
149
    }
150

  
151
    private class JTSVisitorWrapper implements com.vividsolutions.jts.index.ItemVisitor {
152

  
153
        private Visitor visitor = null;
154

  
155
        public JTSVisitorWrapper(Visitor visitor) {
156
            this.visitor = visitor;
157
        }
158

  
159
        @Override
160
        public void visitItem(Object arg0) {
161
            try {
162
                this.visitor.visit(arg0);
163
            } catch (Exception e) {
164
                throw new RuntimeException();
165
            }
166
        }
167

  
168
    }
169

  
170
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexJSI.java
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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.geom.jts.spatialindex;
24

  
25
import com.infomatiq.jsi.IntProcedure;
26
import java.util.ArrayList;
27
import java.util.Iterator;
28
import java.util.List;
29

  
30
import org.gvsig.fmap.geom.SpatialIndex;
31
import org.gvsig.fmap.geom.SpatialIndexFactory;
32
import org.gvsig.fmap.geom.primitive.Envelope;
33
import org.gvsig.tools.visitor.Visitor;
34

  
35
import com.infomatiq.jsi.Rectangle;
36
import com.infomatiq.jsi.rtree.RTree;
37
import java.util.Collection;
38
import java.util.Properties;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.primitive.Point;
41
import org.gvsig.tools.dynobject.DynObject;
42
import org.gvsig.tools.exception.BaseException;
43

  
44
public class SpatialIndexJSI extends AbstractSpatialIndex implements SpatialIndex {
45

  
46
    private RTree index = null;
47

  
48
    class Values implements IntProcedure {
49

  
50
        List elements = new ArrayList();
51

  
52
        public boolean execute(int arg0) {
53
            elements.add(new Integer(arg0));
54
            return true;
55
        }
56

  
57
        public List getElements() {
58
            return elements;
59
        }
60
    }
61

  
62
    public SpatialIndexJSI(GeometryManager geometryManager, SpatialIndexFactory factory, DynObject parameters) {
63
        super(geometryManager, factory, parameters);
64
        this.index = null;
65
        this.open();
66
    }
67

  
68
    public void open() {
69
        this.index = new RTree();
70
        Properties props = new Properties();
71
        if( this.getParameter("MaxNodeEntries")!=null ) {
72
            props.setProperty("MaxNodeEntries", ((Integer)this.getParameter("MaxNodeEntries")).toString());
73
        }
74
        if( this.getParameter("MinNodeEntries")!=null ) {
75
            props.setProperty("MinNodeEntries", ((Integer)this.getParameter("MinNodeEntries")).toString());
76
        }
77
        this.index.init(props);
78
    }
79

  
80
    public void close() {
81
        this.index = null;
82
    }
83

  
84
    private Rectangle asJSI(Envelope envelope) {
85
        Point min = envelope.getLowerCorner();
86
        Point max = envelope.getUpperCorner();
87

  
88
        Rectangle rectangle =
89
            new Rectangle((float) min.getX(), (float) min.getY(),
90
                (float) max.getX(), (float) max.getY());
91
        return rectangle;
92
    }
93

  
94
    public long size() {
95
        return this.index.size();
96
    }
97

  
98
    public void query(Envelope envelope, final Visitor visitor) {
99
        this.index.intersects(asJSI(envelope), new IntProcedure() {
100
            public boolean execute(int i) {
101
                try {
102
                    visitor.visit(new Integer(i));
103
                } catch (BaseException ex) {
104
                    return false;
105
                }
106
                return true;
107
            }
108
        });
109
    }
110

  
111
    public Iterator query(Envelope envelope, final long limit) {
112
        final List results = new ArrayList();
113

  
114
        this.index.intersects(asJSI(envelope), new IntProcedure() {
115
            public boolean execute(int i) {
116
                results.add(new Integer(i));
117
                return results.size()<limit;
118
            }
119
        });
120
        return results.iterator();
121
    }
122

  
123
    public Iterator queryNearest(Envelope envelope, long limit) {
124
        Collection results = this.index.nearest(asJSI(envelope), (int)limit);
125
        return results.iterator();
126
    }
127

  
128
    public Iterator queryAll() {
129
        return this.index.iterator();
130
    }
131

  
132
    public void insert(Envelope envelope, Object data) {
133
        Integer number = (Integer) this.coerceData(data);
134
        if( number == null ) {
135
            throw new IllegalArgumentException("null data are not allowed.");
136
        }
137
        this.index.add(asJSI(envelope), number.intValue());
138
    }
139

  
140
    public boolean remove(Envelope envelope, Object data) {
141
        Integer number = (Integer) this.coerceData(data);
142
        if( number == null ) {
143
            throw new IllegalArgumentException("null data are not allowed.");
144
        }
145
        return this.index.delete(asJSI(envelope), number.intValue());
146
    }
147

  
148
    public void removeAll() {
149
        this.close();
150
        this.open();
151
    }
152

  
153

  
154
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexFactoryJTS.java
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

  
25

  
26
package org.gvsig.fmap.geom.jts.spatialindex;
27

  
28
import java.io.File;
29
import org.gvsig.fmap.geom.GeometryManager;
30
import org.gvsig.fmap.geom.SpatialIndexFactory;
31
import org.gvsig.tools.dataTypes.DataTypes;
32
import org.gvsig.tools.dynobject.DynObject;
33
import org.gvsig.tools.dynobject.DynStruct;
34
import org.gvsig.tools.dynobject.impl.DefaultDynObject;
35
import org.gvsig.tools.service.Service;
36
import org.gvsig.tools.service.ServiceException;
37
import org.gvsig.tools.service.spi.ServiceManager;
38
import org.gvsig.tools.util.HasAFile;
39

  
40

  
41
public class SpatialIndexFactoryJTS extends AbstractSpatialIndexFactory implements SpatialIndexFactory  {
42

  
43
    public static final String NAME = "JTSQuadtree";
44

  
45
    public static class SpatialIndexJTSParameters extends DefaultDynObject implements HasAFile {
46

  
47
        public SpatialIndexJTSParameters(DynStruct dynClass) {
48
            super(dynClass);
49
        }
50

  
51
        @Override
52
        public File getFile() {
53
            return (File) this.getDynValue("file");
54
        }
55

  
56
        @Override
57
        public void setFile(File file) {
58
            this.setDynValue("file", file);
59
        }
60
    }
61
    
62
    @Override
63
    public String getName() {
64
        return NAME;
65
    }
66

  
67
    @Override
68
    public int getDataTypeSupported() {
69
        return DataTypes.OBJECT;
70
    }
71

  
72
    @Override
73
    public Service create(DynObject parameters, ServiceManager serviceManager) throws ServiceException {
74
        return new SpatialIndexJTS((GeometryManager) serviceManager, this, parameters);
75
    }
76

  
77
    @Override
78
    public DynObject createParameters() {
79
        return new SpatialIndexJTSParameters(parametersDefinition);
80
    }
81

  
82
    @Override
83
    public void initialize() {
84
        super.initialize(); 
85
        if( this.parametersDefinition == null ) {
86
            this.parametersDefinition = this.getBaseParametersDefinition();
87
            this.parametersDefinition.addDynFieldFile("file").setMandatory(false);
88
        }
89
    }
90
    
91
    
92
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexJSIRTree.java
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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.geom.jts.spatialindex;
24

  
25
import com.infomatiq.jsi.IntProcedure;
26
import java.util.ArrayList;
27
import java.util.Iterator;
28
import java.util.List;
29

  
30
import org.gvsig.fmap.geom.SpatialIndex;
31
import org.gvsig.fmap.geom.SpatialIndexFactory;
32
import org.gvsig.fmap.geom.primitive.Envelope;
33
import org.gvsig.tools.visitor.Visitor;
34

  
35
import com.infomatiq.jsi.Rectangle;
36
import com.infomatiq.jsi.rtree.RTree;
37
import java.util.Collection;
38
import java.util.Properties;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.primitive.Point;
41
import org.gvsig.tools.dynobject.DynObject;
42
import org.gvsig.tools.exception.BaseException;
43

  
44
public class SpatialIndexJSIRTree extends AbstractSpatialIndex implements SpatialIndex {
45

  
46
    private RTree index = null;
47

  
48
    class Values implements IntProcedure {
49

  
50
        List elements = new ArrayList();
51

  
52
        public boolean execute(int arg0) {
53
            elements.add(new Integer(arg0));
54
            return true;
55
        }
56

  
57
        public List getElements() {
58
            return elements;
59
        }
60
    }
61

  
62
    public SpatialIndexJSIRTree(GeometryManager geometryManager, SpatialIndexFactory factory, DynObject parameters) {
63
        super(geometryManager, factory, parameters);
64
        this.index = null;
65
        this.open();
66
    }
67

  
68
    public void open() {
69
        this.index = new RTree();
70
        Properties props = new Properties();
71
        if( this.getParameter("MaxNodeEntries")!=null ) {
72
            props.setProperty("MaxNodeEntries", ((Integer)this.getParameter("MaxNodeEntries")).toString());
73
        }
74
        if( this.getParameter("MinNodeEntries")!=null ) {
75
            props.setProperty("MinNodeEntries", ((Integer)this.getParameter("MinNodeEntries")).toString());
76
        }
77
        this.index.init(props);
78
    }
79

  
80
    public void close() {
81
        this.index = null;
82
    }
83

  
84
    private Rectangle asJSI(Envelope envelope) {
85
        Point min = envelope.getLowerCorner();
86
        Point max = envelope.getUpperCorner();
87

  
88
        Rectangle rectangle =
89
            new Rectangle((float) min.getX(), (float) min.getY(),
90
                (float) max.getX(), (float) max.getY());
91
        return rectangle;
92
    }
93

  
94
    public long size() {
95
        return this.index.size();
96
    }
97

  
98
    public void query(Envelope envelope, final Visitor visitor) {
99
        this.index.intersects(asJSI(envelope), new IntProcedure() {
100
            public boolean execute(int i) {
101
                try {
102
                    visitor.visit(new Integer(i));
103
                } catch (BaseException ex) {
104
                    return false;
105
                }
106
                return true;
107
            }
108
        });
109
    }
110

  
111
    public Iterator query(Envelope envelope, final long limit) {
112
        final List results = new ArrayList();
113

  
114
        this.index.intersects(asJSI(envelope), new IntProcedure() {
115
            public boolean execute(int i) {
116
                results.add(new Integer(i));
117
                return results.size()<limit;
118
            }
119
        });
120
        return results.iterator();
121
    }
122

  
123
    public Iterator queryNearest(Envelope envelope, long limit) {
124
        Collection results = this.index.nearest(asJSI(envelope), (int)limit);
125
        return results.iterator();
126
    }
127

  
128
    public Iterator queryAll() {
129
        return this.index.iterator();
130
    }
131

  
132
    public void insert(Envelope envelope, Object data) {
133
        Integer number = (Integer) this.coerceData(data);
134
        if( number == null ) {
135
            throw new IllegalArgumentException("null data are not allowed.");
136
        }
137
        this.index.add(asJSI(envelope), number.intValue());
138
    }
139

  
140
    public boolean remove(Envelope envelope, Object data) {
141
        Integer number = (Integer) this.coerceData(data);
142
        if( number == null ) {
143
            throw new IllegalArgumentException("null data are not allowed.");
144
        }
145
        return this.index.delete(asJSI(envelope), number.intValue());
146
    }
147

  
148
    public void removeAll() {
149
        this.close();
150
        this.open();
151
    }
152

  
153

  
154
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexJTSQuadtree.java
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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.geom.jts.spatialindex;
24

  
25
import com.vividsolutions.jts.index.quadtree.Quadtree;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileNotFoundException;
29
import java.io.FileOutputStream;
30
import java.util.Iterator;
31
import java.util.List;
32
import org.apache.commons.lang3.SerializationUtils;
33

  
34
import org.gvsig.fmap.geom.GeometryManager;
35
import org.gvsig.fmap.geom.SpatialIndex;
36
import org.gvsig.fmap.geom.SpatialIndexFactory;
37
import org.gvsig.fmap.geom.jts.GeometryJTS;
38
import org.gvsig.tools.dynobject.DynObject;
39
import org.gvsig.tools.visitor.Visitor;
40

  
41
public class SpatialIndexJTSQuadtree extends AbstractSpatialIndex implements SpatialIndex {
42

  
43
    private com.vividsolutions.jts.index.quadtree.Quadtree index = null;
44
    private boolean modified;
45

  
46
    public SpatialIndexJTSQuadtree(GeometryManager geometryManager, SpatialIndexFactory factory, DynObject parameters) {
47
        super(geometryManager, factory, parameters);
48
        this.index = null;
49
        this.modified = false;
50
        open();
51
    }
52
    
53
    @Override
54
    public void open() {
55
        this.index = new com.vividsolutions.jts.index.quadtree.Quadtree();
56
        File f = (File) this.getParameter("file");
57
        if( f!=null && f.exists() ) {
58
            try {
59
                this.load(f);
60
            } catch (FileNotFoundException ex) {
61
                throw new RuntimeException("Can't load spatial index from '"+f.getAbsolutePath()+"'.");
62
            }
63
        }
64
    }
65

  
66
    @Override
67
    public void close() {
68
        File f = (File) this.getParameter("file");
69
        if( f!=null && modified ) {
70
            try {
71
                this.save(f);
72
            } catch (FileNotFoundException ex) {
73
                throw new RuntimeException("Can't save spatial index to '"+f.getAbsolutePath()+"'.");
74
            }
75
        }
76
        this.index = null;
77
    }
78

  
79
    private void load(File fname) throws FileNotFoundException {
80
        FileInputStream is = new FileInputStream(fname);
81
        Object x = SerializationUtils.deserialize(is);
82
        this.index = (Quadtree) x;
83
        this.modified = false;
84
    }
85
    
86
    private void save(File fname) throws FileNotFoundException {
87
        FileOutputStream os = new FileOutputStream(fname);
88
        SerializationUtils.serialize(this.index, os);
89
        this.modified = false;
90
    }
91
    
92
    private com.vividsolutions.jts.geom.Geometry asJTS(org.gvsig.fmap.geom.Geometry geom) {
93
        return ((GeometryJTS)geom).getJTS();
94
    }
95

  
96
    @Override
97
    public long size() {
98
        return this.index.size();
99
    }
100

  
101
    @Override
102
    public void query(org.gvsig.fmap.geom.primitive.Envelope envelope,
103
            Visitor visitor) {
104
        com.vividsolutions.jts.index.ItemVisitor visitor_jts = new JTSVisitorWrapper(visitor);
105
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
106
        this.index.query(env_jts, visitor_jts);
107

  
108
    }
109

  
110
    @Override
111
    public Iterator query(org.gvsig.fmap.geom.primitive.Envelope envelope,long limit) {
112
        if( limit!=0 ) {
113
            throw new UnsupportedOperationException("Not supported yet.");
114
        }
115
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
116
        List result = this.index.query(env_jts);
117
        return result.iterator();
118
    }
119

  
120
    @Override
121
    public Iterator queryNearest(org.gvsig.fmap.geom.primitive.Envelope envelope, long limit) {
122
        throw new UnsupportedOperationException("Not supported yet.");
123
    }
124

  
125
    @Override
126
    public Iterator queryAll() {
127
        List result = this.index.queryAll();
128
        return result.iterator();
129
    }
130

  
131
    @Override
132
    public void insert(org.gvsig.fmap.geom.primitive.Envelope envelope, Object data) {
133
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
134
        index.insert(env_jts, data);
135
        this.modified = true;
136
    }
137

  
138
    @Override
139
    public boolean remove(org.gvsig.fmap.geom.primitive.Envelope envelope, Object data) {
140
        com.vividsolutions.jts.geom.Envelope env_jts = asJTS(envelope.getGeometry()).getEnvelopeInternal();
141
        this.modified = true;
142
        return index.remove(env_jts, data);
143
    }
144

  
145
    @Override
146
    public void removeAll() {
147
        index = new com.vividsolutions.jts.index.quadtree.Quadtree();
148
        this.modified = true;
149
    }
150

  
151
    private class JTSVisitorWrapper implements com.vividsolutions.jts.index.ItemVisitor {
152

  
153
        private Visitor visitor = null;
154

  
155
        public JTSVisitorWrapper(Visitor visitor) {
156
            this.visitor = visitor;
157
        }
158

  
159
        @Override
160
        public void visitItem(Object arg0) {
161
            try {
162
                this.visitor.visit(arg0);
163
            } catch (Exception e) {
164
                throw new RuntimeException();
165
            }
166
        }
167

  
168
    }
169

  
170
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexFactoryJSIRTree.java
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

  
25

  
26
package org.gvsig.fmap.geom.jts.spatialindex;
27

  
28
import org.gvsig.fmap.geom.DataTypes;
29
import org.gvsig.fmap.geom.GeometryManager;
30
import org.gvsig.fmap.geom.SpatialIndexFactory;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dynobject.DynObject;
33
import org.gvsig.tools.dynobject.DynObjectManager;
34
import org.gvsig.tools.service.Service;
35
import org.gvsig.tools.service.ServiceException;
36
import org.gvsig.tools.service.spi.ServiceManager;
37

  
38

  
39
public class SpatialIndexFactoryJSIRTree extends AbstractSpatialIndexFactory implements SpatialIndexFactory {
40

  
41
    public static final String NAME = GeometryManager.SPATIALINDEX_DEFAULT_RTREE;
42
    
43
    //
44
    // https://github.com/aled/jsi/issues/31
45
    // RTree only supports 2 dimensions 
46
    //
47
    
48
    public String getName() {
49
        return NAME;
50
    }
51

  
52
    public boolean isNearestQuerySupported() {
53
        return true;
54
    }
55

  
56
    public boolean canLimitResults() {
57
        return true;
58
    }
59

  
60
    public int getDataTypeSupported() {
61
        return DataTypes.INT;
62
    }
63

  
64
    public Service create(DynObject parameters, ServiceManager serviceManager) throws ServiceException {
65
        return new SpatialIndexJSIRTree((GeometryManager) serviceManager, this, parameters);
66
    }
67

  
68
    public DynObject createParameters() {
69
        DynObjectManager manager = ToolsLocator.getDynObjectManager();
70
        return manager.createDynObject(this.parametersDefinition);
71
    }
72

  
73
    public void initialize() {
74
        super.initialize(); 
75
        if( this.parametersDefinition == null ) {
76
            this.parametersDefinition = this.getBaseParametersDefinition();
77
            this.parametersDefinition.addDynFieldInt("MaxNodeEntries")
78
                    .setDefaultFieldValue(null)
79
                    .setMandatory(false);
80
            this.parametersDefinition.addDynFieldInt("MinNodeEntries")
81
                    .setDefaultFieldValue(null)
82
                    .setMandatory(false);
83
        }
84
    }
85
    
86
    
87
    
88
}
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/spatialindex/SpatialIndexFactoryJTSQuadtree.java
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

  
25

  
26
package org.gvsig.fmap.geom.jts.spatialindex;
27

  
28
import java.io.File;
29
import org.gvsig.fmap.geom.GeometryManager;
30
import org.gvsig.fmap.geom.SpatialIndexFactory;
31
import org.gvsig.tools.dataTypes.DataTypes;
32
import org.gvsig.tools.dynobject.DynObject;
33
import org.gvsig.tools.dynobject.DynStruct;
34
import org.gvsig.tools.dynobject.impl.DefaultDynObject;
35
import org.gvsig.tools.service.Service;
36
import org.gvsig.tools.service.ServiceException;
37
import org.gvsig.tools.service.spi.ServiceManager;
38
import org.gvsig.tools.util.HasAFile;
39

  
40

  
41
public class SpatialIndexFactoryJTSQuadtree extends AbstractSpatialIndexFactory implements SpatialIndexFactory  {
42

  
43
    public static final String NAME = GeometryManager.SPATIALINDEX_DEFAULT_QUADTREE;
44

  
45
    public static class SpatialIndexJTSParameters extends DefaultDynObject implements HasAFile {
46

  
47
        public SpatialIndexJTSParameters(DynStruct dynClass) {
48
            super(dynClass);
49
        }
50

  
51
        @Override
52
        public File getFile() {
53
            return (File) this.getDynValue("file");
54
        }
55

  
56
        @Override
57
        public void setFile(File file) {
58
            this.setDynValue("file", file);
59
        }
60
    }
61
    
62
    @Override
63
    public String getName() {
64
        return NAME;
65
    }
66

  
67
    @Override
68
    public int getDataTypeSupported() {
69
        return DataTypes.OBJECT;
70
    }
71

  
72
    @Override
73
    public Service create(DynObject parameters, ServiceManager serviceManager) throws ServiceException {
74
        return new SpatialIndexJTSQuadtree((GeometryManager) serviceManager, this, parameters);
75
    }
76

  
77
    @Override
78
    public DynObject createParameters() {
79
        return new SpatialIndexJTSParameters(parametersDefinition);
80
    }
81

  
82
    @Override
83
    public void initialize() {
84
        super.initialize(); 
85
        if( this.parametersDefinition == null ) {
86
            this.parametersDefinition = this.getBaseParametersDefinition();
87
            this.parametersDefinition.addDynFieldFile("file").setMandatory(false);
88
        }
89
    }
90
    
91
    
92
}

Also available in: Unified diff