diff --git a/server/src/main/java/com/project/yozmcafe/domain/cafe/GeometryGenerator.java b/server/src/main/java/com/project/yozmcafe/domain/cafe/GeometryGenerator.java index 394e448e..474fae81 100644 --- a/server/src/main/java/com/project/yozmcafe/domain/cafe/GeometryGenerator.java +++ b/server/src/main/java/com/project/yozmcafe/domain/cafe/GeometryGenerator.java @@ -3,6 +3,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; import com.project.yozmcafe.controller.dto.cafe.CafeLocationRequest; @@ -15,9 +16,6 @@ public class GeometryGenerator { * 그 중, 4326은 WGS84 경위도 좌표계를 의미합니다. GPS 기술에서도 사용되는 좌표계로 범용적으로 가장 널리 사용되는 좌표계입니다. */ private static final int SRID = 4326; - private static final String STRING_POLYGON_FORMAT = "POLYGON((%s))"; - private static final String STRING_GEOMETRY_DELIMITER = " "; - private static final String POINT_DELIMITER = ", "; private GeometryGenerator() { } @@ -28,24 +26,27 @@ public static Point generatePointWithCoordinate(final double latitude, final dou return point; } - public static String generateStringPolygon(final CafeLocationRequest cafeLocationRequest) { + public static Polygon generatePolygon(final CafeLocationRequest cafeLocationRequest) { final double latitude = cafeLocationRequest.latitude(); final double longitude = cafeLocationRequest.longitude(); final double latitudeDelta = cafeLocationRequest.latitudeDelta(); final double longitudeDelta = cafeLocationRequest.longitudeDelta(); - final String minLatitude = String.valueOf(latitude - latitudeDelta); - final String maxLatitude = String.valueOf(latitude + latitudeDelta); - final String minLongitude = String.valueOf(longitude - longitudeDelta); - final String maxLongitude = String.valueOf(longitude + longitudeDelta); - - final String firstVertex = String.join(STRING_GEOMETRY_DELIMITER, minLatitude, maxLongitude); - final String secondVertex = String.join(STRING_GEOMETRY_DELIMITER, maxLatitude, maxLongitude); - final String thirdVertex = String.join(STRING_GEOMETRY_DELIMITER, maxLatitude, minLongitude); - final String fourthVertex = String.join(STRING_GEOMETRY_DELIMITER, minLatitude, minLongitude); - - final String vertexes = String.join(POINT_DELIMITER, firstVertex, secondVertex, thirdVertex, fourthVertex, - firstVertex); - return String.format(STRING_POLYGON_FORMAT, vertexes); + final double minLatitude = latitude - latitudeDelta; + final double maxLatitude = latitude + latitudeDelta; + final double minLongitude = longitude - longitudeDelta; + final double maxLongitude = longitude + longitudeDelta; + + final Coordinate[] vertexes = new Coordinate[]{ + new Coordinate(maxLongitude, minLatitude), + new Coordinate(maxLongitude, maxLatitude), + new Coordinate(minLongitude, maxLatitude), + new Coordinate(minLongitude, minLatitude), + new Coordinate(maxLongitude, minLatitude) + }; + + final Polygon polygon = GEOMETRY_FACTORY.createPolygon(vertexes); + polygon.setSRID(SRID); + return polygon; } } diff --git a/server/src/main/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepository.java b/server/src/main/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepository.java index 7bfc7183..5c493cf8 100644 --- a/server/src/main/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepository.java +++ b/server/src/main/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepository.java @@ -2,6 +2,7 @@ import java.util.List; +import org.locationtech.jts.geom.Polygon; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -10,13 +11,15 @@ public interface CafeCoordinateRepository extends JpaRepository { - @Query(nativeQuery = true, - value = """ - SELECT c.id, c.name, c.address, ST_X(co.coordinate) AS latitude, ST_Y(co.coordinate) AS longitude - FROM cafe_coordinate co - JOIN cafe AS c - ON co.cafe_id = c.id - WHERE ST_CONTAINS(ST_GeomFromText(:area, 4326), co.coordinate); - """) - List findCafePinsFromCoordinate(@Param("area") final String area); + @Query(""" + SELECT + co.cafe.id AS id, + co.cafe.name AS name, + co.cafe.address AS address, + ST_X(co.coordinate) AS latitude, + ST_Y(co.coordinate) AS longitude + FROM CafeCoordinate co + WHERE ST_CONTAINS(:area, co.coordinate) + """) + List findCafePinsFromCoordinate(@Param("area") final Polygon area); } diff --git a/server/src/main/java/com/project/yozmcafe/service/LocationService.java b/server/src/main/java/com/project/yozmcafe/service/LocationService.java index b7e2fe8e..1f065a83 100644 --- a/server/src/main/java/com/project/yozmcafe/service/LocationService.java +++ b/server/src/main/java/com/project/yozmcafe/service/LocationService.java @@ -2,6 +2,7 @@ import java.util.List; +import org.locationtech.jts.geom.Polygon; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,7 +23,7 @@ public LocationService(final CafeCoordinateRepository cafeCoordinateRepository) } public List findCafesFromLocations(final CafeLocationRequest cafeLocationRequest) { - final String area = GeometryGenerator.generateStringPolygon(cafeLocationRequest); + final Polygon area = GeometryGenerator.generatePolygon(cafeLocationRequest); final List cafeLocationDtos = cafeCoordinateRepository.findCafePinsFromCoordinate(area); return cafeLocationDtos.stream() diff --git a/server/src/test/java/com/project/yozmcafe/domain/cafe/GeometryGeneratorTest.java b/server/src/test/java/com/project/yozmcafe/domain/cafe/GeometryGeneratorTest.java index 2d31c8d2..ea56d0f1 100644 --- a/server/src/test/java/com/project/yozmcafe/domain/cafe/GeometryGeneratorTest.java +++ b/server/src/test/java/com/project/yozmcafe/domain/cafe/GeometryGeneratorTest.java @@ -1,11 +1,13 @@ package com.project.yozmcafe.domain.cafe; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; -import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; import com.project.yozmcafe.controller.dto.cafe.CafeLocationRequest; @@ -25,7 +27,7 @@ void generate() { final double resultLongitude = point.getX(); //then - SoftAssertions.assertSoftly(softAssertions -> { + assertSoftly(softAssertions -> { assertThat(srid).isEqualTo(4326); assertThat(resultLatitude).isEqualTo(latitude); assertThat(resultLongitude).isEqualTo(longitude); @@ -33,16 +35,24 @@ void generate() { } @Test - @DisplayName("스트링 폴리곤 생성") - void generateStringPolygonTest() { + @DisplayName("폴리곤 생성 테스트") + void generatePolygonTest() { //given final CafeLocationRequest cafeLocationRequest = new CafeLocationRequest(20, 10, 3, 1); - final String expected = "POLYGON((17.0 11.0, 23.0 11.0, 23.0 9.0, 17.0 9.0, 17.0 11.0))"; //when - final String result = GeometryGenerator.generateStringPolygon(cafeLocationRequest); + final Polygon polygon = GeometryGenerator.generatePolygon(cafeLocationRequest); //then - assertThat(result).isEqualTo(expected); + assertSoftly(softAssertions -> { + assertThat(polygon.getCoordinates()).hasSize(5); + assertThat(polygon.getCoordinates()).containsExactly( + new Coordinate(11, 17), + new Coordinate(11, 23), + new Coordinate(9, 23), + new Coordinate(9, 17), + new Coordinate(11, 17) + ); + }); } } diff --git a/server/src/test/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepositoryTest.java b/server/src/test/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepositoryTest.java index ad0b702a..77fb2f41 100644 --- a/server/src/test/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepositoryTest.java +++ b/server/src/test/java/com/project/yozmcafe/domain/cafe/coordinate/CafeCoordinateRepositoryTest.java @@ -1,11 +1,13 @@ package com.project.yozmcafe.domain.cafe.coordinate; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.Polygon; import org.springframework.beans.factory.annotation.Autowired; import com.project.yozmcafe.BaseTest; @@ -39,12 +41,15 @@ void findCafePinsFromCoordinateWithAreaTest() { cafe2); cafeCoordinateRepository.save(coordinate2); final CafeLocationRequest cafeLocationRequest = new CafeLocationRequest(20, 10, 3, 1); - final String area = GeometryGenerator.generateStringPolygon(cafeLocationRequest); + final Polygon area = GeometryGenerator.generatePolygon(cafeLocationRequest); //when final List cafePins = cafeCoordinateRepository.findCafePinsFromCoordinate(area); //then - assertThat(cafePins).hasSize(1); + assertSoftly(softAssertions -> { + assertThat(cafePins).hasSize(1); + assertThat(cafePins.get(0).getId()).isEqualTo(cafe1.getId()); + }); } }