지도로 말하기/튜토리얼 따라하기

AutoGIS Excercise-1 : txt파일에서 shapely point 만들기

코드아키택트 2024. 1. 13. 15:23
반응형

안녕하세요 집DS 입니다. 좌표 데이터는 다양한 형태로 존재합니다. DB에 저장되어 있을 수도 있고, json 등 파일 형태로 저장되어 있을 수도 있습니다. 오늘은 텍스트 데이터로부터 geo dataframe을 읽는 내용을 중심으로 이야기를 써보겠습니다.

목차
- 데이텀(Datum)과 투영
- 텍스트 파일에서 포인트 생성

 

지도의 생성 이해 (https://www.youtube.com/watch?v=ljZOyxo7QDQ)

 

1. 데이텀과 투영

지도를 쉽게 쓰고 있지만 지도가 어떻게 만들어지는 어느정도 이해가 필요합니다. 그래야 코드에 나오는 crs(coordinate reference system) 등에 대해서 알 수 있습니다.

위에 첨부한 그림을 보게되면 지도를 만드는 과정을 한 장으로 압축했다고 볼 수 있습니다. 위 그림을 차근차근 뜯어보면 지도가 만들어지는 과정을 이해할 수 있습니다.

 

1단계 타원체 정의하기

 

지도의 생성 이해 (https://www.youtube.com/watch?v=ljZOyxo7QDQ)

우리가 배운 지식에서는 지구는 타원 비슷하다고 배웠습니다. 근데 사실 지구의 형상이라는 것은 끊임없이 변하고 있고, 그 모양 자체도 굉장히 쭈구리처럼 생겼습니다. 하지만 이런 쭈구리를 가지고 어떤 좌표를 정의하는 일은 상당히 복잡한 일이 됩니다. 그렇다면 오차가 적은 타원체를 지구의 형상으로 정의하자는 이야기가 성립합니다. 여러 가지 복잡한 계산이 있겠지만, 이렇게 정의한 타원체를 데이텀(Datum)이라고 합니다. 저의 짧은 지식이 맞다면 WGS84라는 타원체를 현재 표준으로 정의하고 있습니다. 

따라서 일단 타원체라는것은 WGS84라는 모양을 따르고 있구나 정도로 이해하고 넘어가면 됩니다. 가끔 다른 타원체 형태를 가진 애들도 있을 텐데 이들을 WGS84로 바꾸는 일도 종종 있었던 것으로 기억합니다.

 

2단계 : 타원체를 펴기

 

지도의 생성 이해 (https://www.youtube.com/watch?v=ljZOyxo7QDQ)

귤을 까본다고 생각해봅시다. 귤껍질을 평평하게 깔 수 있을까요? 고등학교 때 배운 미분의 개념까지, 그러니까 아주 잘게 쪼개면 평면이 될 수 있습니다. 근데 이런 친구들은 평평하게 펴지지가 않습니다. 저의 이전 업인 파사드 컨설팅 측면에서 보면 이는 Double curved surface이기 때문에 불가능합니다. 그래서 지도 쪽에선 해당 형상을 가장 유사하게 추정할 수 있는 Single Curved Surface에 투영시켜 지도를 만듭니다. 

용어들은 다르지만 핵심은 그것입니다. 평면에 누르던, 원뿔에 누르던, 원통에 누르던 이야기는 다 비슷비슷합니다. 각 투영방법은 각각 용도가 있습니다. 가령 우리나라에 가장 적합한 방식은 우리나라를 기준으로 가장 오차가 적은 원뿔일 수도 있고, 원통일 수도 있습니다. 하여튼 그런게 개념인데 좀 더 깊은 건 제가 공부하면서 추가해 보도록 하겠습니다.

아무튼 이렇게 투영을 하고 난 후에는 저희가 흔히 아는 2차원 지도로 만들 수 있습니다.

 

투영방법에 따른 지도들


2. 텍스트 파일에서 포인트 생성

이제 텍스트 파일에서 포인트를 만들어 봅시다. 데이터는 다음과 같이 생겼습니다.

파일 확장자
이 챕터에서 다루는 데이터

 

 

1단계 : Pandas Dataframe으로 읽어오기

위 데이터를 보면 ";"로 나뉜것을 볼 수 있습니다. 그리고 확장자는 txt파일입니다. 그렇다면 이 데이터를 판다스에서 읽기 위해서는 어떻게 해야 할까요? 여러 방법이 있겠지만 여기서는 read_table을 쓰도록 합시다. 저는 다음과 같이 코드를 써서 우선 pandas dataframe으로 넘겨왔습니다.

 

import pandas as pd
data = pd.read_table("./data/travel_times_2015_helsinki.txt",delimiter=";",header=0)

 

요즘 워낙 코드를 잘 쓰셔서 다들 잘 아실거 같습니다. 그래도 위 구문을 써보자면 이렇습니다.

가장 처음 나오는 친구는 데이터의 위치를 뜻합니다. 보통은 실행되는 파일을 기준으로 상대위치를 넣으면 됩니다.

두 번째는 delimeter입니다. 데이터를 다루시다 보면 자주 접하게 되는 용어입니다. 한국말로는 "구분문자"가 좀 더 정확한 용어인 거 같네요. 지금 데이터를 보게 되면 ";"로 각 column이 나뉜 것을 볼 수 있습니다. 따라서 ;를 기준으로 각데이터를 나누면 됩니다. 

마지막은 header입니다. 각 column이 어떤 뜻을 가지는지 설명하는 제목이라고 볼 수 있습니다. pd.read_table을 기준으로, header=0이면 가장 첫 행을 column의 제목으로 쓴다는 뜻입니다. 만약 header가 없는 데이터를 쓴다면 해당 header=None으로 설정하면 됩니다.

위 코드를 거쳐 받은 데이터를 확인해보면 아래와 같습니다.

data.head()

 

2단계 원하는 column만 가져오기

이제 데이터를 불러왔습니다. 그 중 원하는 column만 가져오는 작업을 진행해야 합니다.  pandas 문법은 다음과 같습니다.

data = data[["from_x","from_y","to_x","to_y"]]
data

pandas에서 특정 column만 가져오는 방법은 위 문법과 같습니다. yourdataframe[[columns as list]]와 같은 방식입니다. 저도 항상 헷갈리지만 그리 어렵진 않습니다. 이제 포인트를 만들기 위한 필요한 데이터만 모았습니다.

3단계 포인트 만들기

위 데이터를 보면 시작점과 끝점으로 이루어진 것을 볼 수 있습니다. 그럼 잘 생각해보면 하나의 행에서 4개의 데이터 중 앞의 두 개의 데이터는 시작점을, 뒤의 두 개의 데이터는 끝점을 만드는데 쓸 수 있음을 알 수 있습니다. 데이터를 한줄한줄 iteration을 해야 한다고 생각할 수도 있습니다. 과거의 저도 그랬기 때문입니다. 

하지만 pandas를 쓰는 강력한 이유는 병렬 연산(vectorization)을 통해 방대한 데이터를 빠르게 연산할수 있기 때문입니다. 이때 병렬연산을 위해 쓰이는 기능이 apply입니다.  잠시 api문서를 보면 아래와 같습니다.

어떤 dataframe이 있을때 각 열에 어떤 기능을 적용시키고 싶다면 위와 같습니다. lambda function을 통해 각 열에 대해서 하고자 하는 기능을 입력합니다. 만약 이 기능을 통해 나오는 결과가 두 개 이상이라면 index를 통해 각각의 column이름을 넣어줍니다. 그리고 해당 apply가 각 row에 대해 적용되는 것을 알리기 위해 axis=1로 설정합니다.

 

그럼 제가 적용한 코드를 보면 아래와 같습니다.

 

from shapely.geometry import Point
pts_df = data.apply(lambda x:pd.Series(
    [
        Point([x["from_x"],x["from_y"]]),
        Point([x["to_x"],x["to_y"]]),
    ],
    index=["from_pt","to_pt"]),
axis=1)
origin_points = pts_df["from_pt"].to_list()
destination_points = pts_df["to_pt"].to_list()

위 구문을 뜯어보면 다음과 같습니다. 

2개의 row로 된 데이터 프레임인 pts_df를 만듭니다. 이를 위해 data라는 데이터 프레임의 각 row(index=1)에 어떤 기능을 apply합니다. 이 기능은 두 개의 포인트를 만들며 첫 번째 포인트는 data의 column 중 "from_x"와 "from_y"를 참조하고 두 번째 포인트는 "to_x"와 "to_y"를 참조합니다. 이렇게 생긴 두 포인트의 column을 "from_pt", "to_pt"라고 정의합니다.

이를 그림으로 다시 그려보면 아래와 같습니다.

데이터를 확인해보면 아래와 같이 생성된 것을 볼 수 있습니다.

 

jupyter notebook없는 코드로 써보면 아래와 같습니다.

import pandas as pd
from shapely.geometry import Point
#데이터 불러오기
data = pd.read_table("./data/travel_times_2015_helsinki.txt",delimiter=";",header=0)
print(data.head())

# 불러온 포인트 중 필요한 데이터만 가져오기
data = data[["from_x","from_y","to_x","to_y"]]

# 데이터를 포인트로 변경하기
pts_df = data.apply(lambda x:pd.Series(
    [
        Point([x["from_x"],x["from_y"]]),
        Point([x["to_x"],x["to_y"]]),
    ],
    index=["from_pt","to_pt"]),
axis=1)
print(pfs_df.head())

 

끝맺으며

원해 crs바꾸는 것까지 하려고 했는데 이번 예제에서는 나오지 않는군요. 다음번 예제를 하며 다뤄 보도록 하겠습니다.

 

끝.

 

열심히 하는 것보다 중요한 것은 잘하는 것이다
그러나 잘하기 위해서는 열심히 해야 한다
집 DS

참고자료

 
 
[2]
“Exercise 1.” Accessed: Jan. 13, 2024. [Online]. Available: https://autogis-site.readthedocs.io/en/latest/lessons/lesson-1/exercise-1.html
[3]
Map Projections EPSG: 3857 & 4326 | web mapping basics, (2023). Accessed: Jan. 13, 2024. [Online Video]. Available: https://www.youtube.com/watch?v=ljZOyxo7QDQ
[4]
“pandas.DataFrame.apply — pandas 2.1.4 documentation.” Accessed: Jan. 13, 2024. [Online]. Available: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.apply.html#pandas.DataFrame.apply
[5]
“pandas.read_table — pandas 2.1.4 documentation.” Accessed: Jan. 13, 2024. [Online]. Available: https://pandas.pydata.org/docs/reference/api/pandas.read_table.html
https://www.youtube.com/watch?v=ljZOyxo7QDQ

 

반응형

'지도로 말하기 > 튜토리얼 따라하기' 카테고리의 다른 글

AutoGIS Excercise-1  (0) 2023.12.28
Automating GIS Process 2023 시작  (1) 2023.12.26