Skip to content

Commit

Permalink
Merge pull request #548 from woowacourse-teams/refactor/547-map-jpql
Browse files Browse the repository at this point in the history
지도 검색기능 jpql로 리팩토링
  • Loading branch information
green-kong authored Oct 10, 2023
2 parents 6ef2a07 + 052c0df commit e010354
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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() {
}
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -10,13 +11,15 @@

public interface CafeCoordinateRepository extends JpaRepository<CafeCoordinate, Long> {

@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<CafePinDto> 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<CafePinDto> findCafePinsFromCoordinate(@Param("area") final Polygon area);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -22,7 +23,7 @@ public LocationService(final CafeCoordinateRepository cafeCoordinateRepository)
}

public List<CafeLocationResponse> findCafesFromLocations(final CafeLocationRequest cafeLocationRequest) {
final String area = GeometryGenerator.generateStringPolygon(cafeLocationRequest);
final Polygon area = GeometryGenerator.generatePolygon(cafeLocationRequest);
final List<CafePinDto> cafeLocationDtos = cafeCoordinateRepository.findCafePinsFromCoordinate(area);

return cafeLocationDtos.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -25,24 +27,32 @@ 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);
});
}

@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)
);
});
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<CafePinDto> cafePins = cafeCoordinateRepository.findCafePinsFromCoordinate(area);

//then
assertThat(cafePins).hasSize(1);
assertSoftly(softAssertions -> {
assertThat(cafePins).hasSize(1);
assertThat(cafePins.get(0).getId()).isEqualTo(cafe1.getId());
});
}
}

0 comments on commit e010354

Please sign in to comment.