Skip to content

Commit b868c12

Browse files
committed
Geometry Filter interface and Point Finite Filter implementation
1 parent f151db2 commit b868c12

4 files changed

Lines changed: 294 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Adheres to [Semantic Versioning](http://semver.org/).
66

77
## 2.0.3 (TBD)
88

9-
* TBD
9+
* Geometry Filter interface and Point Finite Filter implementation
1010

1111
## [2.0.2](https://github.com/ngageoint/simple-features-java/releases/tag/2.0.2) (07-08-2019)
1212

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package mil.nga.sf.util.filter;
2+
3+
/**
4+
* Finite Filter Type, including finite values and optionally one of either
5+
* infinite or NaN values
6+
*
7+
* @author osbornb
8+
* @since 2.0.3
9+
*/
10+
public enum FiniteFilterType {
11+
12+
/**
13+
* Accept only finite values
14+
*/
15+
FINITE,
16+
17+
/**
18+
* Accept finite and infinite values
19+
*/
20+
FINITE_AND_INFINITE,
21+
22+
/**
23+
* Accept finite and Not a Number values
24+
*/
25+
FINITE_AND_NAN;
26+
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package mil.nga.sf.util.filter;
2+
3+
import mil.nga.sf.Geometry;
4+
import mil.nga.sf.GeometryType;
5+
6+
/**
7+
* Geometry Filter to filter included geometries and modify them during
8+
* construction
9+
*
10+
* @author osbornb
11+
* @since 2.0.3
12+
*/
13+
public interface GeometryFilter {
14+
15+
/**
16+
* Filter the geometry
17+
*
18+
* @param containingType
19+
* geometry type of the geometry containing this geometry
20+
* element, null if geometry is top level
21+
* @param geometry
22+
* geometry, may be modified
23+
* @return true if passes filter and geometry should be included
24+
*/
25+
public boolean filter(GeometryType containingType, Geometry geometry);
26+
27+
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
package mil.nga.sf.util.filter;
2+
3+
import mil.nga.sf.Geometry;
4+
import mil.nga.sf.GeometryType;
5+
import mil.nga.sf.Point;
6+
import mil.nga.sf.util.SFException;
7+
8+
/**
9+
* Point filter for finite checks on x and y properties, optionally filter on z
10+
* and m properties and non finite values (NaN or infinity)
11+
*
12+
* @author osbornb
13+
* @since 2.0.3
14+
*/
15+
public class PointFiniteFilter implements GeometryFilter {
16+
17+
/**
18+
* Finite Filter type
19+
*/
20+
private FiniteFilterType type = FiniteFilterType.FINITE;
21+
22+
/**
23+
* Include z values in filtering
24+
*/
25+
boolean filterZ = false;
26+
27+
/**
28+
* Include m values in filtering
29+
*/
30+
boolean filterM = false;
31+
32+
/**
33+
* Default Constructor, filter on x and y, allowing only finite values
34+
*/
35+
public PointFiniteFilter() {
36+
37+
}
38+
39+
/**
40+
* Constructor, filter on x and y
41+
*
42+
* @param type
43+
* finite filter type
44+
*/
45+
public PointFiniteFilter(FiniteFilterType type) {
46+
setType(type);
47+
}
48+
49+
/**
50+
* Constructor, filter on x, y, and optionally z
51+
*
52+
* @param type
53+
* finite filter type
54+
* @param filterZ
55+
* filter z values mode
56+
*/
57+
public PointFiniteFilter(FiniteFilterType type, boolean filterZ) {
58+
setType(type);
59+
setFilterZ(filterZ);
60+
}
61+
62+
/**
63+
* Constructor, filter on x, y, and optionally z and m
64+
*
65+
* @param type
66+
* finite filter type
67+
* @param filterZ
68+
* filter z values mode
69+
* @param filterM
70+
* filter m values mode
71+
*/
72+
public PointFiniteFilter(FiniteFilterType type, boolean filterZ,
73+
boolean filterM) {
74+
setType(type);
75+
setFilterZ(filterZ);
76+
setFilterM(filterM);
77+
}
78+
79+
/**
80+
* Constructor, filter on x, y, and optionally z
81+
*
82+
* @param filterZ
83+
* filter z values mode
84+
*/
85+
public PointFiniteFilter(boolean filterZ) {
86+
setFilterZ(filterZ);
87+
}
88+
89+
/**
90+
* Constructor, filter on x, y, and optionally z and m
91+
*
92+
* @param filterZ
93+
* filter z values mode
94+
* @param filterM
95+
* filter m values mode
96+
*/
97+
public PointFiniteFilter(boolean filterZ, boolean filterM) {
98+
setFilterZ(filterZ);
99+
setFilterM(filterM);
100+
}
101+
102+
/**
103+
* Get the finite filter type
104+
*
105+
* @return finite filter type
106+
*/
107+
public FiniteFilterType getType() {
108+
return type;
109+
}
110+
111+
/**
112+
* Set the finite filter type, null defaults to
113+
* {@link FiniteFilterType#FINITE}
114+
*
115+
* @param type
116+
* finite filter type
117+
*/
118+
public void setType(FiniteFilterType type) {
119+
this.type = type;
120+
}
121+
122+
/**
123+
* Is filtering for z values enabled?
124+
*
125+
* @return true if z filtering
126+
*/
127+
public boolean isFilterZ() {
128+
return filterZ;
129+
}
130+
131+
/**
132+
* Set the z value filtering mode
133+
*
134+
* @param filterZ
135+
* true to z filter
136+
*/
137+
public void setFilterZ(boolean filterZ) {
138+
this.filterZ = filterZ;
139+
}
140+
141+
/**
142+
* Is filtering for m values enabled?
143+
*
144+
* @return true if m filtering
145+
*/
146+
public boolean isFilterM() {
147+
return filterM;
148+
}
149+
150+
/**
151+
* Set the m value filtering mode
152+
*
153+
* @param filterM
154+
* true to m filter
155+
*/
156+
public void setFilterM(boolean filterM) {
157+
this.filterM = filterM;
158+
}
159+
160+
/**
161+
* {@inheritDoc}
162+
*/
163+
@Override
164+
public boolean filter(GeometryType containingType, Geometry geometry) {
165+
return geometry.getGeometryType() != GeometryType.POINT
166+
|| !(geometry instanceof Point) || filter((Point) geometry);
167+
}
168+
169+
/**
170+
* Filter the point
171+
*
172+
* @param point
173+
* point
174+
* @return true if passes filter and point should be included
175+
*/
176+
private boolean filter(Point point) {
177+
return filter(point.getX()) && filter(point.getY()) && filterZ(point)
178+
&& filterM(point);
179+
}
180+
181+
/**
182+
* Filter the double value
183+
*
184+
* @param value
185+
* double value
186+
* @return
187+
*/
188+
private boolean filter(double value) {
189+
boolean passes;
190+
switch (type) {
191+
case FINITE:
192+
passes = Double.isFinite(value);
193+
break;
194+
case FINITE_AND_INFINITE:
195+
passes = !Double.isNaN(value);
196+
break;
197+
case FINITE_AND_NAN:
198+
passes = !Double.isInfinite(value);
199+
break;
200+
default:
201+
throw new SFException("Unsupported filter type: " + type);
202+
}
203+
return passes;
204+
}
205+
206+
/**
207+
* Filter the Z value
208+
*
209+
* @param point
210+
* point
211+
* @return true if passes
212+
*/
213+
private boolean filterZ(Point point) {
214+
return !filterZ || !point.hasZ() || filter(point.getZ());
215+
}
216+
217+
/**
218+
* Filter the M value
219+
*
220+
* @param point
221+
* point
222+
* @return true if passes
223+
*/
224+
private boolean filterM(Point point) {
225+
return !filterM || !point.hasM() || filter(point.getM());
226+
}
227+
228+
/**
229+
* Filter the Double value
230+
*
231+
* @param value
232+
* Double value
233+
* @return true if passes
234+
*/
235+
private boolean filter(Double value) {
236+
return value == null || filter(value.doubleValue());
237+
}
238+
239+
}

0 commit comments

Comments
 (0)