본문 바로가기

Programing Language/Python

[Geopandas] 지역 합치기

반응형

[Geopandas] 지역 합치기

지리정보를 다루다 보면, 과거와 현재 지역이 안맞을 때도 있고, 우리나라의 경우 일반시에서 세부구로 나뉜 경우가 있다. (가령, 안산시 단원구 상록구) 이런 경우 두 지역을 안산시로 합쳐줘야 한다. 이럴 때 귀찮은 일이 이만저만이 아니다. 우리나라 shp 파일은 고맙게도 자주 업데이트 해주시는 분이 계시다. (링크) 이 데이터에서 시군구 단위를 기준으로 했을 때, 일반시의 하위 구를 합치는 코드를 작성했다. 이 외에도 특정한 지역들을 합치는 것에 응용할 수 있을 것으로 생각된다.

AIM

  • unary_union을 이용하여 여러 GeoSeries들의 geometry를 하나의 Series로 합치기
import geopandas as gpd

df_geo = gpd.read_file("../Data/Geo/sig.shp", encoding = 'euc-kr')
df_geo = df_geo.set_crs('epsg:5179')

# 내가 가지고있는 df와 어디가 맞지 않는지 확인하기
A = set(df_geo.SIG_KOR_NM)
B = set(df['기초자치단체명'])
print(A - B, B - A)

# Function Define
tgss = [['고양시 덕양구',
  '고양시 일산동구',
  '고양시 일산서구'],
  # '미추홀구',
  ['성남시 분당구',
  '성남시 수정구',
  '성남시 중원구'],
  ['수원시 권선구',
  '수원시 영통구',
  '수원시 장안구',
  '수원시 팔달구'],
  ['안산시 단원구',
  '안산시 상록구'],
  ['안양시 동안구',
  '안양시 만안구'],
  ['용인시 기흥구',
  '용인시 수지구',
  '용인시 처인구'],
  ['전주시 덕진구',
  '전주시 완산구'],
  ['창원시 마산합포구',
  '창원시 마산회원구',
  '창원시 성산구',
  '창원시 의창구',
  '창원시 진해구'],
  ['천안시 동남구',
  '천안시 서북구'],
  ['청주시 상당구',
  '청주시 서원구',
  '청주시 청원구',
  '청주시 흥덕구'],
  ['포항시 남구',
  '포항시 북구']]

def merge_subarea(tgs, round_at=1, crs='epsg:5179'):
    x = df_geo.set_index('SIG_KOR_NM').loc[tgs]

    kor_name = tgs[0].split(' ')[0]
    eng_name = x.SIG_ENG_NM.values[0]
    eng_name = eng_name.split(', ')[-1]

    code = x.SIG_CD.values[0]
    code = int(code)//(10**round_at)*(10**round_at)

    geometry = df_geo.set_index('SIG_KOR_NM').loc[tgs].geometry.unary_union
    _dict = {
        'SIG_KOR_NM': kor_name,
        'SIG_CD': code,
        'SIG_ENG_NM': eng_name,
        'geometry': geometry
    }
    s = pd.DataFrame(_dict, index=[0])
    return gpd.geodataframe.GeoDataFrame(s,
                                        crs=crs,
                                        geometry='geometry')

# Process

temp_res = []
for tgs in tgss:
    x = merge_subarea(tgs)
    temp_res.append(x)

# Export

new_regs = pd.concat(temp_res).set_index('SIG_KOR_NM')

cities = list(A - (A - B))
# df[reg_cols].set_index('기초자치단체명').loc[cities]
ori_regs = df_geo.set_index('SIG_KOR_NM').loc[cities]

tot_regs = pd.concat([ori_regs, new_regs])
tot_regs.SIG_CD = tot_regs.SIG_CD.astype('int')
tot_regs.sort_values('SIG_CD')
tot_regs.reset_index().to_file('../Data/Geo/SIG_merged_v1.shp', encoding='utf-8')
반응형