GIS

가축질병발생정보 오픈 API 사용법 소개 (2) 가축전염병 GPKG 생성

유병혁 2023. 8. 15. 16:10

안녕하세요? 이번 글은 농림축산식품 공공데이터 포털 제공의 가축질병발생정보 오픈 API 사용법을 정리해 보겠습니다.

바로가기: http://data.mafra.go.kr/opendata/data/indexOpenDataDetail.do?data_id=20151204000000000563

이번 글의 내용은 가축질병발생정보 오픈 API를 통해 수집된 전체 데이터 중 일부를 GPKG 파일로 변환하는 과정을 정리해 보겠습니다.

 

가축질병발생정보 오픈 API 사용법 소개 (1) 데이터 검색 및 다운로드

안녕하세요? 이번 글은 농림축산식품 공공데이터 포털 제공의 가축질병발생정보 오픈 API 사용법을 정리해 보겠습니다. 바로가기: http://data.mafra.go.kr/opendata/data/indexOpenDataDetail.do?data_id=20151204000000

foss4g.tistory.com

먼저 필요한 라이브러리를 가져옵니다. requests는 웹페이지에 요청을 보내고 해당 페이지의 내용을 가져오기 위해 필요한 라이브러리입니다. pandas는 데이터를, geopandas는 지리공간 데이터를 다루기 위한 라이브러리입니다. matplotlib 라이브러리의 pyplot 서브모듈은 다양한 종류의 그래프와 시각화를 생성하는데 주로 사용됩니다. numpy는 수치 계산을 위한 기본적인 패키지입니다. 다음으로 matplotlib의 그래프에서 사용되는 폰트 설정은 KoPubDotum Bold로 설정했습니다.

import requests
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np

plt.rc('font', family='KoPubDotum Bold')

이번 글에서 Open API로 가져온 가축질병발생정보 전체 데이터(livestock_disease.csv)을 데이터프레임으로 읽어옵니다.

# 가축질병발생정보
df = pd.read_csv('livestock_disease.csv', encoding='cp949')
df.head(1)

주어진 데이터셋에서 LKNTS_MN 필드에 있는 가축전염병명의 고유값을 계산하고, 이를 막대 그래프로 시각화해 봅니다. 전체 데이터 중 일부를 선택해 보겠습니다.

# LKNTS_NM 필드의 고유값 계산
unique_values = df['LKNTS_NM'].value_counts()

# 고유값이 많은 순서대로 정렬
unique_values = unique_values.sort_values(ascending=False)

# 막대 그래프 그리기
plt.figure(figsize=(10, 6))
unique_values.plot(kind='bar')
plt.xlabel('가축전염병명')
plt.ylabel('발생 건수')
plt.title('가축전염병 별 발생 건수')
plt.xticks(rotation=90)
for index, value in enumerate(unique_values):
    plt.text(index, value, f'{value:,}', ha='center', va='bottom')
plt.tight_layout()
plt.savefig('livestock_disease0.png')

# 그래프 보여주기
plt.show()

'고병원성 조류인플루엔자'라는 가축전염병에 해당하는 데이터만 선택하여 새로운 데이터프레임인 hpai_df에 복사합니다.

# 고병원성 조류인플루엔자(HPAI) 선택
hpai_df = df[df['LKNTS_NM'] == '고병원성 조류인플루엔자'].copy()
hpai_df.head(1)

연도별 고병원성 조류인플루엔자 발생 건수를 가공하고 시각화해 봅니다. OCCRRNC_DE 필드에 있는 날짜 데이터를 문자열에서 datetime 형식(%Y%m%d)으로 변환하고, 연도 정보만 추출해 시계열 차트를 그려봅니다.

# 날짜 형식 변환
hpai_df['OCCRRNC_DE'] = pd.to_datetime(hpai_df['OCCRRNC_DE'], format='%Y%m%d')

# 연도별 발생 건수 계산
yearly_counts = hpai_df['OCCRRNC_DE'].dt.year.value_counts().sort_index()

# 시계열 차트 그리기
plt.figure(figsize=(10, 6))
yearly_counts.plot(kind='line', marker='o')
plt.xlabel('연도')
plt.ylabel('발생 건수')
plt.title('연도별 고병원성 조류인플루엔자 발생 건수')

# 각 연도의 발생 건수를 텍스트로 표시
for year, count in yearly_counts.items():
    plt.text(year, count, str(count), ha='center', va='bottom')

plt.tight_layout()
plt.savefig('livestock_disease1.png')

# 그래프 보여주기
plt.show()

이번에는 연도와 월별로 고병원성 조류인플루엔자의 발생 건수 데이터를 가공하고 히트맵을 통해 시각화하는 과정입니다. 히트맵은 색상의 변화로 발생 건수의 패턴을 파악하기에 용이한 시각화 방법입니다.

# 연도와 월 컬럼 추가
hpai_df['Year'] = hpai_df['OCCRRNC_DE'].dt.year
hpai_df['Month'] = hpai_df['OCCRRNC_DE'].dt.month

# 연도와 월별 발생 건수 계산
year_month_counts = hpai_df.groupby(['Year', 'Month']).size().unstack(fill_value=0)

# 히트맵 그리기
plt.figure(figsize=(10, 6))
plt.imshow(year_month_counts, cmap='viridis', aspect='auto')

# X, Y 축 레이블 설정
plt.xticks(np.arange(len(year_month_counts.columns)), year_month_counts.columns)
plt.yticks(np.arange(len(year_month_counts.index)), year_month_counts.index)

# 발생 건수 텍스트 표시
for i in range(len(year_month_counts.index)):
    for j in range(len(year_month_counts.columns)):
        plt.text(j, i, str(year_month_counts.iloc[i, j]), ha='center', va='center', color='black')

plt.xlabel('월')
plt.ylabel('연도')
plt.title('연도와 월별 고병원성 조류인플루엔자 발생 건수 히트맵')

plt.colorbar(label='발생 건수')
plt.tight_layout()
plt.savefig('livestock_disease2.png')
plt.show()

이제 카카오 API를 활용하여 주소를 GeoPackage로 변환해 보겠습니다. 주소 정보를 포함한 데이터프레임이 주어졌을 때, 해당 주소로부터 좌표 정보(경도, 위도)를 알아내어 데이터프레임에 추가하고, 이것을 다시 GeoPackage로 변환하는 일련의 과정입니다.

 

카카오 API를 활용한 지오코딩: 주소를 GeoPackage로 변환하기

안녕하세요? 이번 글은 카카오 API를 활용하여 주소를 GeoPackage로 변환하는 방법을 정리해 보겠습니다. 주소 정보를 포함한 데이터프레임이 주어졌을 때, 해당 주소로부터 좌표 정보(경도, 위도)

foss4g.tistory.com

# 카카오 API KEY
API_KEY = "YOUR_API_KEY"

# 주소를 좌표로 변환
def convert_address_to_coordinates(address):
    api_url = "https://dapi.kakao.com/v2/local/search/address.json"
    headers = {"Authorization": f"KakaoAK {API_KEY}"}

    params = {"query": address}
    
    try:
        response = requests.get(api_url, headers=headers, params=params)
        response.raise_for_status()
        result = response.json()

        if "documents" in result and len(result["documents"]) > 0:
            coordinates = result["documents"][0]["y"], result["documents"][0]["x"]
            return coordinates
        else:
            return None
    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")
        return None

# 데이터프레임에 좌표 추가
def add_coordinates_to_dataframe(df, address_column):
    latitudes = []
    longitudes = []

    for address in df[address_column]:
        coordinates = convert_address_to_coordinates(address)
        if coordinates:
            latitudes.append(coordinates[0])
            longitudes.append(coordinates[1])
        else:
            latitudes.append(None)
            longitudes.append(None)

    df["decimalLatitude"] = latitudes
    df["decimalLongitude"] = longitudes

# CSV를 GeoPackage로 변환
def csv_to_gpkg(input_csv, output_gpkg):
    df = pd.read_csv(input_csv)
    gdf = gpd.GeoDataFrame(
        df,
        geometry=gpd.points_from_xy(df.decimalLongitude, df.decimalLatitude),
        crs="EPSG:4326",
    )
    gdf.to_file(output_gpkg, driver="GPKG")
    print("데이터 변환 및 저장 완료:", output_gpkg)

FARM_LOCPLC라는 필드는 농장소재지 주소를 포함하고 있습니다. 여기서는 카카오 API를 활용하여 이 주소로부터 좌표 정보(경도, 위도)를 알아내어 데이터프레임에 추가합니다.

 

참고로 이 데이터에는 FARM_LOCPLC_LEGALDONG_CODE(농장소재지 법정동 코드)라는 필드가 있어, 법정구역정보와 속성 조인이 가능합니다.

%%time

# 주소를 좌표로 변환하여 데이터프레임에 추가
add_coordinates_to_dataframe(hpai_df, 'FARM_LOCPLC')
hpai_df.to_csv('hpai_data.csv', index=False, encoding='utf-8')
hpai_df.head(1)
CPU times: total: 14.5 s
Wall time: 1min 1s

CSV 파일을 다시 GeoPackage로 변환합니다. 이제 GeoPackage 내에 저장된 지오메트리 데이터를 사용하여 QGIS와 같은 프로그램에서 다양한 지리공간 분석이 가능합니다.

input_csv = "hpai_data.csv"
output_gpkg = "hpai_data.gpkg"

csv_to_gpkg(input_csv, output_gpkg)

1925_가축질병발생정보 오픈 API 사용법 소개 (2)_가축전염병 GPKG 생성.ipynb
0.21MB