1. 개요
서울시 대기현황 ETL
현재 프로젝트에서는 서울시 열린데이터 광장 API를 활용하여 1시간 간격으로 실시간 서울시의 대기현황 데이터를 수집하고, 이를 PostgreSQL에 저장하는 데이터 파이프라인을 구축하여 운영중에 있습니다. 데이터는 효과적으로 관리하기 위해 날짜별로 파티셔닝하여 저장하며, 파티셔닝된 테이블 정보는 다음과 같습니다.
# RealtimeCityAir_2024-09-26 테이블 예시 |MSRDT |MSRRGN_NM|MSRSTE_NM|PM10|PM25|O3 |NO2 |CO |SO2 |IDEX_NM|IDEX_MVL|ARPLT_MAIN| |---------------|---------|---------|----|----|-----|-----|---|-----|-------|--------|----------| |202,409,260,000|도심권 |중구 |15 |9 |0.032|0.011|0.4|0.002|보통 |52 |O3 | |202,409,260,000|도심권 |종로구 |20 |14 |0.031|0.022|0.4|0.003|좋음 |50 |O3 | |202,409,260,000|도심권 |용산구 |24 |13 |0.009|0.046|0.5|0.002|보통 |76 |NO2 | |202,409,260,000|서북권 |은평구 |15 |8 |0.023|0.01 |0.3|0.003|좋음 |37 |O3 | |202,409,260,000|서북권 |서대문구 |18 |10 |0.036|0.012|0.4|0.002|보통 |55 |O3 |
- MSRDT: 측정일시
- MSRRGN_NM: 권역명
- MSRSTE_NM: 측정소명
- PM10: 미세먼지(㎍/㎥)
- PM25: 초미세먼지(㎍/㎥)
- O3: 오존(ppm)
- NO2: 이산화질소농도(ppm)
- CO: 일산화탄소농도(ppm)
- SO2: 이황산가스농도(ppm)
- IDEX_NM: 통합대기환경등급
- IDEX_MVL: 통합대기환경지수
- ARPLT_MAIN: 지수결정물질
목표
데이터 파이프라인에서 적재된 데이터를 기반으로 Streamlit을 활용하여 실시간 대시보드를 구현합니다.
해당 대시보드를 통해 서울시의 대기현황을 대기 종류, 지역구, 시간 별로 시각화하고, 대기현황 데이터를 직관적으로 확인할 수 있도록 하는 것을 목표로 합니다.
2. Streamlit 파일 구조
Streamlit의 주요 파일 구조는 다음과 같습니다.
SeoulRealtimeCityAir └───apps ├───plots.py ├───requirements.txt ├───seoul_geo_gu.json └───streamlit_app.py
- plots.py: 대시보드에서 사용할 시각화 함수들이 정의된 파일로, 대기현황을 도넛 차트로 시각화하는 함수와 지도에서 지역구별 대기현황을 시각화하는 함수가 포함되어 있습니다.
- requirements.txt: 필요한 패키지를 정의한 파일입니다. Streamlit 컨테이너를 생성할때 해당 파일을 참조하여 필요한 패키지를 설치합니다.
- seoul_geo_gu.json: 서울시 각 구의 경계를 표시하기 위한 GeoJSON 파일입니다. Folium 지도에서 지역구 별로 대기현황 수치를 시각화할 때 사용됩니다.
- streamlit_app.py: 대시보드의 메인 파일로, 여기서 Streamlit으로 대시보드를 구성하고 데이터베이스에서 데이터를 불러와 시각화합니다.
3. 대시보드 구성
대시보드는 Sidebar, Column1, Column2으로 구성되며, 포함된 항목은 다음과 같습니다.

Sidebar
sidebar에서는 사용자가 분석하고자 하는 대기현황 데이터를 필터링 할 수 있는 네 가지 항목을 제공합니다.

- 대기 선택: 미세먼지(PM-10), 초미세먼지(PM-2.5), 오존(O3), 통합대기환경지수 중에서 원하는 대기의 종류를 선택할 수 있습니다. 선택된 값에 따라 coulmn1의 대기현황 지도 시각화가 변경됩니다.
- 지역구 선택: 서울시의 25개 구 중에서 특정 지역구를 선택할 수 있습니다. 선택된 값에 따라 column2의 지역구 대기질 정보와 column2의 시간대 별 미세먼지 및 초미세먼지가 변경됩니다.
- 날짜 및 시간 선택: 특정 날짜 및 시간을 선택할 수 있습니다. 이를 통해 특정 시간의 대기현황를 확인할 수 있습니다.
Column1
column1에서는 서울시 전체적인 대기현황을 파악할 수 있는 항목을 포함합니다.

- 서울시 평균: 선택된 날짜와 시간 기준으로 서울시 전역의 평균 대기현황을 시각화합니다. 서울시의 전체적인 대기질 상태를 좋음, 보통, 나쁨, 매우나쁨으로 구분하며 파악할 수 있으며, 대기질 상태에 따라 색상값이 변경됩니다.

- 대기현황 지도 시각화: 선택된 날짜와 시간을 기준으로, 지역구 별 선택된 대기 현황을 지도에서 시각화합니다. 각 구별 대기현황을 색상으로 구분하여 표시함으로써 사용자가 지역별 대기질을 쉽게 비교할 수 있습니다.
Column2
column2에서는 특정 지역구의 상세한 대기현황을 파악할 수 있는 항목을 포함합니다.

- 지역구 대기질 정보: 선택된 날짜와 시간를 기준으로 선택한 지역구의 대기질 수치 및 대기질 지수를 제공합니다. 사용자는 이 정보를 통해 특정 지역의 상세한 대기현황을 확인할 수 있습니다.

- 시간대 별 미세먼지 및 초미세먼지 : 선택된 날짜를 기준으로 선택한 지역구의 시간대 별 미세먼지 및 초미세먼지 농도를 시각화합니다. 이 그래프는 특정 시간대에 미세먼지 및 초미세먼지 농도가 어떻게 변동하는지를 보여주며, 사용자가 대기질 변화를 쉽게 파악할 수 있도록 합니다.
4. Setup
Streamlit 컨테이너 추가
docker-compose.yaml 파일의 services 항목에 streamlit_app 컨테이너를 추가합니다.
services: streamlit_app: image: python:3.12-slim container_name: streamlit_app healthcheck: test: ["CMD", "curl", "--fail", "http://localhost:8501/health"] interval: 30s timeout: 10s retries: 3 restart: always volumes: - ${AIRFLOW_PROJ_DIR:-.}/app:/app working_dir: /app env_file: - .env command: > bash -c "pip install --upgrade pip && pip install -r requirements.txt && streamlit run streamlit_app.py" ports: - 8501:8501 networks: network_custom: ipv4_address: 172.28.0.11
streamlit에서 사용할 DB connection 정보를 .env 파일에 지정합니다.
vi .env HOST=172.28.0.3 POSTGRES_CUSTOM_PORT=5432 POSTGRES_CUSTOM_DBNAME=[DB명 설정] POSTGRES_CUSTOM_USER=[DB 유저명 설정] POSTGRES_CUSTOM_PASSWORD=[DB 패스워드 설정]
Terraform 방화벽 정책 추가
terraform/main.tf 파일에 streamlit이 사용하는 포트인 8501에 대한 방화벽 정책을 생성하고, 현재 운영중인 GCE에 해당 방화벽 tag를 추가합니다.
resource "google_compute_firewall" "allow-streamlit" { name = "allow-streamlit" project = var.project network = "default" allow { protocol = "tcp" ports = ["8501"] } source_ranges = ["0.0.0.0/0"] target_tags = ["allow-streamlit"] } ... resource "google_compute_instance" "default" { name = "seoulrealtimecityair-gce" machine_type = "n2-standard-4" zone = var.zone boot_disk { initialize_params { image = "ubuntu-os-cloud/ubuntu-2204-lts" } } network_interface { network = "default" access_config { nat_ip = google_compute_address.static_ip.address } } metadata_startup_script = file("startup_script.sh") tags = ["allow-ssh", "allow-airflow-webserver", "allow-streamlit", "allow-postgres"] }
변경된 사항을 GCE 인스턴스에 적용합니다.
terraform apply
5. 컨테이너 실행 및 결과 확인
streamlit_app 컨테이너를 백그라운드에서 실행합니다.
sudo docker compose up streamlit_app -d
컨테이너가 구동된 후 [고정ip주소]:8501에 접속하면 다음과 같이 대시보드에 접속할 수 있습니다.

GitHub - dojun43/SeoulRealtimeCityAir: 서울시 대기현황 데이터 파이프라인 구축 프로젝트
서울시 대기현황 데이터 파이프라인 구축 프로젝트. Contribute to dojun43/SeoulRealtimeCityAir development by creating an account on GitHub.
github.com
'프로젝트 > 서울시 대기현황 데이터 적재 프로젝트' 카테고리의 다른 글
[서울시 대기현황 데이터 적재 프로젝트] Terraform으로 배포 환경 구성하기 (3) (1) | 2024.09.18 |
---|---|
[서울시 대기현황 데이터 적재 프로젝트] Dag 생성하고 실행하기 (2) (0) | 2024.01.16 |
[서울시 대기현황 데이터 적재 프로젝트] Airflow 환경 구성하기 (1) (0) | 2024.01.16 |