Skip to content

Commit 69120ea

Browse files
ashish217rfecher
authored andcommitted
Added geometric compare operations for Geometric objects and 1D data (i.e. within, touches, crosses, etc.) (#1043)
1 parent b5dfb64 commit 69120ea

9 files changed

Lines changed: 594 additions & 48 deletions

File tree

core/geotime/src/main/java/mil/nga/giat/geowave/core/geotime/store/filter/SpatialQueryFilter.java

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,97 @@ public BasicQueryCompareOperation getBaseCompareOp() {
6969
public boolean compare(
7070
final Geometry dataGeometry,
7171
final PreparedGeometry constraintGeometry ) {
72-
return constraintGeometry.intersects(dataGeometry);
72+
return constraintGeometry.overlaps(dataGeometry);
7373
}
7474

7575
@Override
7676
public BasicQueryCompareOperation getBaseCompareOp() {
7777
return BasicQueryCompareOperation.OVERLAPS;
7878
}
79+
},
80+
INTERSECTS {
81+
@Override
82+
public boolean compare(
83+
final Geometry dataGeometry,
84+
final PreparedGeometry constraintGeometry ) {
85+
return constraintGeometry.intersects(dataGeometry);
86+
}
87+
88+
@Override
89+
public BasicQueryCompareOperation getBaseCompareOp() {
90+
return BasicQueryCompareOperation.INTERSECTS;
91+
}
92+
},
93+
TOUCHES {
94+
@Override
95+
public boolean compare(
96+
final Geometry dataGeometry,
97+
final PreparedGeometry constraintGeometry ) {
98+
return constraintGeometry.touches(dataGeometry);
99+
}
100+
101+
@Override
102+
public BasicQueryCompareOperation getBaseCompareOp() {
103+
return BasicQueryCompareOperation.TOUCHES;
104+
}
105+
},
106+
WITHIN {
107+
@Override
108+
public boolean compare(
109+
final Geometry dataGeometry,
110+
final PreparedGeometry constraintGeometry ) {
111+
return constraintGeometry.within(dataGeometry);
112+
}
113+
114+
@Override
115+
public BasicQueryCompareOperation getBaseCompareOp() {
116+
return BasicQueryCompareOperation.WITHIN;
117+
}
118+
},
119+
DISJOINT {
120+
@Override
121+
public boolean compare(
122+
final Geometry dataGeometry,
123+
final PreparedGeometry constraintGeometry ) {
124+
return constraintGeometry.disjoint(dataGeometry);
125+
}
126+
127+
@Override
128+
public BasicQueryCompareOperation getBaseCompareOp() {
129+
return BasicQueryCompareOperation.DISJOINT;
130+
}
131+
},
132+
CROSSES {
133+
@Override
134+
public boolean compare(
135+
final Geometry dataGeometry,
136+
final PreparedGeometry constraintGeometry ) {
137+
return constraintGeometry.crosses(dataGeometry);
138+
}
139+
140+
@Override
141+
public BasicQueryCompareOperation getBaseCompareOp() {
142+
return BasicQueryCompareOperation.CROSSES;
143+
}
144+
},
145+
EQUALS {
146+
@Override
147+
public boolean compare(
148+
final Geometry dataGeometry,
149+
final PreparedGeometry constraintGeometry ) {
150+
//This method is same as Geometry.equalsTopo which is computationally expensive.
151+
//See equalsExact for quick structural equality
152+
return constraintGeometry.getGeometry().equals(dataGeometry);
153+
}
154+
155+
@Override
156+
public BasicQueryCompareOperation getBaseCompareOp() {
157+
return BasicQueryCompareOperation.EQUALS;
158+
}
79159
}
80160
};
81161

82-
private CompareOperation compareOperation = CompareOperation.OVERLAPS;
162+
private CompareOperation compareOperation = CompareOperation.INTERSECTS;
83163

84164
private Set<ByteArrayId> geometryFieldIds;
85165

core/geotime/src/main/java/mil/nga/giat/geowave/core/geotime/store/query/SpatialQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class SpatialQuery extends
3030
{
3131
private final static Logger LOGGER = Logger.getLogger(SpatialQuery.class);
3232
private Geometry queryGeometry;
33-
CompareOperation compareOp = CompareOperation.OVERLAPS;
33+
CompareOperation compareOp = CompareOperation.INTERSECTS;
3434

3535
/**
3636
* Convenience constructor used to construct a SpatialQuery object that has
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
package mil.nga.giat.geowave.core.geotime.store.query;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.text.ParseException;
6+
import java.text.SimpleDateFormat;
7+
import java.util.Date;
8+
9+
import mil.nga.giat.geowave.core.geotime.index.dimension.TimeDefinition;
10+
import mil.nga.giat.geowave.core.geotime.index.dimension.TemporalBinningStrategy.Unit;
11+
import mil.nga.giat.geowave.core.geotime.ingest.SpatialTemporalDimensionalityTypeProvider;
12+
import mil.nga.giat.geowave.core.geotime.store.dimension.Time.TimeRange;
13+
import mil.nga.giat.geowave.core.geotime.store.dimension.TimeField;
14+
import mil.nga.giat.geowave.core.index.ByteArrayId;
15+
import mil.nga.giat.geowave.core.index.sfc.data.NumericRange;
16+
import mil.nga.giat.geowave.core.store.data.CommonIndexedPersistenceEncoding;
17+
import mil.nga.giat.geowave.core.store.data.PersistentDataset;
18+
import mil.nga.giat.geowave.core.store.data.PersistentValue;
19+
import mil.nga.giat.geowave.core.store.filter.BasicQueryFilter.BasicQueryCompareOperation;
20+
import mil.nga.giat.geowave.core.store.filter.QueryFilter;
21+
import mil.nga.giat.geowave.core.store.index.CommonIndexModel;
22+
import mil.nga.giat.geowave.core.store.index.CommonIndexValue;
23+
import mil.nga.giat.geowave.core.store.query.BasicQuery;
24+
import mil.nga.giat.geowave.core.store.query.BasicQuery.ConstraintData;
25+
import mil.nga.giat.geowave.core.store.query.BasicQuery.ConstraintSet;
26+
import mil.nga.giat.geowave.core.store.query.BasicQuery.Constraints;
27+
28+
import org.junit.Test;
29+
30+
31+
public class BasicQueryTest
32+
{
33+
SimpleDateFormat df = new SimpleDateFormat(
34+
"yyyy-MM-dd'T'HH:mm:ssz");
35+
36+
private CommonIndexedPersistenceEncoding createData(
37+
final Date start,
38+
final Date end) {
39+
final PersistentDataset<CommonIndexValue> commonData = new PersistentDataset<CommonIndexValue>();
40+
41+
commonData.addValue(new PersistentValue<CommonIndexValue>(
42+
new TimeField(
43+
Unit.YEAR).getFieldId(),
44+
new TimeRange(
45+
start.getTime(),
46+
end.getTime(),
47+
new byte[0])));
48+
49+
return new CommonIndexedPersistenceEncoding(
50+
new ByteArrayId(
51+
"1"),
52+
new ByteArrayId(
53+
"1"),
54+
new ByteArrayId(
55+
"1"),
56+
1,
57+
commonData,
58+
new PersistentDataset<byte[]>());
59+
}
60+
61+
public void performOp(
62+
final BasicQueryCompareOperation op,
63+
final boolean[] expectedResults )
64+
throws ParseException {
65+
//query time range
66+
ConstraintData constrainData = new ConstraintData(
67+
new NumericRange(
68+
df.parse("2017-02-22T12:00:00GMT-00:00").getTime(),
69+
df.parse("2017-02-22T13:00:00GMT-00:00").getTime()),
70+
true);
71+
Constraints constaints = new Constraints(
72+
new ConstraintSet(
73+
TimeDefinition.class,
74+
constrainData));
75+
final BasicQuery query = new BasicQuery(constaints, op);
76+
77+
final CommonIndexedPersistenceEncoding[] data = new CommonIndexedPersistenceEncoding[] {
78+
79+
//same exact time range as the query
80+
createData(
81+
df.parse("2017-02-22T12:00:00GMT-00:00"),
82+
df.parse("2017-02-22T13:00:00GMT-00:00")),
83+
84+
//partial overlap
85+
createData(
86+
df.parse("2017-02-22T11:00:00GMT-00:00"),
87+
df.parse("2017-02-22T12:30:00GMT-00:00")),
88+
89+
//time range completely within the query
90+
createData(
91+
df.parse("2017-02-22T12:30:00GMT-00:00"),
92+
df.parse("2017-02-22T12:50:00GMT-00:00")),
93+
94+
//time range touching each other
95+
createData(
96+
df.parse("2017-02-22T11:00:00GMT-00:00"),
97+
df.parse("2017-02-22T12:00:00GMT-00:00")),
98+
99+
//no intersection between ranges
100+
createData(
101+
df.parse("2017-02-22T11:00:00GMT-00:00"),
102+
df.parse("2017-02-22T11:59:00GMT-00:00")),
103+
104+
//time range contains complete query range
105+
createData(
106+
df.parse("2017-02-22T11:00:00GMT-00:00"),
107+
df.parse("2017-02-22T14:00:00GMT-00:00"))
108+
};
109+
final CommonIndexModel model = new SpatialTemporalDimensionalityTypeProvider()
110+
.createPrimaryIndex()
111+
.getIndexModel();
112+
int pos = 0;
113+
for (final CommonIndexedPersistenceEncoding dataItem : data) {
114+
for (final QueryFilter filter : query.createFilters(model)) {
115+
assertEquals(
116+
"result: " + pos,
117+
expectedResults[pos++],
118+
filter.accept(
119+
model,
120+
dataItem));
121+
}
122+
}
123+
}
124+
125+
@Test
126+
public void testContains()
127+
throws ParseException {
128+
performOp(
129+
BasicQueryCompareOperation.CONTAINS,
130+
new boolean[] {
131+
true,
132+
false,
133+
true,
134+
false,
135+
false,
136+
false
137+
});
138+
}
139+
140+
@Test
141+
public void testOverlaps()
142+
throws ParseException {
143+
performOp(
144+
BasicQueryCompareOperation.OVERLAPS,
145+
new boolean[] {
146+
false,
147+
true,
148+
false,
149+
false,
150+
false,
151+
false
152+
});
153+
}
154+
155+
@Test
156+
public void testIntersects()
157+
throws ParseException {
158+
performOp(
159+
BasicQueryCompareOperation.INTERSECTS,
160+
new boolean[] {
161+
true,
162+
true,
163+
true,
164+
true,
165+
false,
166+
true
167+
});
168+
}
169+
170+
@Test
171+
public void testEquals()
172+
throws ParseException {
173+
performOp(
174+
BasicQueryCompareOperation.EQUALS,
175+
new boolean[] {
176+
true,
177+
false,
178+
false,
179+
false,
180+
false,
181+
false
182+
});
183+
}
184+
185+
@Test
186+
public void testDisjoint()
187+
throws ParseException {
188+
performOp(
189+
BasicQueryCompareOperation.DISJOINT,
190+
new boolean[] {
191+
false,
192+
false,
193+
false,
194+
false,
195+
true,
196+
false
197+
});
198+
}
199+
200+
@Test
201+
public void testWithin()
202+
throws ParseException {
203+
performOp(
204+
BasicQueryCompareOperation.WITHIN,
205+
new boolean[] {
206+
true,
207+
false,
208+
false,
209+
false,
210+
false,
211+
true
212+
});
213+
}
214+
215+
@Test
216+
public void testCrosses()
217+
throws ParseException {
218+
performOp(
219+
BasicQueryCompareOperation.CROSSES,
220+
new boolean[] {
221+
false,
222+
false,
223+
false,
224+
false,
225+
false,
226+
false
227+
});
228+
}
229+
230+
@Test
231+
public void testTouches()
232+
throws ParseException {
233+
performOp(
234+
BasicQueryCompareOperation.TOUCHES,
235+
new boolean[] {
236+
false,
237+
false,
238+
false,
239+
true,
240+
false,
241+
false
242+
});
243+
}
244+
}

0 commit comments

Comments
 (0)