본문 바로가기
Web Development/PostgreSQL(PostGIS)

[PostgreSQL / Java] PostGIS Geometry타입의 Point(점) 좌표 SELECT, UPDATE 쿼리(feat. Geometry의 VO타입 설정)

by 감자맹고우 2022. 3. 3.
728x90
반응형

PostGIS

프로젝트에서 위도, 경도 좌표를 사용하는 기능을 개발하게 되었다.

기존에는 MySQL에서 decimal과 같은 DataType을 이용하여 소수점으로 위도(latitude), 경도(longitude)를 따로 저장하여 처리하는 방식으로 기능을 구현했다.

 

그러나, PostgreSQL은 PostGIS라는 유용한 Extension(확장프로그램)을 통해 Geometry 타입으로 좌표를 처리한다.

특히, PostGIS를 설치하면 거리를 계산해주는 등의 함수를 제공하기 때문에 GPS, 좌표 등의 기능 구현 시에는 필수적으로 사용되는 것 같다.

 

그러나, 나는 Geometry 타입을 처음 접하게 되었고, 오래되거나 별로 없는 검색결과에 SELECT, UPDATE 쿼리 조차도 어떻게 처리해야할지, Java에서 VO로 타입을 어떻게 받아서 처리해야할지 막막했다.

그래서 그 내용과 처리 과정을 작성하여 공유하고 의견을 나누고자 한다.

 

 

[ DB 쿼리 ]

 

우선, DB로 Geometry 타입 컬럼에 대한 쿼리를 작성해보자.

이 때, PostGIS에서 여러 가지 함수를 제공하기 때문에 여러가지 방법이 있지만, 나는 가장 프로젝트에 적합한 함수로 처리하였음에 유의하자.

 

[ 예시 ]
- DB 테이블명 : TEST

- DB 식별 컬럼명(PRIMARY KEY) : TEST_ID
- 조회하려고 하는 DB 컬럼명(좌표 정보) : GEO

 

반응형

 

1. 조회 ( ST_X, ST_Y )

 

SELECT 
    ST_X(GEO) AS lat
    , ST_Y(GEO) AS lon
FROM
    TEST

 

한 번에 String으로 결과 값을 받는 함수도 있지만, 위의 쿼리를 통해 X, Y 좌표를 따로 받아서 처리하였다.

 

 

2. 좌표값 추가 ( ST_GEOMFROMTEXT or ST_SETSRID, ST_MAKEPOINT )

 

<!-- ST_GEOMFROMTEXT -->
UPDATE
    TEST
SET
    GEO = ST_GEOMFROMTEXT('POINT(128 37)', 5181)
WHERE
    TEST_ID = 1
    
    
<!-- ST_SETSRID, ST_MAKEPOINT -->
UPDATE
    TEST
SET
    GEO = ST_SETSRID(ST_MAKEPOINT(38, 127), 5181)
WHERE
    TEST_ID = 1

 

다른 방법도 있을 수 있겠지만, 위의 함수를 사용한 방식 2가지가 가장 무난해보였다.

 

이 중에서도 내 스타일은 ST_SETSRID와 ST_MAKEPOINT라는 2개의 함수를 같이 사용한 방식이었다.

전자는 한 개의 함수를 사용하여 효율이 좋아보이고 쿼리가 짧은 장점이 있지만, 후자는 TEXT가 아니라 값으로 입력하기에 보다 직관적인 느낌이라 좋아보였다. 위도, 경도의 입력 순서도 마음에 들었다.

 

ST_MAKEPOINT는 점 좌표를 생성하는 함수이고, ST_SETSRID는 해당 포인트에 어떤 좌표계를 설정할지 정하는 함수이다. 나는 카카오맵을 연계할 생각이었기에 카카오맵의 기준 좌표계인 EPSG:5181 의 5181을 적어주었다.

 

이렇게 쿼리를 작성하면, 정상적으로 DB에 조회, 추가가 되는 것을 확인할 수 있다!

 

 

[ Java(VO) ]

 

이미 위에서 눈치챘겠지만, ST_X와 ST_Y로 Point 전체가 아닌 X, Y 좌표값을 따로 받아오기 때문에

Double 타입으로 받으면 된다.

 

<!-- TestVO -->
@Getter @Setter

private Double lat;
private Double lon;
private String geo;

 

덧붙여 프로젝트에서 PostGIS의 Point 외에 Line 등의 기능도 추후 사용될 예정이기에, 나는 geo 컬럼값도 일단 String으로 받아올 수 있도록 설정해주었다.

 

🤞 도움이 되셨기를 바랍니다. 한 번의 클릭과 댓글은 어딘가의 누군가에게 진실로 큰 힘이 됩니다. 🐱‍🏍

 

728x90
반응형

댓글