지도이야기 | 다각형(폴리곤)

보람·2022년 3월 13일
0
post-thumbnail

가로로 화살표를 그리고, 세로로 화살표를 그리고..
그 위로 좌표 4개를 찍습니다.

각각의 좌표값들은

  • (2,2)
  • (4,3)
  • (2,4)
  • (0,3)
    이 됩니다.

그렇게 찍은 4개의 좌표들을 선을 이용하여 이어주면 아래 그림과 같은 다각형이 그려집니다.

건물 한개에 대한 위치를 하나의 포인트라고 하면
네개 건물의 위치를 각각 이어주면 그림과 같은 다각형, 즉 폴리곤이 되는 것입니다.

공유 킥보드 회사에서 제공하는 사용자 앱을 보면 다양한 이동 가능 구역과 주차금지구역이 표시됨을 확인 할 수 있습니다.

만일 저 두번째 이미지와 같이 해당 4개의 좌표를 이은 다각형이 서비스 지역이라고 한다면 우리는 어떤식으로 값을 저장해볼 수 있을까요?

폴리곤 저장

  • (2,2), (4,3), (2,4), (0,3)
    4개의 좌표값이 위와 같다고 할때 해당 값들을 DB에 저장할 수 있는 방법을 떠올려보면 3가지 정도가 있을 것 같습니다.

1. 좌표값을 하나의 포인터 컬럼으로 4행 추가하기

point(2 2)
point(4 3)
point(2 4)
point(0 3)

위같은 형식으로 4개가 생긴다고 하면 감흥이 아직 잘 오지 않습니다.
하지만 점 몇백개, 몇천개를 이어야 하는 폴리곤에 대한 점들을 저장해나간다면 무수히 많은 행들이 테이블에 쌓일 것이고 착잡해질 것입니다.

2. array 형식으로 하나의 text 혹은 json 컬럼에 한 행 추가하기

[[2,2], [4,3], [2,4], [0,3]]

이런식으로 저장한다면요? 이것은 제가 근무를 하면서도 초기에 저장되어져 있던 형식입니다. 그렇다면 다음 방식입니다.

3. 디비 자체에서 제공해주는 polygon 타입 사용하기

POLYGON((2 2,4 3,2 4,0 3, 2 2))

Mysql Geo 타입 중에는 Polygon 이라는 형식을 지원하고 있습니다.
무수히 많은 점들이 이어져 하나의 공간을 만드는 폴리곤 형식의 값을 저장하고자 지원된 데이터 형식입니다.

text? polygon?

위에서 언급된 3가지 방식중에 Polygon 형식을 써야할 것 같은 느낌이 들긴 하는데
두번째 방식과 세번째 방식이 한 행에 모든 점들을 저장하고 있다는 점에서는 크게 다르지 않아서 와닿지 않습니다.
text컬럼과 polygon 컬럼의 차이는 polygon 컬럼이 공간 데이터에 추가할 수 있는 index인 Spatial Index를 제공해준다는 것입니다.

Spatial Index

Spatial Index는 geometry 또는 geo 데이터 형식의 데이터들이 공간 관련된 작업을 좀 더 효율적으로 수행할 수 있습니다.
같은 좌표값들이 저장되는것은 text 컬럼이던 polygon 컬럼이던 동일하겠지만 polygon 컬럼에 Spatial Index를 추가하게 된다면 거리계산, 범위내 데이터 조회시에 훨씬 더 유용하게 쓰일 수 있게 됩니다.

서비스 구역이나 주차금지구역에 대한 폴리곤을 DB에 insert 시켜서 모든 데이터를 화면에 뿌려주기만 했다면 text 컬럼을 계속 사용해도 좋았을 것 같습니다.
하지만 특정 범위에 있는 값만 조회해야 할때도 있고 해당 폴리곤 데이터로 각종 연산을 하기도 해야 했기에 text 컬럼에 값으로는 좀 더 효율적으로 데이터를 사용할 수 없었습니다.

그렇게 어떤식으로 해야 지도 데이터를 좀 더 효율적으로 빠르게 가져올 수 있을까를 연구하는 업무를 맡게 되었고 거기서 찾았던게 geo-type, spatial index 그리고 그것들을 다양한 형식으로 조회할 수 있는 함수들이었습니다.

Polygon 컬럼 사용하기

Polygon 타입을 추가하고 insert 하는것은 아래와 같습니다.

Add Column

ALTER TABLE test_tb  ADD COLUMN `test_polygon` polygon;

Add Index

alter table test_tb 
  add spatial index `IDX_TEST_POLYGON` (test_polygon);

Insert

insert into test_tb(test_polygon) values(
ST_GeomFromText('POLYGON((2 2,4 3,2 4,0 3, 2 2))')
);

첫번째 좌표가 마지막에 한번 더 들어가는 이유?

좌표는 분명 네개뿐이었는데 insert 쿼리를 보면 첫번째 좌표가 마지막에 한 번 더 들어감을 볼 수 있습니다. 왜 그럴까요..?

다각형이 그려질 때
첫번째 점과 두번째 점이 만나서 첫번째 선이 그려지고
두번째 점이 세번째 점을 만나서 두번째 선이 그려지고
세번째 점이 네번째 점을 만나서 세번째 선이 그려집니다.

그런데 여기서 끝나면 위 이미지처럼 3개의 선만 그려집니다. 다각형이 아닌 모습이 되게 되는 것이죠!!
네번째 점이 첫번째 점을 만나야 하나의 다각형이 될 수 있기때 첫 좌표가 마지막에 한번 더 들어가게 되는 것입니다.

Select

select st_asgeojson(test_polygon) from test_tb;

그렇게 넣어준 폴리곤 데이터를 geojson 형식으로 select 한다면 아래와 같이 표시됨을 확인 할 수 있습니다.

{"type": "Polygon", "coordinates": [[[2.0, 2.0], [4.0, 3.0], [2.0, 4.0], [0.0, 3.0], [2.0, 2.0]]]}

이렇게 폴리곤까지 저장하였습니다-!

지금 글은 MySQL을 기반으로 작성된 글이지만 geo타입을 제공하는 다른 DB에서도 비슷하게 제공하고 있는 것으로 보입니다.

다음글에서는 이렇게 저장된 geo 타입의 값들을 조금 더 유용하게 사용할 수 있도록 해준 함수에 대해서 작성해보도록 하겠습니다.🌝

profile
백엔드 개발자

0개의 댓글