IDL/Mapping

ESRI Shapefile의 활용 및 해독에 관하여 (Part 1)

이상우_IDL 2018. 3. 24. 00:58
728x90

오늘은 ESRI Shapefile(이하 "Shape 파일"로 표기합니다)이라고 부르는 특수 포맷 파일을 읽고 그 내용을 해독하여 지도 표출 작업에 활용하는 방법을 알아보고자 합니다. Shape 파일은 지리정보시스템 소프트웨어 기업이며 ArcGIS로 유명한 ESRI에서 개발하여 표준화시킨 데이터 포맷입니다. 이러한 포맷의 Shape 파일은 ArcGIS를 비롯한 다양한 GIS 어플리케이션들에서 사용이 가능합니다. 물론 IDL 및 ENVI에서도 사용 가능한 포맷입니다. 이러한 파일은 내부적으로 각종 지리정보들, 즉 대륙, 섬, 강, 하천등의 위치 및 범위에 해당되는 좌표 정보들을 통합적으로 담고 있습니다. 사용 목적에 따라서 다양한 종류의 Shape 파일들이 존재하기 때문에, 어떤 목적의 지리 정보 표출 작업을 하느냐에 따라 어떤 Shape 파일을 선택하여 사용할지가 결정되기도 합니다.


어쨌든 IDL에서는 이러한 Shape 파일을 다양한 방향으로 활용할 수 있습니다. 단순히 Shape 파일을 읽어서 지도 표출에 활용할 수도 있고, 좀 더 나아가면 Shape 파일의 내부에 담긴 정보들을 추출하여 좀 더 특정한 목적에 맞는 작업을 하는 것도 가능합니다. 그래서 이러한 작업에 관한 내용을 여기서 소개를 해볼까 하는데, 아마도 몇 회에 걸쳐 나눠서 소개를 하게 될 것 같습니다.


그러면 먼저 예제로 사용할 Shape 파일을 하나 선택해야 하는데, 여기서는 IDL이 설치된 디렉토리에 이미 포함되어 있는 cntry08.shp라는 파일을 사용해보기로 하겠습니다. 사실 Shape 파일은 단 하나의 파일로 존재하지는 않습니다. 실제로는 이름은 같지만 확장자가 shp, shx, dbf인 총 3개의 파일로 구성됩니다. 예제로 사용할 파일의 경우 IDL이 설치된 폴더 내에서 resource/maps/shape라는 하위 폴더안에 존재하는데, 직접 확인해보면 cntry08.shp, cntry08.shx, cntry08.dbf 등 세 개의 파일들이 함께 존재하는 것을 확인할 수 있습니다. 따라서 이 파일의 이름 및 폴더 경로 정보를 다음과 같이 먼저 설정합니다.


file = FILEPATH('cntry08.shp', SUBDIRECTORY=['resource', 'maps', 'shape'])


그러면 이 Shape 파일을 활용하는 예제부터 먼저 살펴보겠습니다. 지도의 표출에 있어서 이 Shape 파일의 내용이 반영되도록 하는 것이 가능합니다. 이를 위해서 다음과 같이 NG 체계의 지도 표출 기능인 MAP, MAPCONTINENTS 함수들을 활용해봅시다.


limit = [10, 70, 60, 150]

win = WINDOW(DIMENSIONS=[800, 500], /NO_TOOLBAR)

m = MAP('Geographic', LIMIT=limit, FILL_COLOR='light blue', $

  MARGIN=0.1, CLIP=0, /CURRENT)

mc = MAPCONTINENTS(file, FILL_COLOR='gold')

m.MapGrid.LABEL_POSITION = 0

m.MapGrid.LINESTYLE = 1


여기서는 동북 아시아 지역의 지도를 표출하는데 있어서 cntry08이라는 Shape 파일이 활용되도록 하였습니다. 앞서 정의했던 file이라는 항목이 MAPCONTINENTS 함수의 인자로 활용된 점을 주목해야 합니다. MAPCONTINENTS 함수는 대륙, 섬, 하천 등의 지리 요소의 윤곽선을 표출하는 역할을 하는데, 여기서는 특정한 Shape 파일의 정보를 활용하여 표출하도록 한 것입니다. 그 결과는 다음 그림과 같습니다.



이 그림을 보면 동북아시아 지역의 지도를 표출하는 것 뿐만 아니라 각 국가별 국경선까지도 함께 표시되어 있는 것을 볼 수 있습니다. 그런데 혹시 IDL에서 지도를 그려본 유저들에게는 이러한 모습이 약간 낯설게 느껴질 수도 있습니다. 그 이유는 MAPCONTINENTS 함수를 활용할 때 굳이 Shape 파일을 따로 지정하지 않고 사용하는 경우가 더 많기 때문입니다. 물론 이러한 경우에는 IDL이 자체적으로 내장하고 있는 지리 정보를 활용합니다. 만약 위의 코드에서 MAPCONTINENTS 함수가 사용된 부분만 다음과 같이 대체할 경우에는 IDL이 알아서 표출합니다.


mc = MAPCONTINENTS(FILL_COLOR='gold')


그 결과는 다음 그림과 같습니다.



이와 같이 간략한 형태의 대륙 경계선만을 표출하게 되는데, 이것이 디폴트입니다. 무난해 보이긴 하지만 이 경우의 문제는 대륙 경계선의 디테일이 그리 높지 않다는 것 그리고 섬들(Islands)이 표시가 전혀 되고 있지 않다는 것입니다. 따라서 만약 여기에 /HIRES 키워드를 추가적으로 사용할 경우에는 대륙 경계선에 대한 좀 더 세세한 묘사뿐 아니라 섬들까지도 표시가 되도록 할 수 있습니다. 물론 이러한 표출의 경우 그만큼 시간은 약간 더 걸립니다.


mc = MAPCONTINENTS(FILL_COLOR='gold', /HIRES)


이 결과는 다음 그림과 같습니다.



어쨌든 바로 위의 두 그림에서 표출된 지도의 모습이 유저들에게는 좀 더 친숙하게 느껴질지도 모르겠습니다. 어쨌든 중요한 것은 MAPCONTINENTS 함수는 Shape 파일을 인자로 사용할 수 있는 기능이 있으며, 이 경우 Shape 파일에 포함된 대륙, 섬 등의 윤곽선 데이터를 사용하게 된다는 것입니다. 따라서 사용자가 어떤 Shape 파일을 지정하느냐에 따라 표출 결과도 달라지게 됩니다. 실제로 지도 표출 작업에 있어서 특수한 목적으로 특수한 Shape 파일(예를 들면 GSHHG Shape 파일)을 사용하여 표출해야 할 경우가 간혹 있을 수 있는데, MAPCONTINENTS 함수에서는 바로 쉽게 활용이 가능합니다. 물론 Shape 파일의 온전한 사용을 위해서는 앞서 언급했던 것처럼 3종의 확장자 파일들이 모두 준비되어야 합니다.


자 그러면 cntry08이라는 Shape 파일로 다시 돌아오겠습니다. 이 데이터를 사용하여 표출된 지도를 우리가 맨 처음에 표출해보았는데,이 지도에서는 각 국가별 국경선이 표시되어 있음을 이미 확인하였습니다. 그런데 이와 같이 모든 국가들의 국경선이 한꺼번에 표출된 지도를 그려보는 것도 충분히 의미가 있겠지만, 혹시 특정 국가에 대한 국경선 데이터만 따로 추출하여 활용해보는 것은 어떨까요? 만약가능하다면 좀 더 다양한 작업들이 가능하지 않을까요? 실제로 가능합니다. 다만 이를 위해서는 Shape 파일을 해독하는 방법에 관한 이해가 어느 정도 필요합니다. 물론 IDL에서도 이러한 작업을 가능하게 해주는 기능이 지원됩니다. 바로 IDLffShape라는 것입니다. 이 기능에 관해서는 IDL 도움말에서 IDLffShape를 검색해보면 바로 확인이 가능합니다. 그런데 도움말에 소개된 IDLffShape에 관한 내용은 그리 호락호락하지가 않아 보입니다. 실제로 맨 앞부분에서는 IDLffShape에 대하여 다음과 같이 소개되어 있습니다.


An IDLffShape object contains geometry, connectivity and attributes for graphics primitives accessed from ESRI Shapefiles. See Overview of ESRI Shapefiles.


여기서 "object"라는 무시무시한 단어가 등장하는데요. 그렇습니다. IDLffShape는 객체(object)의 형태로 그 기능이 지원됩니다. 그것만으로도 일반적인 IDL 유저들에게는 굉장히 까다롭게 느껴질 수도 있습니다. 게다가 구조체(Structure) 및 포인터(Pointer)의 개념에 대한 이해도 어느 정도 필요한 것이 사실입니다. 하지만 그렇다고 무작정 겁먹을 것도 없습니다. 문법적으로 다소 생소한 부분들 몇 개만 감당할 수 있으면 됩니다. 이러한 부분들에 대하여 가급적 충분한 설명을 곁들여가며 내용을 소개해보겠습니다. 우선 특정한 Shape 파일의 정보를 해독하기 위하여 다음과 같이 IDLffShape 객체를 정의해봅시다.


obj = OBJ_NEW('IDLffShape', file)


이와 같이 어떤 Shape 파일에 대응되는 IDLffShape 객체를 생성하면, 이 객체를 통하여 Shape 파일 내의 다양한 정보들을 끄집어낼 수 있는 바탕이 마련됩니다. Shape 파일로부터 추출 가능한 정보들은 크게 두가지 범주로 나눌 수 있습니다. 바로 Entity와 Attribute라는 것입니다. 굳이 해석한다면 Entity는 요소들이고 Attribute는 각 요소별 세부 특성이라고 볼 수 있습니다. 물론 어떤 Shape 파일을 사용중이냐에 따라 달라질 수도 있겠지만, 적어도 우리가 지금 다루고 있는 cntry08의 경우만 본다면, Entity는 각 국가들에 해당되고 Attribute 국가별 세부 데이터라고 보면 됩니다. 따라서 만약 우리나라로 예를 든다면, 한국이라는 Entity에 대한 Attribute에 속한 정보들 중에 국경선 데이터도 포함되어 있다고 보면 됩니다. 그러면 먼저 다음과 같은 방법으로 이 Shape 파일 내에 Entity와 Attribute가 각각 몇 개씩 존재하는지 확인해봅시다.


obj -> GetProperty, N_ENTITIES=n_ent, N_ATTRIBUTES=n_att

PRINT, n_ent, n_att


실제로 출력된 결과를 보면 249와 17이라는 숫자가 나옵니다. 즉 이 Shape 파일 내에는 총 249개의 "국가"들(Entities)이 존재하며, 각 국가별로는 총 17종의 세부특성들(Attributes)이 저장되어 있다는 얘기입니다. 따라서 특정 entity에 대한 attribute들 중에서 내가 필요한 정보를 추출하는 방향으로 작업을 진행하면 됩니다. 이 작업에 관한 구체적인 내용은 조만간 이어질 다음 회차 게시물에서 이어서 소개하도록 하겠습니다.

LIST