내용으로 건너뛰기
기상기후데이터위키
사이트 도구
검색
도구
문서 보기
이전 판
역링크
최근 바뀜
사이트맵
>
최근 바뀜
사이트맵
지진_화산:지진
문서의 이전 판을 선택했습니다!
저장하면 이 자료로 새 판을 만듭니다.
미디어 파일
======지진 (Earthquake) 데이터====== [[지진_화산:지진#활용방안|{{:wiki:활용방안클릭.png?250|}}]] 출처: https://www.kma.go.kr/eqk_pub/main2.do =====1. 개요===== 지진은 지구 내부 단층의 급격한 파쇄 혹은 마그마의 이동으로 발생하는 탄성파 현상입니다. 한반도는 유라시아 판 내부에 위치하여 판 경계 지역(일본 등)에 비해 발생 빈도는 낮으나, 지각 내 응력 축적에 따른 중대형 지진(규모 5.0 이상)의 위험이 상존합니다. 기상청은 국가지진방재의 중추로서 지진의 발생 위치(진원, 진앙), 발생 시각, 규모(Magnitude), 그리고 지표면의 흔들림 정도인 진도(Intensity)를 정밀하게 분석하여 데이터를 제공합니다. {{지진_화산:38ea0643-706c-4ef7-9d0b-7806baf81235.png?nolink800}} 출처: https://www.kma.go.kr/eqk_pub/obsrEarthquake.do?tab=3 =====2. 관측 (Observation)===== 국가지진관측망은 지면의 미세한 움직임을 실시간으로 포착하기 위해 다수의 관측소와 고정밀 센서로 구성됩니다. • **관측망 밀집도**: 전국적으로 약 10~20km 간격의 관측망을 구축하여 지진 분석의 정밀도를 높이고 있습니다. • **센서의 종류**: * **속도계(Velocity Sensor)**: 지면 운동의 속도를 측정하며, 초광대역(VBB) 및 광대역 센서는 원거리 및 미세 지진 분석에, 단주기 센서는 근거리 지진 분석에 특화됩니다. * **가속도계(Acceleration Sensor)**: 강지진 발생 시 포화(Saturation) 없이 강한 흔들림을 측정하며, 구조물 및 지반의 동적 특성 분석에 필수적입니다. • **관측 환경**: 배경 잡음(Background Noise)을 최소화하기 위해 지표형 외에도 지하 수십~수백 미터 아래에 설치하는 시추형(Borehole) 관측소를 확대 운영하고 있습니다. {{지진_화산:600da144-d409-4f62-bc62-377ff8676027.png?nolink&800}} =====3. 산출물 (Data Products)===== • **파형 데이터(Waveform Data)**: 관측소에서 기록된 시계열 데이터로, 국제 표준 포맷인 MiniSEED 혹은 SEED 형식으로 제공됩니다. 이는 지각 구조 연구 및 파원을 정밀 분석하는 데 활용됩니다. • **지진 카탈로그(Event Catalog)**: 지진 발생 시각, 진앙 위치(위경도), 진원 깊이, 규모 등을 포함한 속성 데이터베이스입니다. • **지진조기경보(EEW)**: 지진 발생 후 수 초 이내에 파괴력이 큰 S파 도착 시간을 예측하여 전파하는 경보 데이터입니다. • **계기진도 데이터**: 관측된 최대지반가속도(PGA) 또는 속도(PGV)를 기반으로 산출된 지역별 진도 값(MMI 등급)입니다. {{지진_화산:e2e557da9b204239c774af7fe58a06dae7iit1tkhydmy4mp-279.png?nolink800}} ======지진해일 (Tsunami) 데이터====== =====1. 개요===== 지진해일은 해저 지진 등으로 인해 해수면 높이가 급격히 변하며 발생하는 장주기파(Long Wave)입니다. 동해와 같이 수심이 깊은 해역에서 발생한 지진해일은 시속 수백 킬로미터로 이동하며, 연안의 얕은 수심으로 진입할 때 파고가 급증하여 막대한 피해를 입힙니다. 기상청은 일본 서쪽 해역의 대규모 지진에 따른 동해안 내습 가능성을 상시 감시합니다. {{지진_화산:ecece1e04cbacfc0a6efa11338222dbf_1628170432_1722.jpg?nolink800}} =====2. 관측 (Observation)===== 기상청은 울릉도, 임원항 및 정동진에 해일파고계(15m 이상 파고 관측 가능), 연안 방재 관측 시스템(17개소), 해상감시 CCTV(24개소), 국립해양조사원의 조위자료(56개소) 등을 공유하여 실시간으로 감시에 활용하고 있습니다. • **해일파고계**: 연안의 조석 성분을 제외한 해수면의 급격한 변동만을 추출하기 위해 초음파 혹은 수압 센서를 활용합니다. • **조위관측소 공유**: 국립해양조사원의 고정밀 조위 관측 데이터를 실시간으로 수신하여 보완적인 감시망을 운영합니다. {{지진_화산:0d63ac33-4724-4ea4-9b25-f9a54a7feffd.jpg?nolink500}} {{지진_화산:00f9dc56-6094-4a1b-b67d-847c24c05194.jpg?nolink500}} =====3. 산출물 (Data Products)===== • 수치모의 시나리오 DB: 가상 지진 파원에 따른 예상 파고 및 도달 시간을 미리 계산한 6,000여 개의 시나리오 세트입니다. • 지진해일 특보: 예상 파고가 일정 기준(주의보 0.5m, 경보 1.0m 이상)을 초과할 것으로 예상될 때 발표되는 격자형 공간 데이터입니다. • 실시간 해수면 변동 자료: 관측소별로 기록된 지진해일의 최대 파고와 내습 지속 시간 데이터입니다. {{지진_화산:4f6b31d517c8401fc11367483f6fd152mWHLeeTs6IHCjIAP-673.png}} ===== 4. 활용방안 ===== 소스코드 : {{ :지진_화산:earthquake_epicenter_example.py |}} ==== 4.1. 라이브러리 설치 및 기본 설정 ==== 지진목록 자료를 조회하고 최근 1년 지진의 진앙 분포도를 시각화하기 위해 필요한 라이브러리를 설치합니다. <code py> pip install requests pandas matplotlib cartopy </code> <code py> import os from datetime import datetime, timedelta import requests import pandas as pd import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt from matplotlib import font_manager from matplotlib.lines import Line2D import cartopy.crs as ccrs import cartopy.feature as cfeature </code> API 인증키와 API 주소, 조회 기간, 결과 파일명을 설정합니다. <code py> AUTH_KEY = "본인의_API_인증키" BASE_URL = "https://apihub.kma.go.kr/api/typ01/url/eqk_list.php" START_TM = None END_TM = None DISP = 1 HELP = 1 OUTPUT_CSV = "earthquake_list_last_1year.csv" RAW_TEXT_FILE = "earthquake_raw_response.txt" OUTPUT_PNG_ALL = "earthquake_epicenter_map_all.png" OUTPUT_PNG_M2 = "earthquake_epicenter_map_m2.png" OUTPUT_PNG_M4 = "earthquake_epicenter_map_m4.png" OUTPUT_PNG_M6 = "earthquake_epicenter_map_m6.png" OUTPUT_PNG_M8 = "earthquake_epicenter_map_m8.png" </code> BASE_URL은 (신)기상자료개방포털 > API > 지진/화산 > 국내·외 지진정보 > 지진목록(임의기간의 지진정보) 조회 메뉴의 호출 URL을 사용합니다. START_TM과 END_TM을 None으로 설정하면 현재 시각 기준 최근 1년 기간을 자동으로 조회합니다. ==== 4.2. 지진목록 자료 조회 및 정리 ==== 조회 시작시각과 종료시각을 yyyyMMddHHmm 형식으로 생성합니다. <code py> def make_time_range(): if START_TM is not None and END_TM is not None: return START_TM, END_TM now = datetime.now() one_year_ago = now - timedelta(days=365) tm1 = one_year_ago.strftime("%Y%m%d%H%M") tm2 = now.strftime("%Y%m%d%H%M") return tm1, tm2 </code> 지진목록 API를 호출하여 응답 원문 TEXT를 받아옵니다. <code py> def fetch_earthquake_text(tm1, tm2): params = { "tm1": tm1, "tm2": tm2, "disp": DISP, "help": HELP, "authKey": AUTH_KEY, } response = requests.get(BASE_URL, params=params, timeout=60) response.raise_for_status() text = response.text with open(RAW_TEXT_FILE, "w", encoding="utf-8") as f: f.write(text) return text </code> API 응답에는 설명 줄과 실제 데이터 줄이 함께 포함됩니다. 설명 줄은 #으로 시작하므로 제외하고, 숫자로 시작하는 줄만 실제 지진 데이터로 사용합니다. <code py> def extract_data_lines(text): lines = [] for raw_line in text.splitlines(): line = raw_line.strip() if not line: continue if line.startswith("#"): continue if line[0].isdigit(): lines.append(line) return lines </code> 응답 데이터 중 진앙 분포도 작성에 필요한 컬럼만 사용합니다. <code py> COLUMNS = [ "TP", "TM_FC", "SEQ", "TM_EQK_MSC", "MT", "LAT", "LON", "LOC", ] </code> 추출한 데이터 줄을 pandas DataFrame으로 변환합니다. <code py> def parse_text_to_dataframe(text): lines = extract_data_lines(text) if len(lines) == 0: return pd.DataFrame(columns=COLUMNS) rows = [] for line in lines: line = line.strip() if line.endswith(",="): line = line[:-2] parts = line.split(",", 7) if len(parts) < 8: continue tp = parts[0].strip() tm_fc = parts[1].strip() seq = parts[2].strip() tm_eqk_msc = parts[3].strip() mt = parts[4].strip() lat = parts[5].strip() lon = parts[6].strip() rest = parts[7].strip() loc = rest.split(",", 1)[0].strip() rows.append([tp, tm_fc, seq, tm_eqk_msc, mt, lat, lon, loc]) df = pd.DataFrame(rows, columns=COLUMNS) return df </code> 숫자형 컬럼과 시간 컬럼을 변환하고, 지도 표출에 필요한 규모, 위도, 경도 값이 없는 행은 제거합니다. <code py> def clean_dataframe(df): if df.empty: return df df = df.copy() numeric_cols = ["TP", "SEQ", "MT", "LAT", "LON"] for col in numeric_cols: df[col] = pd.to_numeric(df[col], errors="coerce") df["datetime_eqk"] = pd.to_datetime( df["TM_EQK_MSC"], format="%Y%m%d%H%M%S.%f", errors="coerce" ) df["datetime_fc"] = pd.to_datetime( df["TM_FC"], format="%Y%m%d%H%M", errors="coerce" ) df = df.dropna(subset=["MT", "LAT", "LON"]).copy() df = df.sort_values("datetime_eqk").reset_index(drop=True) return df </code> ==== 4.3. 지진 진앙 분포도 저장 ==== 지진 규모를 M2, M4, M6, M8 구간으로 분류합니다. <code py> def classify_magnitude(mt): if pd.isna(mt): return "UNKNOWN" mt = float(mt) if mt < 4.0: return "M2" elif mt < 6.0: return "M4" elif mt < 8.0: return "M6" else: return "M8" </code> 규모 구간별 색상을 지정합니다. <code py> COLOR_M2 = "#1E88E5" COLOR_M4 = "#FDD835" COLOR_M6 = "#FB8C00" COLOR_M8 = "#E53935" def magnitude_class_to_color(cls): if cls == "M2": return COLOR_M2 elif cls == "M4": return COLOR_M4 elif cls == "M6": return COLOR_M6 elif cls == "M8": return COLOR_M8 else: return "gray" </code> 전지구 지도 배경을 생성합니다. <code py> def setup_map(): fig = plt.figure(figsize=(16, 7)) ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_global() ax.coastlines(linewidth=0.8) ax.add_feature(cfeature.BORDERS, linewidth=0.4) ax.add_feature(cfeature.LAND, alpha=0.3) ax.add_feature(cfeature.OCEAN, alpha=0.2) ax.gridlines(draw_labels=False, linewidth=0.4, linestyle="--", alpha=0.5) return fig, ax </code> 전체 지진 진앙 분포도를 저장합니다. <code py> def plot_all_map(df): if df.empty: print("[안내] 전체 지도에 그릴 데이터가 없습니다.") return fig, ax = setup_map() tmp = df.copy() tmp["MAG_CLASS"] = tmp["MT"].apply(classify_magnitude) tmp["COLOR"] = tmp["MAG_CLASS"].apply(magnitude_class_to_color) ax.scatter( tmp["LON"], tmp["LAT"], s=32, c=tmp["COLOR"], alpha=0.85, edgecolors="black", linewidths=0.25, transform=ccrs.PlateCarree() ) ax.set_title("Epicenter Distribution for the Last 1 Year (All)", fontsize=14) plt.savefig(OUTPUT_PNG_ALL, dpi=150, bbox_inches="tight") plt.close() </code> 규모 구간별 지도도 각각 저장합니다. <code py> def plot_single_class_map(df, mag_class, output_png): if df.empty: return tmp = df.copy() tmp["MAG_CLASS"] = tmp["MT"].apply(classify_magnitude) tmp = tmp[tmp["MAG_CLASS"] == mag_class].copy() if tmp.empty: return color = magnitude_class_to_color(mag_class) fig, ax = setup_map() ax.scatter( tmp["LON"], tmp["LAT"], s=32, color=color, alpha=0.85, edgecolors="black", linewidths=0.25, transform=ccrs.PlateCarree() ) ax.set_title(f"Epicenter Distribution for the Last 1 Year ({mag_class})", fontsize=14) plt.savefig(output_png, dpi=150, bbox_inches="tight") plt.close() </code> 전체 실행 코드는 다음과 같습니다. <code py> tm1, tm2 = make_time_range() text = fetch_earthquake_text(tm1, tm2) df = parse_text_to_dataframe(text) df = clean_dataframe(df) df.to_csv(OUTPUT_CSV, index=False, encoding="utf-8-sig") plot_all_map(df) plot_single_class_map(df, "M2", OUTPUT_PNG_M2) plot_single_class_map(df, "M4", OUTPUT_PNG_M4) plot_single_class_map(df, "M6", OUTPUT_PNG_M6) plot_single_class_map(df, "M8", OUTPUT_PNG_M8) </code> 실행하면 다음 파일이 생성됩니다. {{:지진_화산:earthquake_epicenter_map_all.png?nolink500}} {{:지진_화산:earthquake_epicenter_map_m2.png?nolink500}} {{:지진_화산:earthquake_epicenter_map_m4.png?nolink500}} {{:지진_화산:earthquake_epicenter_map_m6.png?nolink500}} {{:지진_화산:earthquake_epicenter_map_m8.png?nolink500}}
저장
미리 보기
취소
편집 요약
문서 도구
문서 보기
이전 판
역링크
맨 위로