Project/주차장 입지 및 주차 공유지 후보 선정

[Project] 지역 주차문제 해소를 위한 주차장 입지 및 주차 공유지 후보 선정 1

gangee 2023. 1. 4. 23:07
728x90
반응형

울산광역시 중구지역의 주차장 부족, 불법주정차 문제 해소를 목적으로 주차장 입지 및 주차 공유지 후보 선정

* LH COMPAS에서 주관한 "(울산 경남) 제2회 빅데이터로 우리동네 문제해결 아이디어 공모대회" 에 직접 참가한 프로젝트이다.

1. 분석 목표

  • 주차문제의 근본적인 문제해결을 위해서는 수요와 공급의 불균형 해결 및 해당 지역 부지 내의 효율적인 활용이 필요하다. 따라서 울산광역시 중구의 지역적 특성을 분석하여 이를 분석 지표로 활용하고 부족 주차장 면수를 산출해 개선우선지역을 선정한다. 선정된 개선 우선 지역에 주차공간 확보를 위한 주차장 입지 및 주차장 공유 후보지를 제시하는 것이 목적이다.

2. 데이터 수집

* 모든 데이터는 공공데이터 포털, 행정안전부, 통계청, 울산광역시 중구 차량등록사업소, 건축행정시스템 세움터, 국토교통부 국가공간정보포털 등에서 수집되었다.
  • 자동차 등록대수 데이터, 행정동별 인구 수 및 세대 수 데이터, 건축물 표제부 데이터, 건축물 노후도 데이터, 건축물인허가 주차장 데이터, 불법주정차 단속건수 데이터 등을 수집하였다.

3. 데이터 전처리

  • 데이터 정규화를 위해 MinMaxscaler 객체 생성
scaler = MinMaxScaler()

1. 불법주정차 단속건수 데이터

  • Google API를 이용하여 주소지 데이터를 위경도 데이터로 변환
import googlemaps

googlemaps_key = " (API KEY) "
gmaps = googlemaps.Client(key=googlemaps_key)

def add_to_point(address):
    geo_location = gmaps.geocode(address)[0].get('geometry')

    lat = geo_location['location']['lat']     # 위도
    lng = geo_location['location']['lng']     # 경도

    return lat, lng

junggu_points = []
null_list = []

for i in tqdm(range(len(df))):
    address = df['대지위치'][i]

    try:
        lat, lng = add_to_point(address)
        tmp_dic = {"index":i, "위도":lat, "경도":lng}
        junggu_points.append(tmp_dic)
    except:
        null_list.append(i)

2. 인구 데이터

  • 인구 분포 현황 : 데이터를 Min-Max Scaler로 정규화하고 pydeck을 활용해 지도로 시각화하였다.
mm_scaler = scaler.fit(df[['인구수']])
df['정규화인구'] = mm_scaler.transform(df[['인구수']])

layer = pdk.Layer(
    'PolygonLayer',     
    df, 
    get_polygon='coordinates', 
    get_fill_color='[0, 255*정규화인구, 0]', 
    pickable=True, 
    auto_highlight=True 
)

center =[129.305261,35.571258] 
view_state = pdk.ViewState(
    longitude=center[0],
    latitude=center[1],
    zoom=12)

r = pdk.Deck(layers=[layer],
            mapbox_key=MAPBOX_API_KEY,
            initial_view_state=view_state)
r.to_html('html/정규화 행정동 인구.html')
  • 인구 수 예측 : 페이스북에서 공개한 시계열 예측 Prophet 라이브러리를 이용하여 2022.11 ~2025.10(추후 3년)까지의 인구수를 예측하였다.
from prophet import Prophet 
dong_name = ['학성동', '반구1동', '반구2동', '복산1동', '복산2동', '중앙동', '우정동', '태화동', '다운동', '병영1동', '병영2동', '약사동', '성안동', 'Date']

last_3year = list()
for i in range(2022, 2025):
    for j in range(1, 13):
        last_3year.append(['%04d-%02d' % (i,j)])

for i in range(2025, 2026):
    for j in range(1, 11):
        last_3year.append(['%04d-%02d' % (i,j)])

last_3year = pd.DataFrame(last_3year, columns = ['ds'])
last_3year['ds']= pd.to_datetime(last_3year['ds'])
pd.to_datetime(df['Date'], format='%Y%m')
for i in range(len(df['Date'])):
    date_time_str = df['Date'][i]

    date = datetime.datetime.strptime(str(date_time_str), '%Y%m')

    df['Date'][i] = date
junggu_hangjung_predict = pd.DataFrame()

for i,name in enumerate(dong_name):
    data = pd.DataFrame()
    data = df[[name,'Date']]
    data.columns = ['y','ds']
    data['ds'] = pd.to_datetime(data['ds'])

    model = Prophet().fit(data)
    print(i,"model_fit")

    forecast = model.predict(last_3year)
    print(i,"model_predict")
    junggu_hangjung_predict = pd.concat([junggu_hangjung_predict, forecast['yhat']], ignore_index = True, axis=1)
junggu_hangjung_predict = pd.concat([junggu_hangjung_predict, forecast['ds']], ignore_index = True, axis=1)

junggu_hangjung_predict.columns = ['학성동', '반구1동', '반구2동', '복산1동', '복산2동', '중앙동', '우정동', '태화동', '다운동', '병영1동', '병영2동', '약사동', '성안동', 'Date']

junggu_hangjung_predict=junggu_hangjung_predict[10:]

3. 차량 등록대수 데이터

  • 차량 등록 현황 : 2022년 10월의 행정동별 차량 데이터를 승용차와 승합차 데이터만 산출하여 Min-Max Scaler로 데이터를 정규화하고 pydeck으로 시각화하여 나타내었다.
mm_scaler = scaler.fit(df[['차량수']])
df['정규화차량'] = mm_scaler.transform(df[['차량수']])

layer = pdk.Layer(
    'PolygonLayer',     
    df, 
    get_polygon='coordinates', 
    get_fill_color='[0, 255*정규화차량, 0]', 
    pickable=True, 
    auto_highlight=True 
)

center =[129.305261,35.571258] 
view_state = pdk.ViewState(
    longitude=center[0],
    latitude=center[1],
    zoom=12)

r = pdk.Deck(layers=[layer],
            mapbox_key=MAPBOX_API_KEY,
            initial_view_state=view_state)
r.to_html('html/정규화 행정동 차량.html')

4. 건축물 표제부 데이터

  • 주택 형태 현황 : 주소지를 위경도로 변환하여 행정동 매핑을 하였다. 그리고 pydeck을 이용해 단독주택과 공동주택을 시각화하였다.
  • 단독주택
mm_scaler = scaler.fit(df[['단독주택수']])
df['정규화단독주택수'] = mm_scaler.transform(df[['단독주택수']])

layer = pdk.Layer(
    'PolygonLayer',     
    df, 
    get_polygon='coordinates', 
    get_fill_color='[0, 255*정규화단독주택수, 0]', 
    pickable=True, 
    auto_highlight=True 
)

center =[129.305261,35.571258] 
view_state = pdk.ViewState(
    longitude=center[0],
    latitude=center[1],
    zoom=12)

r = pdk.Deck(layers=[layer],
            mapbox_key=MAPBOX_API_KEY,
            initial_view_state=view_state)
r.to_html('html/정규화 행정동 주택형태(단독).html')
  • 공동주택
mm_scaler = scaler.fit(df[['공동주택수']])
df['정규화공동주택수'] = mm_scaler.transform(df[['공동주택수']])

layer = pdk.Layer(
    'PolygonLayer',     
    df, 
    get_polygon='coordinates', 
    get_fill_color='[0, 255*정규화공동주택수, 0]', 
    pickable=True, 
    auto_highlight=True 
)

center =[129.305261,35.571258] 
view_state = pdk.ViewState(
    longitude=center[0],
    latitude=center[1],
    zoom=12)

r = pdk.Deck(layers=[layer],
            mapbox_key=MAPBOX_API_KEY,
            initial_view_state=view_state)
r.to_html('html/정규화 행정동 주택형태(공동).html')

5. 건축물인허가 주차장 데이터

  • 주차면 수 현황 : 주소지를 위경도로 변환하여 행정동 매핑을 하였고 옥외식주차대수와 옥내식주차대수를 합산해 데이터를 산출하여 pydeck으로 시각화하였다.
mm_scaler = scaler.fit(df[['총주차면수']])
df['정규화주차면수'] = mm_scaler.transform(df[['총주차면수']])

layer = pdk.Layer(
    'PolygonLayer',     
    df, 
    get_polygon='coordinates', 
    get_fill_color='[0, 255*정규화주차면수, 0]', 
    pickable=True, 
    auto_highlight=True 
)

center =[129.305261,35.571258] 
view_state = pdk.ViewState(
    longitude=center[0],
    latitude=center[1],
    zoom=12)

r = pdk.Deck(layers=[layer],
            mapbox_key=MAPBOX_API_KEY,
            initial_view_state=view_state)
r.to_html('html/정규화 행정동 주차면수.html')

6. 주차장 확보율

  • 행정동별 차량 데이터와 건축물인허가 주차장 데이터를 이용해 주차장 확보율 현황을 구하였다.
  • 주차장 확보율(%) = (총 주차면수/차량수)*100
df['주차장확보율'] = (df['총주차면수'] / df['차량수']) * 100
mm_scaler = scaler.fit(df[['주차장확보율']])
df['정규화주차장확보율'] = mm_scaler.transform(df[['주차장확보율']])

layer = pdk.Layer(
    'PolygonLayer',     
    df, 
    get_polygon='coordinates', 
    get_fill_color='[0, 255*정규화주차장확보율, 0]', 
    pickable=True, 
    auto_highlight=True 
)

center =[129.305261,35.571258] 
view_state = pdk.ViewState(
    longitude=center[0],
    latitude=center[1],
    zoom=12)

r = pdk.Deck(layers=[layer],
            mapbox_key=MAPBOX_API_KEY,
            initial_view_state=view_state)
r.to_html('html/정규화 행정동 주차장확보율.html')
728x90
반응형