Skip to content

Commit de407a6

Browse files
committed
contains within tolerance
1 parent 11b4896 commit de407a6

3 files changed

Lines changed: 173 additions & 12 deletions

File tree

src/main/java/mil/nga/sf/GeometryEnvelope.java

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,21 @@ public GeometryEnvelope union(GeometryEnvelope envelope) {
682682
* @since 2.1.0
683683
*/
684684
public boolean contains(Point point) {
685-
return contains(point.getX(), point.getY());
685+
return contains(point, 0.0);
686+
}
687+
688+
/**
689+
* Determine if contains the point
690+
*
691+
* @param point
692+
* point
693+
* @param epsilon
694+
* epsilon equality tolerance
695+
* @return true if contains
696+
* @since 2.2.0
697+
*/
698+
public boolean contains(Point point, double epsilon) {
699+
return contains(point.getX(), point.getY(), epsilon);
686700
}
687701

688702
/**
@@ -696,8 +710,24 @@ public boolean contains(Point point) {
696710
* @since 2.1.0
697711
*/
698712
public boolean contains(double x, double y) {
699-
return x >= getMinX() && x <= getMaxX() && y >= getMinY()
700-
&& y <= getMaxY();
713+
return contains(x, y, 0.0);
714+
}
715+
716+
/**
717+
* Determine if contains the coordinate
718+
*
719+
* @param x
720+
* x value
721+
* @param y
722+
* y value
723+
* @param epsilon
724+
* epsilon equality tolerance
725+
* @return true if contains
726+
* @since 2.2.0
727+
*/
728+
public boolean contains(double x, double y, double epsilon) {
729+
return x >= getMinX() - epsilon && x <= getMaxX() + epsilon
730+
&& y >= getMinY() - epsilon && y <= getMaxY() + epsilon;
701731
}
702732

703733
/**
@@ -709,10 +739,24 @@ public boolean contains(double x, double y) {
709739
* @since 2.0.1
710740
*/
711741
public boolean contains(GeometryEnvelope envelope) {
712-
return getMinX() <= envelope.getMinX()
713-
&& getMaxX() >= envelope.getMaxX()
714-
&& getMinY() <= envelope.getMinY()
715-
&& getMaxY() >= envelope.getMaxY();
742+
return contains(envelope, 0.0);
743+
}
744+
745+
/**
746+
* Determine if inclusively contains the provided envelope
747+
*
748+
* @param envelope
749+
* geometry envelope
750+
* @param epsilon
751+
* epsilon equality tolerance
752+
* @return true if contains
753+
* @since 2.2.0
754+
*/
755+
public boolean contains(GeometryEnvelope envelope, double epsilon) {
756+
return getMinX() - epsilon <= envelope.getMinX()
757+
&& getMaxX() + epsilon >= envelope.getMaxX()
758+
&& getMinY() - epsilon <= envelope.getMinY()
759+
&& getMaxY() + epsilon >= envelope.getMaxY();
716760
}
717761

718762
/**

src/main/java/mil/nga/sf/util/GeometryUtils.java

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,7 +2027,7 @@ public static Geometry crop(Geometry geometry, GeometryEnvelope envelope) {
20272027

20282028
Geometry crop = null;
20292029

2030-
if (envelope.contains(geometry.getEnvelope())) {
2030+
if (contains(envelope, geometry.getEnvelope())) {
20312031
crop = geometry;
20322032
} else {
20332033

@@ -2102,7 +2102,7 @@ public static Geometry crop(Geometry geometry, GeometryEnvelope envelope) {
21022102
*/
21032103
public static Point crop(Point point, GeometryEnvelope envelope) {
21042104
Point crop = null;
2105-
if (envelope.contains(point)) {
2105+
if (contains(envelope, point)) {
21062106
crop = new Point(point);
21072107
}
21082108
return crop;
@@ -2133,7 +2133,7 @@ public static List<Point> crop(List<Point> points,
21332133
Point previousPoint = null;
21342134
boolean previousContains = false;
21352135
for (Point point : points) {
2136-
boolean contains = envelope.contains(point);
2136+
boolean contains = contains(envelope, point);
21372137

21382138
if (previousPoint != null && (!contains || !previousContains)) {
21392139

@@ -2179,7 +2179,7 @@ public static List<Point> crop(List<Point> points,
21792179
if (vertLine != null) {
21802180
vertIntersection = intersection(line, vertLine);
21812181
if (vertIntersection != null
2182-
&& !envelope.contains(vertIntersection)) {
2182+
&& !contains(envelope, vertIntersection)) {
21832183
vertIntersection = null;
21842184
}
21852185
}
@@ -2188,7 +2188,7 @@ public static List<Point> crop(List<Point> points,
21882188
if (horizLine != null) {
21892189
horizIntersection = intersection(line, horizLine);
21902190
if (horizIntersection != null
2191-
&& !envelope.contains(horizIntersection)) {
2191+
&& !contains(envelope, horizIntersection)) {
21922192
horizIntersection = null;
21932193
}
21942194
}
@@ -2649,6 +2649,41 @@ public static boolean isEqual(Point point1, Point point2, double epsilon) {
26492649
return equal;
26502650
}
26512651

2652+
/**
2653+
* Determine if the envelope contains the point within the default tolerance
2654+
* of {@link GeometryConstants#DEFAULT_EQUAL_EPSILON}. For exact equality,
2655+
* use {@link GeometryEnvelope#contains(Point)}.
2656+
*
2657+
* @param envelope
2658+
* envelope
2659+
* @param point
2660+
* point
2661+
* @return true if contains
2662+
* @since 2.2.0
2663+
*/
2664+
public static boolean contains(GeometryEnvelope envelope, Point point) {
2665+
return envelope.contains(point,
2666+
GeometryConstants.DEFAULT_EQUAL_EPSILON);
2667+
}
2668+
2669+
/**
2670+
* Determine if the first envelope contains the second within the default
2671+
* tolerance of {@link GeometryConstants#DEFAULT_EQUAL_EPSILON}. For exact
2672+
* equality, use {@link GeometryEnvelope#contains(GeometryEnvelope)}.
2673+
*
2674+
* @param envelope1
2675+
* envelope 1
2676+
* @param envelope2
2677+
* envelope 2
2678+
* @return true if contains
2679+
* @since 2.2.0
2680+
*/
2681+
public static boolean contains(GeometryEnvelope envelope1,
2682+
GeometryEnvelope envelope2) {
2683+
return envelope1.contains(envelope2,
2684+
GeometryConstants.DEFAULT_EQUAL_EPSILON);
2685+
}
2686+
26522687
/**
26532688
* Determine if the geometries contain a Z value
26542689
*

src/test/java/mil/nga/sf/GeometryUtilsTest.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,88 @@ public void testCropIDL() {
10581058
assertEquals(10156058.722522344, cropRing.getPoint(4).getY(),
10591059
0.00000000001);
10601060

1061+
polygon = new Polygon();
1062+
ring = new LineString();
1063+
ring.addPoint(new Point(-120.0, -90.0));
1064+
ring.addPoint(new Point(-120.0, 0.0));
1065+
ring.addPoint(new Point(-180.0, 0.0));
1066+
ring.addPoint(new Point(-180.0, -90.0));
1067+
ring.addPoint(new Point(-120.0, -90.0));
1068+
polygon.addRing(ring);
1069+
1070+
envelope = new GeometryEnvelope(
1071+
-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1072+
-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1073+
GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1074+
GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH);
1075+
1076+
meters = GeometryUtils.degreesToMeters(polygon);
1077+
crop = GeometryUtils.crop(meters, envelope);
1078+
degrees = GeometryUtils.metersToDegrees(crop);
1079+
GeometryUtils.minimizeWGS84Geometry(degrees);
1080+
1081+
cropRing = degrees.getRing(0);
1082+
assertEquals(5, cropRing.numPoints());
1083+
assertTrue(cropRing.isClosed());
1084+
1085+
assertEquals(-120.0, cropRing.getPoint(0).getX(), 0.00000000001);
1086+
assertEquals(GeometryConstants.WEB_MERCATOR_MIN_LAT_RANGE,
1087+
cropRing.getPoint(0).getY(), 0.0);
1088+
1089+
assertEquals(-120.0, cropRing.getPoint(1).getX(), 0.0);
1090+
assertEquals(0.0, cropRing.getPoint(1).getY(), 0.0);
1091+
1092+
assertEquals(-180.0, cropRing.getPoint(2).getX(), 0.0);
1093+
assertEquals(0.0, cropRing.getPoint(2).getY(), 0.0);
1094+
1095+
assertEquals(-180.0, cropRing.getPoint(3).getX(), 0.0);
1096+
assertEquals(GeometryConstants.WEB_MERCATOR_MIN_LAT_RANGE,
1097+
cropRing.getPoint(3).getY(), 0.0);
1098+
1099+
assertEquals(-120.0, cropRing.getPoint(4).getX(), 0.00000000001);
1100+
assertEquals(GeometryConstants.WEB_MERCATOR_MIN_LAT_RANGE,
1101+
cropRing.getPoint(4).getY(), 0.0);
1102+
1103+
polygon = new Polygon();
1104+
ring = new LineString();
1105+
ring.addPoint(new Point(-13358338.89519283, -233606567.09255272));
1106+
ring.addPoint(new Point(-13358338.89519283, 0.0));
1107+
ring.addPoint(new Point(
1108+
-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH, 0.0));
1109+
ring.addPoint(
1110+
new Point(-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1111+
-233606567.09255272));
1112+
ring.addPoint(new Point(-13358338.89519283, -233606567.09255272));
1113+
polygon.addRing(ring);
1114+
1115+
crop = GeometryUtils.crop(polygon, envelope);
1116+
1117+
cropRing = crop.getRing(0);
1118+
assertEquals(5, cropRing.numPoints());
1119+
assertTrue(cropRing.isClosed());
1120+
1121+
assertEquals(-13358338.89519283, cropRing.getPoint(0).getX(),
1122+
0.00000001);
1123+
assertEquals(-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1124+
cropRing.getPoint(0).getY(), 0.00000001);
1125+
1126+
assertEquals(-13358338.89519283, cropRing.getPoint(1).getX(), 0.0);
1127+
assertEquals(0.0, cropRing.getPoint(1).getY(), 0.0);
1128+
1129+
assertEquals(-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1130+
cropRing.getPoint(2).getX(), 0.0);
1131+
assertEquals(0.0, cropRing.getPoint(2).getY(), 0.0);
1132+
1133+
assertEquals(-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1134+
cropRing.getPoint(3).getX(), 0.0);
1135+
assertEquals(-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1136+
cropRing.getPoint(3).getY(), 0.00000001);
1137+
1138+
assertEquals(-13358338.89519283, cropRing.getPoint(4).getX(),
1139+
0.00000001);
1140+
assertEquals(-GeometryConstants.WEB_MERCATOR_HALF_WORLD_WIDTH,
1141+
cropRing.getPoint(4).getY(), 0.00000001);
1142+
10611143
}
10621144

10631145
/**

0 commit comments

Comments
 (0)