본문 바로가기
  • 紹睿: 자유롭고 더불어 사는 가치있는 삶
Project/따릉이 및 자전거 데이터 분석

[따릉이] 자전거 도로에 관하여 (2) - 자전거 도로 위치 정보 변환

by 징여 2018. 9. 16.
반응형

자전거 도로에 관하여 정보를 받으면 shp, sbn 등을 받게 되는데, 이 아이들을 불러오고 좌표체계를 바꿔주는 코드이다.

자전거 도로 현황에 관한 정보는 자전거 도로에 관하여 (3)에 가면 있다.(3을 먼저 작성해서 ㅎㅎ...)

In [30]:
import shapefile  
import pandas as pd
from pyproj import Proj, transform  

1. shp파일열기¶

In [2]:
shp_path = './data/자전거도로/2018년/Bicycle_Lane_Seoul.shp'
shp_file = shapefile.Reader(shp_path)

fields = [x[0] for x in shp_file.fields][1:]
records= shp_file.records()
shps = [s.points for s in shp_file.shapes()]

shp_dataframe = pd.DataFrame(columns=fields, data=records)
shp_dataframe = shp_dataframe.assign(coords=shps)
shp_dataframe.head(3)
Out[2]:
ROAD_NAME NAME Shape_Leng Width ROAD_TYPE SEP_FAC PAVE_TYPE PAVE_COLOR NOTES LANE_COLOR LANE_TYPE coords
0 b'\xc3\xb5\xc8\xa3\xb4\xeb\xb7\xce' b'\xb5\xbf\xb4\xeb\xb9\xae\xb1\xb8' 125.337485 0.0 b'\xc0\xda\xc0\xfc\xb0\xc5\xba\xb8\xc7\xe0\xc0... b'\xba\xb8\xb5\xb5\xba\xed\xb7\xb0' b'\xb3\xec\xbb\xf6' b'\xb5\xb5\xb7\xce\xba\xaf' [(206156.42150000017, 551272.0171000008), (206...
1 b'\xc3\xb5\xc8\xa3\xb4\xeb\xb7\xce' b'\xb5\xbf\xb4\xeb\xb9\xae\xb1\xb8' 137.017645 0.0 b'\xc0\xda\xc0\xfc\xb0\xc5\xba\xb8\xc7\xe0\xc0... b'\xba\xb8\xb5\xb5\xba\xed\xb7\xb0' b'\xb3\xec\xbb\xf6' b'\xb5\xb5\xb7\xce\xba\xaf' [(206020.642, 551297.2594000008), (205885.6416...
2 b'\xc3\xb5\xc8\xa3\xb4\xeb\xb7\xce' b'\xb5\xbf\xb4\xeb\xb9\xae\xb1\xb8' 143.576140 0.0 b'\xc0\xda\xc0\xfc\xb0\xc5\xba\xb8\xc7\xe0\xc0... b'\xba\xb8\xb5\xb5\xba\xed\xb7\xb0' b'\xb3\xec\xbb\xf6' b'\xb5\xb5\xb7\xce\xba\xaf' [(205552.6403000001, 551381.5241999999), (2054...

1-1. sbn 파일열기¶

In [3]:
sbn_path = './data/자전거도로/2018년/Bicycle_Lane_Seoul.sbn'
sbn_file = shapefile.Reader(sbn_path)
sbn_fields = [x[0] for x in sbn_file.fields][1:]
sbn_records= sbn_file.records()
sbns = [s.points for s in sbn_file.shapes()]
sbn_dataframe = pd.DataFrame(columns=sbn_fields, data=sbn_records)
sbn_dataframe = sbn_dataframe.assign(coords=sbns)
sbn_dataframe.head(3)
Out[3]:
ROAD_NAME NAME Shape_Leng Width ROAD_TYPE SEP_FAC PAVE_TYPE PAVE_COLOR NOTES LANE_COLOR LANE_TYPE coords
0 b'\xc3\xb5\xc8\xa3\xb4\xeb\xb7\xce' b'\xb5\xbf\xb4\xeb\xb9\xae\xb1\xb8' 125.337485 0.0 b'\xc0\xda\xc0\xfc\xb0\xc5\xba\xb8\xc7\xe0\xc0... b'\xba\xb8\xb5\xb5\xba\xed\xb7\xb0' b'\xb3\xec\xbb\xf6' b'\xb5\xb5\xb7\xce\xba\xaf' [(206156.42150000017, 551272.0171000008), (206...
1 b'\xc3\xb5\xc8\xa3\xb4\xeb\xb7\xce' b'\xb5\xbf\xb4\xeb\xb9\xae\xb1\xb8' 137.017645 0.0 b'\xc0\xda\xc0\xfc\xb0\xc5\xba\xb8\xc7\xe0\xc0... b'\xba\xb8\xb5\xb5\xba\xed\xb7\xb0' b'\xb3\xec\xbb\xf6' b'\xb5\xb5\xb7\xce\xba\xaf' [(206020.642, 551297.2594000008), (205885.6416...
2 b'\xc3\xb5\xc8\xa3\xb4\xeb\xb7\xce' b'\xb5\xbf\xb4\xeb\xb9\xae\xb1\xb8' 143.576140 0.0 b'\xc0\xda\xc0\xfc\xb0\xc5\xba\xb8\xc7\xe0\xc0... b'\xba\xb8\xb5\xb5\xba\xed\xb7\xb0' b'\xb3\xec\xbb\xf6' b'\xb5\xb5\xb7\xce\xba\xaf' [(205552.6403000001, 551381.5241999999), (2054...

2. 한글 인코딩¶

In [4]:
shp_dataframe['ROAD_NAME'] = shp_dataframe['ROAD_NAME'].str.decode('cp949')
shp_dataframe['NAME'] = shp_dataframe['NAME'].str.decode('cp949')
shp_dataframe['ROAD_TYPE'] = shp_dataframe['ROAD_TYPE'].str.decode('cp949')
shp_dataframe['SEP_FAC'] = shp_dataframe['SEP_FAC'].str.decode('cp949')
shp_dataframe['LANE_COLOR'] = shp_dataframe['LANE_COLOR'].str.decode('cp949')
shp_dataframe['PAVE_TYPE'] = shp_dataframe['PAVE_TYPE'].str.decode('cp949')
shp_dataframe['PAVE_COLOR'] = shp_dataframe['PAVE_COLOR'].str.decode('cp949')
shp_dataframe['NOTES'] = shp_dataframe['NOTES'].str.decode('cp949')
shp_dataframe.head(3)
Out[4]:
ROAD_NAME NAME Shape_Leng Width ROAD_TYPE SEP_FAC PAVE_TYPE PAVE_COLOR NOTES LANE_COLOR LANE_TYPE coords
0 천호대로 동대문구 125.337485 0.0 자전거보행자겸용도로 NaN 보도블럭 녹색 도로변 NaN [(206156.42150000017, 551272.0171000008), (206...
1 천호대로 동대문구 137.017645 0.0 자전거보행자겸용도로 NaN 보도블럭 녹색 도로변 NaN [(206020.642, 551297.2594000008), (205885.6416...
2 천호대로 동대문구 143.576140 0.0 자전거보행자겸용도로 NaN 보도블럭 녹색 도로변 NaN [(205552.6403000001, 551381.5241999999), (2054...

2-1. sbn도¶

In [5]:
sbn_dataframe['ROAD_NAME'] = sbn_dataframe['ROAD_NAME'].str.decode('cp949')
sbn_dataframe['NAME'] = sbn_dataframe['NAME'].str.decode('cp949')
sbn_dataframe['ROAD_TYPE'] = sbn_dataframe['ROAD_TYPE'].str.decode('cp949')
sbn_dataframe['PAVE_TYPE'] = sbn_dataframe['PAVE_TYPE'].str.decode('cp949')
sbn_dataframe['PAVE_COLOR'] = sbn_dataframe['PAVE_COLOR'].str.decode('cp949')
sbn_dataframe['NOTES'] = sbn_dataframe['NOTES'].str.decode('cp949')
sbn_dataframe['SEP_FAC'] = sbn_dataframe['SEP_FAC'].str.decode('cp949')
sbn_dataframe['LANE_COLOR'] = sbn_dataframe['LANE_COLOR'].str.decode('cp949')
print(sbn_dataframe.shape, shp_dataframe.shape)
sbn_dataframe.head(3)
(13451, 12) (13451, 12)
Out[5]:
ROAD_NAME NAME Shape_Leng Width ROAD_TYPE SEP_FAC PAVE_TYPE PAVE_COLOR NOTES LANE_COLOR LANE_TYPE coords
0 천호대로 동대문구 125.337485 0.0 자전거보행자겸용도로 NaN 보도블럭 녹색 도로변 NaN [(206156.42150000017, 551272.0171000008), (206...
1 천호대로 동대문구 137.017645 0.0 자전거보행자겸용도로 NaN 보도블럭 녹색 도로변 NaN [(206020.642, 551297.2594000008), (205885.6416...
2 천호대로 동대문구 143.576140 0.0 자전거보행자겸용도로 NaN 보도블럭 녹색 도로변 NaN [(205552.6403000001, 551381.5241999999), (2054...

3. 위도 경도로 바꿔주기¶

In [6]:
import requests
import json
In [7]:
def change_latlon(x, y):
    inProj = Proj(init = 'epsg:5186')
    outProj= Proj(init = 'epsg:4326')
    lon = transform(inProj, outProj, x, y)[0]
    lat = transform(inProj, outProj, x, y)[1]
    return lat, lon
In [8]:
x = shp_dataframe['coords'].iloc[0][1][0]
y = shp_dataframe['coords'].iloc[0][1][1]
change_latlon(x, y)
Out[8]:
(37.56116515164998, 127.06828483534693)

shp파일이나, sbn 파일이나 결과가 똑같아서 하나만 하기로 함!

몇개의 위도경도 값이 있는지 확인¶

In [9]:
sample = []
for idx, row in shp_dataframe.iterrows():
    tmp = row['coords']
    count = len(tmp)
    sample.append(count)
len(sample), shp_dataframe.shape[0]
Out[9]:
(13451, 13451)
In [10]:
shp_dataframe['coords_number'] = sample
result = shp_dataframe[['ROAD_NAME', 'NAME', 'coords', "coords_number"]]
coord_numbers = list(result['coords_number'].unique())
print(coord_numbers)
[2, 4, 3, 5, 6, 8, 14, 7, 10, 13, 16, 11, 17, 23, 9, 40, 37, 33, 12, 20, 26, 15, 22, 18, 19, 21, 62, 25, 46, 34, 44, 0, 29, 50, 83, 61, 28, 31, 38, 27, 54, 36, 45, 24, 57, 42, 66, 47, 73, 30, 32, 86, 71, 35, 51, 49, 95, 39, 78, 80, 64, 58, 109, 43, 55]

0 이 존재하기 때문에 제거해주자

In [11]:
result = result[result['coords_number']!=0]
coord_numbers = list(result['coords_number'].unique())
print(coord_numbers)
[2, 4, 3, 5, 6, 8, 14, 7, 10, 13, 16, 11, 17, 23, 9, 40, 37, 33, 12, 20, 26, 15, 22, 18, 19, 21, 62, 25, 46, 34, 44, 29, 50, 83, 61, 28, 31, 38, 27, 54, 36, 45, 24, 57, 42, 66, 47, 73, 30, 32, 86, 71, 35, 51, 49, 95, 39, 78, 80, 64, 58, 109, 43, 55]
In [12]:
result[result['coords_number']==109]
Out[12]:
ROAD_NAME NAME coords coords_number
12057 NaN 용산구 [(201729.12119999994, 547043.3727000002), (201... 109
In [13]:
result_sample = result.set_index(["NAME"])
In [14]:
result_sample.head(10)
Out[14]:
ROAD_NAME coords coords_number
NAME
동대문구 천호대로 [(206156.42150000017, 551272.0171000008), (206... 2
동대문구 천호대로 [(206020.642, 551297.2594000008), (205885.6416... 2
동대문구 천호대로 [(205552.6403000001, 551381.5241999999), (2054... 2
동대문구 천호대로 [(204762.65220000036, 551854.8541000001), (204... 2
동대문구 천호대로 [(204677.60670000035, 551934.4329000004), (204... 2
동대문구 천호대로 [(204599.11629999988, 552008.6241999995), (204... 2
성동구 천호대로 [(204827.97310000006, 551732.9068), (204865.72... 2
성동구 천호대로 [(206030.50490000006, 551249.1722999997), (206... 2
성동구 아차산로 [(205473.68400000036, 549273.1195), (205347.83... 2
성동구 구의로 [(205034.08270000014, 549405.0739999991), (205... 2
In [15]:
result_sample.pivot_table(index='NAME', columns='ROAD_NAME', aggfunc='count')
Out[15]:
coords ... coords_number
ROAD_NAME 63로 가마산길 가마산로 가산C로 가양대로 가재울미래로 가재울미래로(중로2-1호) 감일남로 강남대로 강동대로 ... 홍제천(우안) 홍제천(좌안) 화곡로65길 화곡로69길 화곡로73길 화랑로 효자로 훈련원로 흑석한강로 흥능길(청량리3)
NAME
강남구 NaN NaN NaN NaN NaN NaN NaN NaN 5.0 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
강동구 NaN NaN NaN NaN NaN NaN NaN NaN NaN 10.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
강북구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
강서구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN 6.0 4.0 8.0 NaN NaN NaN NaN NaN
관악구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
광진구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
구로구 NaN 9.0 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
금천구 NaN NaN NaN 34.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
노원구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN 58.0 NaN NaN NaN NaN
도봉구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
동대문구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN 10.0
동작구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN
마포구 NaN NaN NaN NaN 13.0 NaN NaN NaN NaN NaN ... 26.0 31.0 NaN NaN NaN NaN NaN NaN NaN NaN
서대문구 NaN NaN NaN NaN NaN 2.0 1.0 NaN NaN NaN ... 46.0 76.0 NaN NaN NaN NaN NaN NaN NaN NaN
서초구 NaN NaN NaN NaN NaN NaN NaN NaN 10.0 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
성동구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
성북구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN 22.0 NaN NaN NaN NaN
송파구 NaN NaN NaN NaN NaN NaN NaN 4.0 NaN 12.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
양천구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
영등포구 3.0 NaN 8.0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
용산구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
은평구 NaN NaN NaN NaN 2.0 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
종로구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN 5.0 NaN NaN NaN
중구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN 4.0 NaN NaN
중랑구 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

25 rows × 1004 columns

In [18]:
result_sample.reset_index(inplace=True)
In [20]:
latlon = []
for idx, row in result_sample.iterrows():
    if idx%1000 == 0:
        print(row['ROAD_NAME'])
    tmp = []
    for i in row['coords']:
        x = i[0]
        y = i[1]
        lat, lon = change_latlon(x, y)
        tmp.append((lat, lon))
    latlon.append(tmp)
천호대로
천호대로
중랑천(좌안)
여의대로
목동로
nan
nan
nan
송파대로
nan
nan
관천로 15길
이태원로
nan
In [21]:
result_sample['coords2'] = latlon
In [22]:
result_sample.head(3)
Out[22]:
NAME ROAD_NAME coords coords_number coords2
0 동대문구 천호대로 [(206156.42150000017, 551272.0171000008), (206... 2 [(37.56095825909572, 127.06967941710447), (37....
1 동대문구 천호대로 [(206020.642, 551297.2594000008), (205885.6416... 2 [(37.561186588203796, 127.06814284995941), (37...
2 동대문구 천호대로 [(205552.6403000001, 551381.5241999999), (2054... 2 [(37.56194874916615, 127.06284655236189), (37....
In [25]:
#result_sample.to_csv('./data/자전거도로/2018년/bicycle_road(18).csv', index=False, encoding='utf-8')
In [29]:
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:90% !important;}</style>"))
In [ ]:
 

자전거도로(2018)-Copy1 \


반응형

댓글