diff --git a/jts/pom.xml b/jts/pom.xml
new file mode 100644
index 000000000000..afbc543b46fd
--- /dev/null
+++ b/jts/pom.xml
@@ -0,0 +1,93 @@
+
+ 4.0.0
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+ com.baeldung.jts
+ jst-example
+ 1.0-SNAPSHOT
+ jar
+
+
+ 21
+ 21
+ 2.0.17
+ 4.13.2
+ 1.20.0
+ 1.5.18
+ 3.14.0
+ 3.2.4
+
+
+
+ org.locationtech.jts
+ jts-core
+ ${jts.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ ch.qos.logback
+ logback-core
+ ${qos.logback.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${qos.logback.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven.compiler.plugin.version}
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ ${maven.shade.plugin.version}
+
+
+ package
+
+ shade
+
+
+
+
+ com.baeldung.jts.JtsApplication
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jts/src/main/java/com/baeldung/jts/JtsApplication.java b/jts/src/main/java/com/baeldung/jts/JtsApplication.java
new file mode 100644
index 000000000000..e6931fd99bfd
--- /dev/null
+++ b/jts/src/main/java/com/baeldung/jts/JtsApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.jts;
+
+import com.baeldung.jts.utils.GeometryFactoryUtil;
+import org.locationtech.jts.geom.Geometry;
+
+public class JtsApplication {
+
+ public static void main(String[] args) throws Exception {
+
+ }
+
+}
diff --git a/jts/src/main/java/com/baeldung/jts/operations/JTSOperationUtils.java b/jts/src/main/java/com/baeldung/jts/operations/JTSOperationUtils.java
new file mode 100644
index 000000000000..77c79c1bdde5
--- /dev/null
+++ b/jts/src/main/java/com/baeldung/jts/operations/JTSOperationUtils.java
@@ -0,0 +1,57 @@
+package com.baeldung.jts.operations;
+
+import org.locationtech.jts.geom.Geometry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JTSOperationUtils {
+ private static final Logger log = LoggerFactory.getLogger(JTSOperationUtils.class);
+
+ public static boolean checkContainment(Geometry point, Geometry polygon) {
+ boolean isInside = polygon.contains(point);
+ log.info("Is the point inside polygon? {}", isInside);
+ return isInside;
+ }
+
+ public static boolean checkIntersect(Geometry rectangle1, Geometry rectangle2) {
+ boolean intersect = rectangle1.intersects(rectangle2);
+ Geometry overlap = rectangle1.intersection(rectangle2);
+
+ log.info("Do both rectangle intersect? {}", intersect);
+ log.info("Overlapping Area: {}", overlap);
+ return intersect;
+ }
+
+ public static Geometry getBuffer(Geometry point, int intBuffer) {
+ Geometry buffer = point.buffer(intBuffer);
+ log.info("Buffer Geometry: {}", buffer);
+ return buffer;
+ }
+
+ public static double getDistance(Geometry point1, Geometry point2) {
+ double distance = point1.distance(point2);
+ log.info("Distance: {}",distance);
+ return distance;
+ }
+
+ public static Geometry getUnion(Geometry geometry1, Geometry geometry2) {
+ Geometry union = geometry1.union(geometry2);
+ log.info("Union Result: {}", union);
+ return union;
+ }
+
+ public static Geometry getDifference(Geometry base, Geometry cut) {
+ Geometry result = base.difference(cut);
+ log.info("Resulting Geometry: {}", result);
+ return result;
+ }
+
+ public static Geometry validateAndRepair(Geometry invalidGeo) throws Exception {
+ boolean valid = invalidGeo.isValid();
+ log.info("Is valid Geometry value? {}", valid);
+
+ Geometry repaired = invalidGeo.buffer(0);
+ log.info("Repaired Geometry: {}", repaired);
+ return repaired;
+ }
+}
diff --git a/jts/src/main/java/com/baeldung/jts/utils/GeometryFactoryUtil.java b/jts/src/main/java/com/baeldung/jts/utils/GeometryFactoryUtil.java
new file mode 100644
index 000000000000..3893a3deda1f
--- /dev/null
+++ b/jts/src/main/java/com/baeldung/jts/utils/GeometryFactoryUtil.java
@@ -0,0 +1,11 @@
+package com.baeldung.jts.utils;
+
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.io.WKTReader;
+
+public class GeometryFactoryUtil {
+ public static Geometry readWKT(String wkt) throws Exception {
+ WKTReader reader = new WKTReader();
+ return reader.read(wkt);
+ }
+}
diff --git a/jts/src/main/resources/application.properties b/jts/src/main/resources/application.properties
new file mode 100644
index 000000000000..09c71cce3c4e
--- /dev/null
+++ b/jts/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.application.name=jts
diff --git a/jts/src/test/java/com/baeldung/jts/JtsApplicationUnitTest.java b/jts/src/test/java/com/baeldung/jts/JtsApplicationUnitTest.java
new file mode 100644
index 000000000000..adabbb8d7f4c
--- /dev/null
+++ b/jts/src/test/java/com/baeldung/jts/JtsApplicationUnitTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.jts;
+
+import com.baeldung.jts.operations.JTSOperationUtils;
+import com.baeldung.jts.utils.GeometryFactoryUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.locationtech.jts.geom.Geometry;
+
+public class JtsApplicationUnitTest {
+ @Test
+ public void givenPolygon2D_whenContainPoint_thenContainmentIsTrue() throws Exception {
+ Geometry point = GeometryFactoryUtil.readWKT("POINT (10 20)");
+ Geometry polygon = GeometryFactoryUtil.readWKT("POLYGON ((0 0, 0 40, 40 40, 40 0, 0 0))");
+ Assert.assertTrue(JTSOperationUtils.checkContainment(point, polygon));
+ }
+
+ @Test
+ public void givenRectangle1_whenIntersectWithRectangle2_thenIntersectionIsTrue() throws Exception {
+ Geometry rectangle1 = GeometryFactoryUtil.readWKT("POLYGON ((10 10, 10 30, 30 30, 30 10, 10 10))");
+ Geometry rectangle2 = GeometryFactoryUtil.readWKT("POLYGON ((20 20, 20 40, 40 40, 40 20, 20 20))");
+ Assert.assertTrue(JTSOperationUtils.checkIntersect(rectangle1, rectangle2));
+ }
+
+ @Test
+ public void givenPoint_whenAddedBuffer_thenPointIsInsideTheBuffer() throws Exception {
+ Geometry point = GeometryFactoryUtil.readWKT("POINT (10 10)");
+ Geometry bufferArea = JTSOperationUtils.getBuffer(point, 5);
+ Assert.assertTrue(JTSOperationUtils.checkContainment(point, bufferArea));
+ }
+
+ @Test
+ public void givenTwoPoints_whenGetDistanceBetween_thenGetTheDistance() throws Exception {
+ Geometry point1 = GeometryFactoryUtil.readWKT("POINT (10 10)");
+ Geometry point2 = GeometryFactoryUtil.readWKT("POINT (13 14)");
+ double distance = JTSOperationUtils.getDistance(point1, point2);
+ double expectedResult = 5.00;
+ double delta = 0.00;
+ Assert.assertEquals(expectedResult, distance, delta);
+ }
+
+ @Test
+ public void givenTwoGeometries_whenGetUnionOfBoth_thenGetTheUnion() throws Exception {
+ Geometry geometry1 = GeometryFactoryUtil.readWKT("POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))");
+ Geometry geometry2 = GeometryFactoryUtil.readWKT("POLYGON ((10 0, 10 10, 20 10, 20 0, 10 0))");
+
+ Geometry union = JTSOperationUtils.getUnion(geometry1, geometry2);
+ Geometry expectedResult = GeometryFactoryUtil.readWKT("POLYGON ((0 0, 0 10, 10 10, 20 10, 20 0, 10 0, 0 0))");
+ Assert.assertEquals(expectedResult, union);
+ }
+
+ @Test
+ public void givenBaseRectangle_whenAnotherRectangleOverlapping_thenGetTheDifferenceRectangle() throws Exception {
+ Geometry base = GeometryFactoryUtil.readWKT("POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))");
+ Geometry cut = GeometryFactoryUtil.readWKT("POLYGON ((5 0, 5 10, 10 10, 10 0, 5 0))");
+
+ Geometry result = JTSOperationUtils.getDifference(base, cut);
+ Geometry expectedResult = GeometryFactoryUtil.readWKT("POLYGON ((0 0, 0 10, 5 10, 5 0, 0 0))");
+ Assert.assertEquals(expectedResult, result);
+ }
+
+ @Test
+ public void givenInvalidGeometryValue_whenValidated_thenGiveFixedResult() throws Exception {
+ Geometry invalidGeo = GeometryFactoryUtil.readWKT("POLYGON ((0 0, 5 5, 5 0, 0 5, 0 0))");
+ Geometry result = JTSOperationUtils.validateAndRepair(invalidGeo);
+
+ Geometry expectedResult = GeometryFactoryUtil.readWKT("POLYGON ((2.5 2.5, 5 5, 5 0, 2.5 2.5))");
+ Assert.assertEquals(expectedResult, result);
+ }
+}
diff --git a/pom.xml b/pom.xml
index a2cf091e9c9b..48ee7bbba11e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -681,6 +681,7 @@
jmonkeyengine
json-modules
jsoup
+ jts
jws
ksqldb
kubernetes-modules