지도이야기 | Geo 함수 - geojson, envelope, centroid

보람·2022년 3월 27일
2
post-thumbnail

아래와 같이 무수히 많은 좌표들이 모여서 하나의 폴리곤이 있다고 합니다.
스크롤을 한참 해야 끝이 나는 이 데이터는 하나의 폴리곤을 나타내고 있는데 해당 폴리곤이 실제로 맵에서는 어떤식으로 표시되는지 확인하기 위해서는 어떤 방법이 있을까요?

POLYGON((126.97688884275 37.575650779449,126.97703449888 37.569194530055, 126.97597472821 37.569336299426, 126.97537470991 37.569315567022, 126.97433193562 37.569261800518, 126.96904837002 37.568194417708, 126.96854493603 37.568427679613, 126.96664995982 37.569491655207, 126.96628175024 37.569700734799, 126.96609732708 37.569856509724, 126.96572852923 37.570183936115, 126.96592699822 37.570318805686, 126.96601094018 37.571548395577, 126.96365922052 37.57517466066, 126.96308600435 37.576485920016, 126.96284099051 37.576661586093, 126.96281041047 37.579448809657, 126.96742431584 37.579601537124, 126.96742176303 37.579263521442, 126.96743006018 37.579192577999, 126.9674570901 37.578975250585, 126.968066047 37.578246780468, 126.96895511695 37.57793526234, 126.96921284297 37.577935299309, 126.96941453887 37.578121124142, 126.96966442669 37.578531136682, 126.96966721915 37.578736205135, 126.96966877353 37.57899287901, 126.9696694991 37.57911252675, 126.96990457362 37.579301753629, 126.97135197545 37.57951327794, 126.97381925784 37.579372140303, 126.97391736338 37.578487073041, 126.97393961998 37.578240429978, 126.97433153836 37.5757499063, 126.97580378998 37.575649468824, 126.97688884275 37.575650779449))

위 사이트는 geometry 데이터를 에디터 창에 입력하면 올바른 형식일 경우 해당 데이터를 지도에 그리는 사이트입니다.
해당 사이트에서는 geojson이랑 형식에 데이터를 입력해야하는데 geojson이란 아래 설명과 같은 데이터를 의미합니다.

geojson

  • geojson : 위치정보를 갖는 점을 기반으로 체계적으로 지형을 표현하기 위해 설계된 개방형 공개 표준 형식입니다.
  • geojson은 단 한줄로 하나의 지도 객체를 나타낼수도 있으며 적은 용량과 빠른 속도를 갖습니다.
  • 해당 데이터는 네이버맵에서 addGeoJson함수 한줄을 이용하여 무수히 많은 geojson 데이터를 맵에 표시할 수 있습니다.
  • geojson은 아래와 같은 geometry 타입을 지원합니다.
    • point : 점 형식(lat,lng)
    • linestring : 라인형식의 첫점과 끝점이 만나지 않는 형식
    • polygon : 다각형
    • multipolygon : 여러개의 다각형
    • Feature : geometry 객체
    • FeatureCollection : 여러개의 feature 객체

geojson은 아래와 같은 형식을 갖습니다. type에는 위에서 언급한 타입중 한개가 오면 됩니다.

{
  "type": "FeatureCollection",
  "features": []
}

해당 geometry 타입별로 가져야 하는 geojson 형식은 다른데 이러한 geojson 형식대로 나타내주는 함수가 MySQL에 존재합니다.

st_asgeojson(geometry)

해당 함수는 geometry 타입의 지도 데이터를 geojson 형식으로 변환해서 나타내줍니다.

select st_asgeojson(st_geomfromtext('point(126.1234 37.1234)')),
       st_asgeojson(ST_GeomFromText('POLYGON((1 1,4 1, 4 3, 1 3, 1 1))'));


위 이미지와 같이 geojson 형식으로 나타내주는 고마운 함수가 st_asgeojson() 입니다.

위에서 언급했던 수많은 좌표들이 이어진 하나의 폴리곤도 st_asgeojson()함수를 이용한다면 하나의 geojson 데이터를 얻을 수 있고 select된 그 데이터를 geojson.io 페이지에 붙여넣으면 하나의 폴리곤이 표시됨을 확인 할 수 있습니다.

sql

select st_asgeojson(ST_GEOMFROMTEXT(
        'POLYGON((126.97688884275 37.575650779449,126.97703449888 37.569194530055, 126.97597472821 37.569336299426, 126.97537470991 37.569315567022, 126.97433193562 37.569261800518, 126.96904837002 37.568194417708, 126.96854493603 37.568427679613, 126.96664995982 37.569491655207, 126.96628175024 37.569700734799, 126.96609732708 37.569856509724, 126.96572852923 37.570183936115, 126.96592699822 37.570318805686, 126.96601094018 37.571548395577, 126.96365922052 37.57517466066, 126.96308600435 37.576485920016, 126.96284099051 37.576661586093, 126.96281041047 37.579448809657, 126.96742431584 37.579601537124, 126.96742176303 37.579263521442, 126.96743006018 37.579192577999, 126.9674570901 37.578975250585, 126.968066047 37.578246780468, 126.96895511695 37.57793526234, 126.96921284297 37.577935299309, 126.96941453887 37.578121124142, 126.96966442669 37.578531136682, 126.96966721915 37.578736205135, 126.96966877353 37.57899287901, 126.9696694991 37.57911252675, 126.96990457362 37.579301753629, 126.97135197545 37.57951327794, 126.97381925784 37.579372140303, 126.97391736338 37.578487073041, 126.97393961998 37.578240429978, 126.97433153836 37.5757499063, 126.97580378998 37.575649468824, 126.97688884275 37.575650779449))'));

select geojson

{"type": "Polygon", "coordinates": [[[126.97688884275, 37.575650779449], [126.97703449888, 37.569194530055], [126.97597472821, 37.569336299426], [126.97537470991, 37.569315567022], [126.97433193562, 37.569261800518], [126.96904837002, 37.568194417708], [126.96854493603, 37.568427679613], [126.96664995982, 37.569491655207], [126.96628175024, 37.569700734799], [126.96609732708, 37.569856509724], [126.96572852923, 37.570183936115], [126.96592699822, 37.570318805686], [126.96601094018, 37.571548395577], [126.96365922052, 37.57517466066], [126.96308600435, 37.576485920016], [126.96284099051, 37.576661586093], [126.96281041047, 37.579448809657], [126.96742431584, 37.579601537124], [126.96742176303, 37.579263521442], [126.96743006018, 37.579192577999], [126.9674570901, 37.578975250585], [126.968066047, 37.578246780468], [126.96895511695, 37.57793526234], [126.96921284297, 37.577935299309], [126.96941453887, 37.578121124142], [126.96966442669, 37.578531136682], [126.96966721915, 37.578736205135], [126.96966877353, 37.57899287901], [126.9696694991, 37.57911252675], [126.96990457362, 37.579301753629], [126.97135197545, 37.57951327794], [126.97381925784, 37.579372140303], [126.97391736338, 37.578487073041], [126.97393961998, 37.578240429978], [126.97433153836, 37.5757499063], [126.97580378998, 37.575649468824], [126.97688884275, 37.575650779449]]]}


이런식으로 geojson은 해당 geojson.io 사이트에서 확인해볼 수 있으며,

실제로 geojson을 맵으로 표현하도록 지원하는 네이버맵에서는 addGeoJson함수를 이용하여 표시할 수 있습니다! addGeoJson을 사용한 사례는 다른 글에서 작성 후 링크를 걸 예정입니다.

그런데 이렇게 열손가락으로도 셀수가 없는 무수히 많은 좌표들을 단 5개의 좌표로 나타낼 수 있는 함수가 존재합니다.

st_envelope

바로 아래 이미지와 같이 하나의 폴리곤에서 가장 끝 꼭짓점들을 구하고자 할때 사용하는 함수입니다.

sql

select st_asgeojson(st_envelope(ST_GEOMFROMTEXT(
        'POLYGON((126.97688884275 37.575650779449,126.97703449888 37.569194530055, 126.97597472821 37.569336299426, 126.97537470991 37.569315567022, 126.97433193562 37.569261800518, 126.96904837002 37.568194417708, 126.96854493603 37.568427679613, 126.96664995982 37.569491655207, 126.96628175024 37.569700734799, 126.96609732708 37.569856509724, 126.96572852923 37.570183936115, 126.96592699822 37.570318805686, 126.96601094018 37.571548395577, 126.96365922052 37.57517466066, 126.96308600435 37.576485920016, 126.96284099051 37.576661586093, 126.96281041047 37.579448809657, 126.96742431584 37.579601537124, 126.96742176303 37.579263521442, 126.96743006018 37.579192577999, 126.9674570901 37.578975250585, 126.968066047 37.578246780468, 126.96895511695 37.57793526234, 126.96921284297 37.577935299309, 126.96941453887 37.578121124142, 126.96966442669 37.578531136682, 126.96966721915 37.578736205135, 126.96966877353 37.57899287901, 126.9696694991 37.57911252675, 126.96990457362 37.579301753629, 126.97135197545 37.57951327794, 126.97381925784 37.579372140303, 126.97391736338 37.578487073041, 126.97393961998 37.578240429978, 126.97433153836 37.5757499063, 126.97580378998 37.575649468824, 126.97688884275 37.575650779449))')));

select geojson

{"type": "Polygon", 
"coordinates": [[
[126.96281041047, 37.568194417708],
[126.97703449888, 37.568194417708],
[126.97703449888, 37.579601537124],
[126.96281041047, 37.579601537124],
[126.96281041047, 37.568194417708]
]]}

다섯개의 점만 select되는 것을 확인 할 수 있습니다!
select된 geojson 데이터를 geojson.io 사이트에 넣으면
아까 폴리곤이 그려진 동일한 지역에서 하나의 사각형이 표시됨을 알 수 있습니다.

해당 데이터는 조건을 느슨하게 하여 해당 envelope 데이터에 겹치는 부분을 먼저 걸러낸 후에 좀더 세세한 작업을 할 때 사용해볼 수 있습니다.

해당 사각형 혹은 폴리곤에서 딱 중점을 구하고자 할때는 어떻게 할까요?
가장 큰 lng, lat와 가장 작은 lng, lat를 갖고서 두개를 더해 2로 나누면 구할 수도 있겠지만..
계산 대신 아래와 같은 함수를 사용해볼 수 있습니다.

st_centroid(geometry)

select sql

select st_asgeojson(st_centroid(ST_GEOMFROMTEXT(
        'POLYGON((126.97688884275 37.575650779449,126.97703449888 37.569194530055, 126.97597472821 37.569336299426, 126.97537470991 37.569315567022, 126.97433193562 37.569261800518, 126.96904837002 37.568194417708, 126.96854493603 37.568427679613, 126.96664995982 37.569491655207, 126.96628175024 37.569700734799, 126.96609732708 37.569856509724, 126.96572852923 37.570183936115, 126.96592699822 37.570318805686, 126.96601094018 37.571548395577, 126.96365922052 37.57517466066, 126.96308600435 37.576485920016, 126.96284099051 37.576661586093, 126.96281041047 37.579448809657, 126.96742431584 37.579601537124, 126.96742176303 37.579263521442, 126.96743006018 37.579192577999, 126.9674570901 37.578975250585, 126.968066047 37.578246780468, 126.96895511695 37.57793526234, 126.96921284297 37.577935299309, 126.96941453887 37.578121124142, 126.96966442669 37.578531136682, 126.96966721915 37.578736205135, 126.96966877353 37.57899287901, 126.9696694991 37.57911252675, 126.96990457362 37.579301753629, 126.97135197545 37.57951327794, 126.97381925784 37.579372140303, 126.97391736338 37.578487073041, 126.97393961998 37.578240429978, 126.97433153836 37.5757499063, 126.97580378998 37.575649468824, 126.97688884275 37.575650779449))')));

select geojson

{"type": "Point", "coordinates": [126.97014369441878, 37.57410804599561]}

실제 테이블로 조회 MySQL 8.1, SRID = 4326인 경우

select st_asgeojson(st_centroid((ST_GeomFromText(st_astext(geometry_col))))) from table_nm;

이미 4326으로 설정돼있는 폴리곤의 중심점을 구하기 위해선 위 같은 sql로 조회를 하면 됩니다.

실제로 세가지의 함수들은 지역 관련된 연산을 할 때 유용하게 쓰였던 함수입니다.
다음 글에서 st_centroid와 st_envelope함수를 사용한 사례를 작성하려고 합니다.

profile
백엔드 개발자

0개의 댓글