전국 산 위치정보.xlsx

2020 전국산불데이터.xlsx

2021 전국산불데이터.xlsx

2022 전국산불데이터.xlsx

2023 전국산불데이터.xlsx

최단거리 산 찾기.ipynb

최단거리 산 기상데이터.ipynb

발생시간별 기상 데이터 가져오기 .ipynb

20~23 전국 산불 데이터 총합.xlsx

# 최단거리 산 찾기
import pandas as pd
from geopy.distance import geodesic

# 파일 경로 설정
fire_data_path = r'C:\\Users\\ASUS\\SAI\\2024 전국산불데이터.xlsx'
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\전국 산 위치정보.xlsx'
output_path = r'C:\\Users\\ASUS\\SAI\\전국_가장_가까운_산_결과_2024.xlsx'

# 데이터 읽기
fire_data = pd.read_excel(fire_data_path)
mountain_data = pd.read_excel(mountain_data_path)

# 필요한 컬럼 이름 확인 후, 가정: 산불 데이터에 '위도', '경도', 산 데이터에 '산 이름', '위도', '경도'가 존재
fire_locations = fire_data[['발생연월일', '위도', '경도']].dropna().reset_index(drop=True)
mountain_locations = mountain_data[['산이름', '위도', '경도']].dropna().reset_index(drop=True)

# 결과를 저장할 리스트 초기화
results = []

# 산불 위치별 가장 가까운 산 찾기
for idx, fire in fire_locations.iterrows():
    where = fire['발생연월일']
    fire_coord = (fire['위도'], fire['경도'])
    closest_mountain = None
    closest_distance = float('inf')
    
    for _, mountain in mountain_locations.iterrows():
        mountain_coord = (mountain['위도'], mountain['경도'])
        distance = geodesic(fire_coord, mountain_coord).kilometers
        
        if distance < closest_distance:
            closest_distance = distance
            closest_mountain = mountain['산이름']
    
    # 결과 저장
    results.append({
        '산불_발생시기': where,
        '산불_위도': fire['위도'],
        '산불_경도': fire['경도'],
        '가장_가까운_산': closest_mountain,
        '거리(km)': closest_distance
    })

# 결과를 데이터프레임으로 변환
result_df = pd.DataFrame(results)

# 엑셀 파일로 저장
result_df.to_excel(output_path, index=False)
print(f"결과가 '{output_path}' 파일로 저장되었습니다.")
#최단거리 산 기상데이

import pandas as pd
from geopy.distance import geodesic

# 파일 경로 설정
whether_data_path = r'C:\\Users\\ASUS\\SAI\\2024 강원산불 기상데이터.xlsx'
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\가장_가까운_산_결과_2024.xlsx'
output_path = r'C:\\Users\\ASUS\\SAI\\2024 가장 가까운산 기상데이터 어쩌구.xlsx'

# 데이터 읽기
whether_data = pd.read_excel(whether_data_path)
mountain_data = pd.read_excel(mountain_data_path)

# 필요한 컬럼 이름 확인 후, 가정: 산불 데이터에 '위도', '경도', 산 데이터에 '산 이름', '위도', '경도'가 존재
whether_locations = whether_data[['발생시간','산이름','기압','기온','10m 풍속','2m 풍속', '2미터 습도']].dropna().reset_index(drop=True)
mountain_locations = mountain_data[['산불_발생시기', '가장_가까운_산']].dropna().reset_index(drop=True)

# 결과를 저장할 리스트 초기화
results = []

# 산불 위치별 가장 가까운 산 찾기
for idx, whether in whether_locations.iterrows():
    when = whether['발생시간']
    where = whether['산이름']
    air_t = None
    air_p = None
    air_s10 = None
    air_s2 = None
    suup_2 = None
    for _, mountain in mountain_locations.iterrows():
        if whether['발생시간'] == mountain['산불_발생시기'] :
            if whether['산이름'] == mountain['가장_가까운_산'] :
                air_t = whether['기온']
                air_p = whether['기압']
                air_s10 = whether['10m 풍속']
                air_s2 = whether['2m 풍속']
                suup_2 = whether['2미터 습도']
            else :
                continue
        else :
            continue
        
    
    # 결과 저장
    results.append({
        '발생시기': when,
        '발생위치' : where,
        '기온' : air_t,
        '기압' : air_p,
        '풍속 10m': air_s10,
        '풍속 2m': air_s2,
        '습도 2m': suup_2
    })

# 결과를 데이터프레임으로 변환
result_df = pd.DataFrame(results)
result_df.dropna(axis='index', how = 'any', inplace = True)
result_df
# 엑셀 파일로 저장
result_df.to_excel(output_path, index=False)
print(f"결과가 '{output_path}' 파일로 저장되었습니다.")
# 발생시간 기상 데이터 가져오기

import requests
from xml.etree import ElementTree as ET
import pandas as pd
import time  # 요청 간 대기 시간 추가를 위해 사용

# API 키
SKEY = '04ivMBs+T+/URYubuW0VoEysuWeCU4Oj2pts0CujIh1h3rcbtP2XmmgCOmIhHyBRGI1uGJEBhrY0cuac9lHz0w=='

# 강원 지역의 산불 데이터를 필터링하고 발생 시간 컬럼을 추가하는 함수
def get_fire_data(file_path):
    ffire_data = pd.read_excel(file_path).dropna().reset_index(drop=True)  # 파일 경로의 데이터를 불러옴
    # 발생시간 컬럼 생성 (예: 202311021632) -> YYYYMMDDHHMM 형식
    ffire_data['발생시간'] = ffire_data.apply(
        lambda x: f"{x['발생연']:04}{x['발생월']:02}{x['발생일']:02}", axis=1
    )
    return ffire_data

# 특정 발생 시간에 맞는 기상 데이터를 API에서 가져오는 함수
def get_weather_data(time_str):
    url = '<http://apis.data.go.kr/1400377/mtweather/mountListSearch>'
    params = {
        'serviceKey': SKEY,
        'numOfRows': '1000',
        'pageNo': '1',
        '_type': 'xml',
        'localArea': '10',
        'tm': time_str
    }

    response = requests.get(url, params=params)
    print(f"Requesting data for {time_str}... Status: {response.status_code}")
    if response.status_code == 200:
        root = ET.fromstring(response.content)
        data = []
        for item in root.findall('.//item'):
            data.append({
                '발생시간': time_str,
                '산이름': item.find('obsname').text if item.find('obsname') is not None else None,
                '관측시간': item.find('tm').text if item.find('tm') is not None else None,
                '기압': item.find('pa').text if item.find('pa') is not None else None,
                '기온': item.find('tm2m').text if item.find('tm2m') is not None else None,
                '10m 풍향': item.find('wd10m').text if item.find('wd10m') is not None else None,
                '10m 풍속': item.find('ws10m').text if item.find('ws10m') is not None else None,
                '2m 풍향': item.find('wd2m').text if item.find('wd2m') is not None else None,
                '2m 풍속': item.find('ws2m').text if item.find('ws2m') is not None else None,
                '2m 풍향str': item.find('wd2mstr').text if item.find('wd2mstr') is not None else None,
                '2미터 습도': item.find('hm2m').text if item.find('hm2m') is not None else None,
            })
        
        # 데이터가 없으면 알림
        if not data:
            print(f"No data returned for {time_str}")
        
        return data
    else:
        print(f"Failed to retrieve data for {time_str}: Status code {response.status_code}")
        return []  # 데이터가 없는 경우 빈 리스트 반환

# 산불 데이터 파일에서 발생 시간을 불러와 강원 지역 산불 발생 시간에 맞는 기상 데이터를 추출하고 하나의 파일로 저장
file_path = r'C:\\Users\\ASUS\\SAI\\2021 전국산불데이터.xlsx'  # 산불 데이터 파일 경로
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\전국 산 위치정보.xlsx'

fire_data = get_fire_data(file_path)
close_mountain = get_colsest_monutain(mountain_data_path)

'''
# 전체 기상 데이터를 누적할 리스트 생성
all_weather_data = []

# 강원 지역의 각 발생 시간에 맞는 기상 데이터를 리스트에 추가
for time_str in fire_data['발생시간']:
    weather_data = get_weather_data(time_str)
    if weather_data:  # 데이터가 있는 경우만 누적
        all_weather_data.extend(weather_data)
    time.sleep(1)  # API 요청 간 대기 시간 추가

# 누적된 데이터를 데이터프레임으로 변환
all_weather_df = pd.DataFrame(all_weather_data)
all_weather_df
'''

# 엑셀 파일로 저장 (with 문을 사용)

#output_path = r'C:\\Users\\ASUS\\SAI\\2024 강원산불 기상데이터.xlsx'
#with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
#    all_weather_df.to_excel(writer, index=False)
#print("完了")

산불데이터 넣으면 최근접 관측소 기상데이터 뽑기

import requests
from xml.etree import ElementTree as ET
import pandas as pd
import time
from geopy.distance import geodesic

# API 키
SKEY = '04ivMBs+T+/URYubuW0VoEysuWeCU4Oj2pts0CujIh1h3rcbtP2XmmgCOmIhHyBRGI1uGJEBhrY0cuac9lHz0w=='

# 강원 지역 산불 데이터를 처리하는 함수
def get_fire_data(file_path):
    ffire_data = pd.read_excel(file_path).dropna().reset_index(drop=True)
    ffire_data['발생시간'] = ffire_data.apply(
        lambda x: f"{x['발생연']:04}{x['발생월']:02}{x['발생일']:02}{x['발생시'][:2]}{x['발생시'][3:5]}", axis=1
    )
    ffire_data['발생시간'] = ffire_data['발생시간'].apply(lambda x: x[:-1] + '0')
    # 지역코드 매핑 사전
    region_code_map = {
        "서울": "01",
        "세종": "02",
        "부산": "03",
        "대구": "04",
        "광주": "05",
        "인천": "06",
        "대전": "07",
        "울산": "08",
        "경기": "09",
        "강원": "10",
        "충남": "11",
        "충북": "12",
        "전남": "13",
        "전북": "14",
        "경남": "15",
        "경북": "16",
        "제주": "17"
    }
    
    # 지역코드 설정
    ffire_data['지역코드'] = ffire_data['시'].apply(
        lambda x: region_code_map.get(x, "알수없음")  # 매핑되지 않는 경우 "알수없음" 처리
    )
    print(f"✅ 산불 데이터 로드 완료: {len(ffire_data)}건의 데이터")
    return ffire_data

# 특정 시간의 기상 데이터를 가져오는 함수
def get_weather_data(time_str,loc_str):
    url = '<http://apis.data.go.kr/1400377/mtweather/mountListSearch>'
    params = {
        'serviceKey': SKEY,
        'numOfRows': '1000',
        'pageNo': '1',
        '_type': 'xml',
        'localArea': loc_str,
        'tm': time_str
    }

    try:
        response = requests.get(url, params=params, timeout=10)  # 타임아웃 설정
        if response.status_code == 200:
            root = ET.fromstring(response.content)
            data = []
            for item in root.findall('.//item'):
                data.append({
                    '발생시간': time_str,
                    '산이름': item.find('obsname').text if item.find('obsname') is not None else None,
                    '관측시간': item.find('tm').text if item.find('tm') is not None else None,
                    '기압': item.find('pa').text if item.find('pa') is not None else None,
                    '기온': item.find('tm2m').text if item.find('tm2m') is not None else None,
                    '10m 풍향': item.find('wd10m').text if item.find('wd10m') is not None else None,
                    '10m 풍속': item.find('ws10m').text if item.find('ws10m') is not None else None,
                    '2m 풍향': item.find('wd2m').text if item.find('wd2m') is not None else None,
                    '2m 풍속': item.find('ws2m').text if item.find('ws2m') is not None else None,
                    '2m 풍향str': item.find('wd2mstr').text if item.find('wd2mstr') is not None else None,
                    '2미터 습도': item.find('hm2m').text if item.find('hm2m') is not None else None,
                })
            return data
        else:
            print(f"❌ {time_str} 데이터 요청 실패: HTTP {response.status_code}")
            return []
    except requests.exceptions.Timeout:
        print(f"⚠️ {time_str} 데이터 요청 시간 초과")
        return []
    except requests.exceptions.RequestException as e:
        print(f"⚠️ {time_str} 데이터 요청 실패: {e}")
        return []

# 산불 위치에서 가장 가까운 산을 찾는 함수
def get_closest_mountain(fire_data, mountain_data_path):
    mountain_data = pd.read_excel(mountain_data_path)
    fire_locations = fire_data[['발생시간', '위도', '경도']].dropna().reset_index(drop=True)
    mountain_locations = mountain_data[['산이름', '위도', '경도']].dropna().reset_index(drop=True)
    results = []

    for idx, fire in fire_locations.iterrows():
        fire_coord = (fire['위도'], fire['경도'])
        closest_mountain = None
        closest_distance = float('inf')

        for _, mountain in mountain_locations.iterrows():
            mountain_coord = (mountain['위도'], mountain['경도'])
            distance = geodesic(fire_coord, mountain_coord).kilometers
            if distance < closest_distance:
                closest_distance = distance
                closest_mountain = mountain['산이름']

        results.append({
            '발생시간': fire['발생시간'],
            '위도': fire['위도'],
            '경도': fire['경도'],
            '가장 가까운 산': closest_mountain,
            '거리(km)': closest_distance
        })

    return pd.DataFrame(results)

# 데이터 경로
file_path = r'C:\\Users\\ASUS\\SAI\\2023 전국산불데이터.xlsx'
mountain_data_path = r'C:\\Users\\ASUS\\SAI\\전국 산 위치정보.xlsx'

# 데이터 로드
fire_data = get_fire_data(file_path)
closest_mountain_df = get_closest_mountain(fire_data, mountain_data_path)

# 기상 데이터 추출 및 병합
all_weather_data = []
total_requests = len(fire_data)  # 전체 요청 수

# zip으로 두 컬럼을 동시에 순회
for idx, (time_str, loc_str) in enumerate(zip(fire_data['발생시간'], fire_data['지역코드'])):
    progress = ((idx + 1) / total_requests) * 100
    print(f"🚀 진행 중: {idx + 1}/{total_requests} ({progress:.2f}%) - {time_str}, 지역코드: {loc_str}")
    
    # 해당 발생 시간의 가장 가까운 산 이름 가져오기
    closest_mountain_name = closest_mountain_df[closest_mountain_df['발생시간'] == time_str]['가장 가까운 산'].values[0]
    
    # 기상 데이터 요청
    weather_data = get_weather_data(time_str, loc_str)  # time_str과 loc_str을 함수에 전달
    
    # 가장 가까운 산의 데이터만 필터링
    if weather_data:
        filtered_data = [w for w in weather_data if w['산이름'] == closest_mountain_name]
        all_weather_data.extend(filtered_data)
        print(f"✅ {time_str} - {closest_mountain_name} 데이터 추가됨")
    else:
        print(f"⚠️ {time_str}에 대한 데이터 없음")
    time.sleep(1)  # 요청 간 대기

# 데이터프레임 생성 및 병합
weather_df = pd.DataFrame(all_weather_data)
final_df = pd.merge(closest_mountain_df, weather_df, on='발생시간', how='inner')  # 가장 가까운 산의 데이터만 유지

# 결과 저장
output_file = '2023_산불_기상_데이터_가까운_산.xlsx'
final_df.to_excel(output_file, index=False)
print(f"✅ 데이터가 '{output_file}'로 저장되었습니다!")