Skip to content

Commit 2a58914

Browse files
authored
Add spatial index module (#71)
1 parent 13c8f1d commit 2a58914

13 files changed

Lines changed: 376 additions & 0 deletions

File tree

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Modules
1616
feature
1717
filter
1818
proj
19+
index/*
1920
layer
2021
workspace
2122
style

doc/api/index/quadtree.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
:class:`index.Quadtree`
2+
==========================
3+
4+
.. class:: index.Quadtree()
5+
6+
Create a Quadtree Spatial Index.
7+
8+
9+
Properties
10+
----------
11+
12+
.. attribute:: size
13+
14+
``Int``
15+
The number of items in the spatial index.
16+
17+
18+
Methods
19+
-------
20+
21+
.. function:: Quadtree.query
22+
23+
:arg bounds: :class:`geom.Bounds` The Bounds.
24+
:returns: :class:`Array`
25+
26+
Query the spatial index by Bounds.
27+
28+
.. function:: Quadtree.queryAll
29+
30+
:returns: :class:`Array`
31+
32+
Get all item in the spatial index.
33+
34+
.. function:: Quadtree.insert
35+
36+
:arg bounds: :class:`geom.Bounds` The Bounds.
37+
:arg item: :class:`Object` The value.
38+
:returns: :class:`boolean` Whether an item was removed or not
39+
40+
Remove an item from the spatial index
41+
42+
.. function:: Quadtree.remove
43+
44+
:arg bounds: :class:`geom.Bounds` The Bounds.
45+
:arg item: :class:`Object` The value.
46+
:returns: :class:`boolean` Whether an item was removed or not
47+
48+
Remove an item from the spatial index
49+
50+
Get all item in the spatial index.
51+
52+
53+
54+
55+
56+
57+

doc/api/index/strtree.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
:class:`index.STRtree`
2+
==========================
3+
4+
.. class:: index.STRtree()
5+
6+
Create a STRtree Spatial Index.
7+
8+
9+
Properties
10+
----------
11+
12+
.. attribute:: size
13+
14+
``Int``
15+
The number of items in the spatial index.
16+
17+
18+
Methods
19+
-------
20+
21+
.. function:: STRtree.query
22+
23+
:arg bounds: :class:`geom.Bounds` The Bounds.
24+
:returns: :class:`Array`
25+
26+
Query the spatial index by Bounds.
27+
28+
.. function:: STRtree.insert
29+
30+
:arg bounds: :class:`geom.Bounds` The Bounds.
31+
:arg item: :class:`Object` The value.
32+
:returns: :class:`boolean` Whether an item was removed or not
33+
34+
Remove an item from the spatial index
35+
36+
37+
38+
39+
40+
41+
42+

src/main/java/org/geoscript/js/geom/Geometry.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.lang.reflect.Method;
55
import java.util.Arrays;
66
import java.util.List;
7+
import java.util.Objects;
78

89
import org.locationtech.jts.densify.Densifier;
910
import org.geoscript.js.GeoObject;
@@ -646,4 +647,17 @@ public String toFullString() {
646647
return arrayRepr(getCoordinates());
647648
}
648649

650+
@Override
651+
public boolean equals(Object o) {
652+
if (this == o) return true;
653+
if (o == null || getClass() != o.getClass()) return false;
654+
Geometry geometry1 = (Geometry) o;
655+
return Objects.equals(geometry, geometry1.geometry) &&
656+
Objects.equals(projection, geometry1.projection);
657+
}
658+
659+
@Override
660+
public int hashCode() {
661+
return Objects.hash(geometry, projection);
662+
}
649663
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.geoscript.js.index;
2+
3+
import org.geoscript.js.GeoObject;
4+
import org.geoscript.js.index.*;
5+
import org.mozilla.javascript.Scriptable;
6+
import org.mozilla.javascript.ScriptableObject;
7+
8+
import java.lang.reflect.InvocationTargetException;
9+
import java.util.Arrays;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
13+
public class Module {
14+
15+
static HashMap<String, Scriptable> prototypes;
16+
17+
/**
18+
* Define all geometry constructors in the given module scope. If the
19+
* provided scope is not a "top level" scope, constructors will be defined
20+
* in the top level scope for the given scope.
21+
* @param scope
22+
* @throws IllegalAccessException
23+
* @throws InstantiationException
24+
* @throws InvocationTargetException
25+
*/
26+
public static void init(Scriptable scope) throws IllegalAccessException, InstantiationException, InvocationTargetException {
27+
28+
scope = ScriptableObject.getTopLevelScope(scope);
29+
30+
@SuppressWarnings("unchecked")
31+
List<Class<? extends GeoObject>> classes = Arrays.asList(Quadtree.class, STRtree.class);
32+
33+
prototypes = new HashMap<String, Scriptable>();
34+
for (Class<? extends GeoObject> cls : classes) {
35+
String name = ScriptableObject.defineClass(scope, cls, false, true);
36+
Scriptable prototype = ScriptableObject.getClassPrototype(scope, name);
37+
prototypes.put(name, prototype);
38+
}
39+
40+
}
41+
42+
protected static Scriptable getClassPrototype(Class<? extends GeoObject> cls) {
43+
String name = cls.getName();
44+
if (prototypes == null || !prototypes.containsKey(name)) {
45+
throw new RuntimeException(
46+
"Attempt to access prototype before requiring module: " + name);
47+
}
48+
return prototypes.get(name);
49+
}
50+
51+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.geoscript.js.index;
2+
3+
import org.geoscript.js.geom.Bounds;
4+
import org.mozilla.javascript.Context;
5+
import org.mozilla.javascript.Function;
6+
import org.mozilla.javascript.Scriptable;
7+
import org.mozilla.javascript.annotations.JSConstructor;
8+
import org.mozilla.javascript.annotations.JSFunction;
9+
import org.mozilla.javascript.annotations.JSGetter;
10+
11+
public class Quadtree extends SpatialIndex {
12+
13+
public Quadtree() {
14+
super(new org.locationtech.jts.index.quadtree.Quadtree());
15+
}
16+
17+
public Quadtree(Scriptable scope) {
18+
this();
19+
this.setParentScope(scope);
20+
this.setPrototype(Module.getClassPrototype(Quadtree.class));
21+
}
22+
23+
24+
@JSFunction
25+
public void insert(Bounds bounds, Object item) {
26+
this.index.insert(bounds.unwrap(), item);
27+
}
28+
29+
@JSFunction
30+
public Object query(Bounds bounds) {
31+
return javaToJS(this.index.query(bounds.unwrap()), getParentScope());
32+
}
33+
34+
@JSGetter
35+
public int getSize() {
36+
return ((org.locationtech.jts.index.quadtree.Quadtree)this.index).size();
37+
}
38+
39+
@JSFunction
40+
public Object queryAll() {
41+
return javaToJS(((org.locationtech.jts.index.quadtree.Quadtree)this.index).queryAll(), getParentScope());
42+
}
43+
44+
@JSFunction
45+
public boolean remove(Bounds bounds, Object item) {
46+
return this.index.remove(bounds.unwrap(), item);
47+
}
48+
49+
/**
50+
* JavaScript constructor.
51+
* @param cx
52+
* @param args
53+
* @param ctorObj
54+
* @param isNewExpr
55+
* @return
56+
*/
57+
@JSConstructor
58+
public static Object constructor(Context cx, Object[] args, Function ctorObj, boolean isNewExpr) {
59+
if (isNewExpr) {
60+
return new Quadtree();
61+
} else {
62+
return new Quadtree(ctorObj.getParentScope());
63+
}
64+
}
65+
66+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package org.geoscript.js.index;
2+
3+
import org.geoscript.js.geom.Bounds;
4+
import org.mozilla.javascript.Context;
5+
import org.mozilla.javascript.Function;
6+
import org.mozilla.javascript.Scriptable;
7+
import org.mozilla.javascript.annotations.JSConstructor;
8+
import org.mozilla.javascript.annotations.JSFunction;
9+
import org.mozilla.javascript.annotations.JSGetter;
10+
11+
import java.util.List;
12+
13+
public class STRtree extends SpatialIndex {
14+
15+
public STRtree() {
16+
super(new org.locationtech.jts.index.strtree.STRtree());
17+
}
18+
19+
public STRtree(Scriptable scope) {
20+
this();
21+
this.setParentScope(scope);
22+
this.setPrototype(Module.getClassPrototype(STRtree.class));
23+
}
24+
25+
@JSFunction
26+
public void insert(Bounds bounds, Object item) {
27+
this.index.insert(bounds.unwrap(), item);
28+
}
29+
30+
@JSFunction
31+
public List query(Bounds bounds) {
32+
return this.index.query(bounds.unwrap());
33+
}
34+
35+
@JSGetter
36+
public int getSize() {
37+
return ((org.locationtech.jts.index.strtree.STRtree)this.index).size();
38+
}
39+
40+
/**
41+
* JavaScript constructor.
42+
* @param cx
43+
* @param args
44+
* @param ctorObj
45+
* @param isNewExpr
46+
* @return
47+
*/
48+
@JSConstructor
49+
public static Object constructor(Context cx, Object[] args, Function ctorObj, boolean isNewExpr) {
50+
if (isNewExpr) {
51+
return new STRtree();
52+
} else {
53+
return new STRtree(ctorObj.getParentScope());
54+
}
55+
}
56+
57+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.geoscript.js.index;
2+
3+
import org.geoscript.js.GeoObject;
4+
import org.mozilla.javascript.Wrapper;
5+
6+
public abstract class SpatialIndex extends GeoObject implements Wrapper {
7+
8+
protected final org.locationtech.jts.index.SpatialIndex index;
9+
10+
public SpatialIndex(org.locationtech.jts.index.SpatialIndex index) {
11+
this.index = index;
12+
}
13+
14+
@Override
15+
public Object unwrap() {
16+
return index;
17+
}
18+
}

src/main/java/org/geoscript/js/proj/Projection.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.geoscript.js.proj;
22

3+
import java.util.Objects;
34
import java.util.logging.Logger;
45

56
import org.geoscript.js.GeoObject;

src/main/resources/org/geoscript/js/lib/geoscript.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ exports.workspace = require("./geoscript/workspace");
77
exports.viewer = require("./geoscript/viewer");
88
exports.style = require("./geoscript/style");
99
exports.map = require("./geoscript/map");
10+
exports.index = require("./geoscript/index");

0 commit comments

Comments
 (0)