JPA와 MySQL에서 Point 사용하기

Alex·2024년 9월 6일

Binder프로젝트

목록 보기
4/18

Binder는 쓰레기통 데이터를 DB에 넣는다.

주변 반경에 있는 쓰레기통을 조회하는 기능이 필요하다.

이를 좀더 빠르게 조회할 수있도록 Point 공간 데이터에 인덱스를 설정하기로 했다.

MySQL의 공간 데이터

참고 : 공간 데이터 개념부터 적용까지

MySQL에는 7개의 공간 데이터가 있다.

단일타입은 Point, LineString, Polygon 세 가지가 있다.
나머지는 이것들을 활용하는 것이다.

이 데이터 타입을 쓰면 공간함수를 쓸 수 있게 된다.

SRID

SRID(Spatial Reference Identifier)는 데이터 좌표계를 구분할 수 있는 식별 코드다.

가장 흔하게 사용되는 값은 4326으로 위도(Latitude)와 경도(Longitude)를 사용하여 위치를 표현하는 WGS84 좌표계를 의미한다. 이는 GPS 및 다양한 GIS 솔루션에서 널리 사용된다고 한다. 카카오맵 같은 경우도 이 좌표계를 사용한다.

MySQL에 입력되는 데이터에도 이 SRID 값을 지정해 줄 수가 있다.

CREATE TABLE sridTest2 (
	id bigint auto_increment primary key,
	point point SRID 4326
);

공간 인덱스와 관련해서는 여기에 추가로 정리해둔다.

JPA에서 공간데이터 설정하기

공간 데이터를 생성하는 방법에는 크게 두가지가 있다.
첫 번째는 GeometryFactory 를 사용하는 것이고,
두 번째는 WKTReader를 사용하는 것이다.

@Test  
void createPointWithFactory() {  
    //given  
    final GeometryFactory geometryFactory = new GeometryFactory();  
    final Coordinate coordinate = new Coordinate(180, 90);  
  
    //when  
    final Point point = geometryFactory.createPoint(coordinate);  
    point.setSRID(4326); // SRID 설정  
  
    //then  
    assertThat(point.getX()).isEqualTo(180);  
    assertThat(point.getY()).isEqualTo(90);  
}  

@Test  
void createPointWithWKT() throws ParseException {  
    //given  
    final WKTReader wktReader = new WKTReader();  
    final Geometry read = wktReader.read("POINT(180 90)");  
  
    //when  
    final Point point = (Point) read;  
    point.setSRID(4326);  
  
    //then  
    assertThat(point.getX()).isEqualTo(180);  
    assertThat(point.getY()).isEqualTo(90);  
}

WKTReader를 사용하는 방식은 WKT 를 읽어서 공간 데이터를 생성하는데, WKT는 모든 공간 데이터 타입의 입력이 가능하다. read()의 반환 값이 추상클래스인 Geometry타입을 반환하기에 다운캐스팅이 필요하다.

WKT를 파싱하는 과정에서 발생할 수 있는 ParseException도 처리해줘야 하기에 사용하기에 번거롭기 때문에 GeometryFactory가 편하다고 한다.

어떠한 방식을 사용하든 꼭 한 가지 주의해야 할 점이 있다.
SRID 값이 4326이라는 가정하에, MySQL 에서 사용하는 WKT의 X, Y 값은 각각 위도와 경도이다.

예시) POINT(위도 경도)

그런데 new Coordinate()의 인자와 WKTReader가 읽는 WKT 모두 경도, 위도 순이다.

위도(latitude)와 경도(longitude)
Point(longitude, latitude)
new Coordinate(longitude, latitude)

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글