(ggplot2) coord_sf 지도 CRS, Datum 설정하기

coord_sf() 함수는 ggplot2 패키지에서 사용되는 함수로, Simple Features (sf) 객체를 사용하여 지리적인 데이터를 시각화할 때 좌표 참조 체계와 관련된 설정을 셋팅하는데 사용된다. 이 함수를 사용하여 x와 y 축의 좌표 및 투영(projection) 등을 조절할 수 있다.

CRS & Datum

Datum은 지구의 모양과 크기에 관한 정보를 포함하고 있다. 정확한 좌표를 계산하려면, 좌표 참조 체계(CRS)와 함께 Datum이 정의되어야 한다. coord_sf 함수에는 다양한 파라메터를 셋팅할 수 있는데, 조금씩 바꿔가며 지도의 변화사항을 보기로 한다.

시군구 데이터를 읽어오면, 최초에는 설정이 되어 있지 않아, CRS(좌표참조체계)가 NA 로 나온다.

map_nocrs = read_sf('~/sig_20230729/sig.shp') |> 
  mutate(SIG_KOR_NM = iconv(SIG_KOR_NM, from = "EUC-KR", to = 'UTF-8')) |> 
  ms_simplify(keep = 0.001, keep_shapes = T)

st_crs(map_nocrs)
# 출력결과.
Coordinate Reference System: NA

지도데이터를 다운 받는 곳에 잘 보면, 어떤 좌표계로 만들어진 데이터인지 표시되어 있다. 지금 내가 사용하는 데이터는 EPSG:5179 좌표계이며, st_set_crs() 함수를 이용하여 설정한다. 그러면 crs 정보를 제대로 볼 수 있다.

map_5179 = map_nocrs |> 
  st_set_crs(5179)

st_crs(map_5179)
# 출력결과.
oordinate Reference System:
  User input: EPSG:5179 
  wkt:
PROJCRS["Korea 2000 / Unified CS",
    BASEGEOGCRS["Korea 2000",
        DATUM["Geocentric datum of Korea",
            ELLIPSOID["GRS 1980",6378137,298.257222101,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",4737]],
    CONVERSION["Korea Unified Belt",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",38,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",127.5,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",0.9996,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",1000000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",2000000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["northing (X)",north,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["easting (Y)",east,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Topographic mapping (small scale)."],
        AREA["Republic of Korea (South Korea) - onshore and offshore."],
        BBOX[28.6,122.71,40.27,134.28]],
    ID["EPSG",5179]]

CRS 가 셋팅되어 있으면, Datum 정보가 있기 때문에, 경도/위도로 x/y 축이 표시된다. 하지만 CRS 정보가 없으면 경도/위도로 계산이 안되기 때문에, x/y 축이 숫자로만 나오게 된다. 여기서 중요한건 좌/우 그래프는 동일한 크기로 그려진다는 것이고 x/y 축 정보와 보조선이 다를 뿐이다.

# (지도 1-1) CRS 셋팅이 안되있는 경우,
ggplot(map_nocrs) + 
  geom_sf()

# (지도 1-2) CRS 셋팅되어 있는 경우,
ggplot(map_5179) + 
  geom_sf()

CRS가 셋팅된 데이터를 가지고 몇가지 셋팅을 더 해보자. 지도의 변형없이 coord_sf 함수를 이용해서 x/y 축 정보기준을 바꿀 수 있다.

# (지도 2-1) EPSG:5179의 데이터를 가지고, 
# datum 정보를 EPSG:4326으로 셋팅한 경우,
ggplot(map_5179) + 
  geom_sf() +
  coord_sf(datum = st_crs(4326))

# (지도 2-2) EPSG:5179의 데이터를 가지고, 
# datum 정보를 EPSG:5179으로 셋팅한 경우,
ggplot(map_5179) + 
  geom_sf() +
  coord_sf(datum = st_crs(5179))

마지막으로, coord_sf 에서 crs 정보를 셋팅하면 입력한 좌표참조체계로 그래프를 그리게 된다. EPSG:5179 기준의 지도데이터라서, 굳이 셋팅할 필요는 없지만 coord_sf 에 crs 를 5179로 셋팅하면 지도 3-1 처럼 그려진다. 그리고 crs 를 EPSG:4326 으로 셋팅하면, 경도/위도가 직선으로 펴지면서 지도의 크기와 형태가 살짝 달라진다.

# (지도 3-1) EPSG:5179의 데이터를 가지고, 
# crs 정보를 EPSG:5179으로 셋팅한 경우,
ggplot(map_5179) + 
  geom_sf() +
  coord_sf(crs = st_crs(5179))

# (지도 3-2) EPSG:5179의 데이터를 가지고, 
# crs 정보를 EPSG:4326으로 셋팅한 경우,
ggplot(map_5179) + 
  geom_sf() +
  coord_sf(crs = st_crs(4326))

정확히 대고 봐야 알거 같아서, gif 파일을 만들었다.


더 보면 좋을 글들