λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

개발회고둝

πŸ‘€ μ΄ν™”μ—¬μžλŒ€ν•™κ΅ 4-1 도전학기 μ™Έμ£Ό 개발 ν”„λ‘œμ νŠΈ

728x90

동기

λ‚΄κ°€ μž¬μž‘λ…„μ— ν™œλ™ν–ˆλ˜ EFUB μ˜€ν”ˆ μΉ΄μΉ΄μ˜€ν†‘ λ°©μ—μ„œ μš°μ—°νžˆ λ‹€μŒκ³Ό 같은 곡고λ₯Ό 보게 λ˜μ—ˆλ‹€.

 

 

λ‚˜λŠ” 생계λ₯Ό μœ μ§€ν•΄μ•Όν•˜λŠ” λŒ€ν•™μƒμ΄λ―€λ‘œ.. 돈이 κΈ‰ν•œ 것도 μžˆμ—ˆμ§€λ§Œ λ‚˜μ˜ 전곡과 κ΄€λ ¨ν•œ 지식(λŠ₯λ ₯)을 λ°œνœ˜ν•˜λ©΄μ„œ λˆμ„ 벌 수 μžˆλ‹€λ©΄ 이보닀 더 쒋은 κΈ°νšŒλŠ” 없을 것이라고 μƒκ°ν–ˆλ‹€! 사싀 μ™Έμ£Ό κ°œλ°œμ€ 처음이고 아직 μš”κ΅¬μ‚¬ν•­λ„ λΆˆλΆ„λͺ…ν•˜κ³  정해진 짧은 κΈ°ν•œ 내에 κ²°κ³Όλ₯Ό λ‚΄μ•Όν–ˆκΈ°μ— '제 μ‹œκ°„ μ•ˆμ— μ™„μ„±ν•˜μ§€ λͺ»ν•˜λ©΄ μ–΄λ–‘ν•˜μ§€', '잘 ν•΄λ‚Ό 수 μžˆμ„κΉŒ'에 λŒ€ν•œ 걱정도 μ•½κ°„ μžˆμ—ˆμ§€λ§Œ, ν”„λ‘ νŠΈμ—”λ“œ μ›Ήκ°œλ°œμ€ λ‚΄κ°€ μƒλ‹Ήνžˆ μ΅μˆ™ν•œ 뢄야이고 λ‚˜λŠ” λ‚˜λ₯Ό 'μ†Œν†΅μ„ μž˜ν•˜λŠ” 개발자' , '같이 μž‘μ—…ν•˜κ³  싢은 개발자' μ •λ„λ‘œ γ…‹γ…‹γ…‹γ…‹γ…‹ μΈμ‹ν•˜κ³  μžˆμ—ˆκΈ° λ•Œλ¬Έμ— 큰 걱정이 λ˜μ§€λŠ” μ•Šμ•˜λ‹€! 😊

 

μ£Όμ œλŠ” 'λ†μ–΄μ΄Œ 정신건강 μ˜λ£ŒλΆˆκ· ν˜•' 에 κ΄€λ ¨λœ 것이닀. 항상 컴퓨터 곡학 μ „κ³΅μƒλ“€κ³Όλ§Œ μ†Œν†΅μ„ 해왔기에 μ•„μ˜ˆ λ‹€λ₯Έ 전곡을 가진 μ‚¬λžŒλ“€κ³Ό ν•¨κ»˜ ν”„λ‘œμ νŠΈλ₯Ό 진행해보고 μ‹Άλ‹€λŠ” μš•κ΅¬λ„ μžˆμ—ˆλ‹€. κΈ‰μ—¬λŠ” 60λ§Œμ› 정도이고, 쑰건 및 μš”κ΅¬μ‚¬ν•­ λ“±μ˜ λ‚œμ΄λ„κ°€ κ·Έλ ‡κ²Œ 높아보이지 μ•Šμ•„μ„œ ν”μΎŒνžˆ κ°œλ°œμ„ Accept ν–ˆλ‹€!

 

레퍼런슀

레퍼런슀둜 보내주신 μ›Ή μ‚¬μ΄νŠΈλŠ” λ‹€μŒκ³Ό κ°™μ•˜λ‹€. μœ μ €μ™€ μƒν˜Έμž‘μš© κ°€λŠ₯ν•œ μΈν„°λž™ν‹°λΈŒν•œ μš”μ†Œλ“€μ΄ λˆˆμ— λ„μ—ˆλ‹€. 

 

https://news.kbs.co.kr/special/somyeol/index.html#/chp3 

 

μ†Œλ©Έμ˜ λ•…, 지방은 μ–΄λ–»κ²Œ μ‚¬λΌμ§€λ‚˜

μ†Œλ©Έμ˜ λ•…, 지방은 μ–΄λ–»κ²Œ μ‚¬λΌμ§€λ‚˜

news.kbs.co.kr

 

QGIS지리 데이터λ₯Ό 기반 μΈν„°λž™ν‹°λΈŒ 지도 ꡬ좕

특히 κ·Έμ€‘μ—μ„œ QGIS의 지리 데이터λ₯Ό 기반으둜 μΈν„°λž™ν‹°λΈŒν•œ 지도λ₯Ό κ΅¬μΆ•ν•˜λŠ” 것을 메인 κΈ°λŠ₯으둜 μš”κ΅¬ λ°›μ•˜λ‹€.

 

총 3개의 지도λ₯Ό λ§Œλ“€μ–΄μ•Ό ν–ˆλŠ”λ° 

 

1. μ£Όμ œκ°€ 무엇이고 μ–΄λ–€ 데이터λ₯Ό μ œκ³΅λ°›λŠ”μ§€

2. 이λ₯Ό μ–΄λ–€μ‹μœΌλ‘œ λ³΄μ—¬μ£Όμ–΄μ•Όν•˜λŠ”μ§€

 

에 μ΄ˆμ μ„ λ§žμΆ”μ–΄μ„œ λ‹€μŒκ³Ό 같은 κΈ°νšμ„œλ₯Ό 전달 λ°›μ•˜λ‹€.

 

 

 

https://www.qgistutorials.com/ko/docs/leaflet_maps_with_qgis2leaf.html

 

qgis2leaf둜 μ›Ή 지도 λ§Œλ“€κΈ° — QGIS Tutorials and Tips

qgis2leaf둜 μ›Ή 지도 λ§Œλ“€κΈ° κ²½κ³  qgis2leaf plugin is no longer in active development. The functionality of this plugin is folded into a new plugin called qgis2web. See Web Mapping with QGIS2Web tutorial for an updated version of this tutorial. 리

www.qgistutorials.com

 

QGIS 에 λ‚΄μž₯된 지도λ₯Ό Web μƒμœΌλ‘œ import ν•  ν•„μš”κ°€ μžˆμ—ˆλŠ”λ°,

 

첫번째 λ– μ˜¬λ¦° λ°”λ‘œλŠ” ν•΄λ‹Ή SW 내에 qgis2leaf λ˜λŠ” qgis2webμ΄λΌλŠ” ν”ŒλŸ¬κ·ΈμΈμ΄ μžˆλ‹€κ³  λ“€μ–΄μ„œ μœ„ νŠœν† λ¦¬μ–Όμ„ λ”°λ₯΄λ©΄ μ•„λž˜μ²˜λŸΌ Leaflet Map HTML 둜 λ³€ν™˜ν•  수 μžˆμ„ 것이라고 μƒκ°ν–ˆλ‹€.

 

ν•˜μ§€λ§Œ QGIS κ°€ μ„€μΉ˜λ˜μ–΄ μžˆλŠ” 기획자 λΆ„κ»˜μ„œ μ‹œν–‰μ°©μ˜€λ₯Ό 많이 κ²ͺμœΌμ‹œκ³  무엇이 λ¬Έμ œμ˜€λŠ”μ§€ λ³€ν™˜μ΄ 잘 μ•ˆλ˜μ‹œλŠ” 어렀움을 λŠλΌμ…”μ„œ λ‹€λ₯Έ 방법을 λ– μ˜¬λ €λ³΄κΈ°λ‘œ ν–ˆλ‹€. 

 

λ‘λ²ˆμ§Έλ‘œλŠ” QGIS μžμ²΄μ—μ„œ μ œκ³΅ν•˜λŠ” .jeojson 데이터와 leaflet API λ₯Ό κ²°ν•©ν•˜μ—¬ 자체적으둜 지도λ₯Ό κ°œλ°œν•˜λŠ” 것이닀.

leaflet μžμ²΄μ—μ„œ GeoJSON 데이터λ₯Ό ν™œμš©ν•΄μ„œ μ§€λ„λ‘œ λ³΄μ—¬μ£ΌλŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό μ œκ³΅ν•˜κ³  μžˆμ–΄μ„œ
React μ—μ„œ ν•΄λ‹Ή 라이브러리 μ‚¬μš©ν•΄μ„œ 맡을 μ»€μŠ€ν„°λ§ˆμ΄μ§•ν•  수 μžˆμ„ 것이라고 μƒκ°ν–ˆλ‹€.

 

이λ₯Ό μœ„ν•΄μ„œ 기획자 λΆ„κ»˜ QGIS μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ ν™œμš©ν•˜μ—¬ 자체적으둜 가곡해주신 .geojson 데이터λ₯Ό λ°›μ•˜λ‹€.

 

features λΌλŠ” 객체 배열에 λ‹΄κΈ΄ 객체 ν•˜λ‚˜ν•˜λ‚˜κ°€ 지역 λ‹¨μœ„ ν•˜λ‚˜ν•˜λ‚˜λ₯Ό μ˜λ―Έν–ˆλ‹€.


1. κ° 데이터 포인트의 경계, 자료 정보λ₯Ό λ‹΄κ³  μžˆλŠ” .geojson

{
"type": "FeatureCollection",
"name": "sgg_mhc_4326_fin",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "sgg_cd": "11010", "sgg_nm": "μ’…λ‘œκ΅¬", "sd_nm": "μ„œμšΈνŠΉλ³„μ‹œ", "pro_num": 12, "gen_num": 5, "etc_num": 0, "pop_rate": 8.6, "pop_rate2": 12.2, "pro_rate": 70.59, "sum": 17 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 126.974965506626646, 37.629025846322392 ], [ 126.979932541642896, 37.628551385741844 ], [ 126.986578589226838, 37.613972040206576 ], [ 126.98666961211083, 37.60402408418873 ], [ 126.976720448663031, 37.597900773419852 ], [ 126.989222005235973, 37.591257335444396 ], [ 127.000983830349256, 37.592321896606414 ], [ 127.008637970768916, 37.580459930712074 ], [ 127.014833342262051, 37.58233145639781 ], [ 127.018090672138015, 37.577566726827079 ], [ 127.023138495286972, 37.578020879003603 ], [ 127.02335824789148, 37.571907275493935 ], [ 126.990150966911386, 37.568136140900691 ], [ 126.97320520035349, 37.569318939391493 ], [ 126.966697705086418, 37.565819760343544 ], [ 126.953558194879776, 37.578748855890005 ], [ 126.958173167115675, 37.580984573579705 ], [ 126.95903333886244, 37.595059021840669 ], [ 126.95771415697908, 37.598367077095006 ], [ 126.953061091977574, 37.598758628935428 ], [ 126.94900026132089, 37.624335133915118 ], [ 126.95864765352961, 37.629500235655868 ], [ 126.960723745696427, 37.629776396868195 ], [ 126.975084766
...
}

 

ν•˜λ‚˜μ˜ 지역은 λ©€ν‹° 폴리곀 νƒ€μž… λ°μ΄ν„°λ‘œ ν‘œν˜„μ΄ λ˜λŠ”λ°, μ—¬λŸ¬κ°œμ˜ 폴리곀(λ„ν˜•)이 λͺ¨μΈ 곡간 데이터 νƒ€μž…μ΄λΌκ³  이해해주면 쉽닀!

 

 

ν•˜λ‚˜μ˜ 지역이 μ™œ μ—¬λŸ¬κ°œμ˜ 폴리곀을 ν¬ν•¨ν•˜κ³  μžˆλŠ”μ§€ λ¬»λŠ”λ‹€λ©΄, λ‹€μŒκ³Ό 같이 ν•˜λ‚˜μ˜ κ΅¬λΆ„λ˜λŠ” 지역에 λŒ€ν•΄μ„œ μ—¬λŸ¬κ°œμ˜ 섬을 포함할 수 있기 λ•Œλ¬Έμ΄λ‹€. 

 

 

2. 각 데이터 포인트의 쀑심점을 담은 .geojson

{
"type": "FeatureCollection",
"name": "sgg_mhc_4326_point",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "sgg_cd": "11010", "sgg_nm": "μ’…λ‘œκ΅¬", "sd_nm": "μ„œμšΈνŠΉλ³„μ‹œ", "pro_num": 12, "gen_num": 5, "etc_num": 0, "pop_rate": 8.6, "pop_rate2": 12.2, "pro_rate": 70.59, "sum": 17 }, "geometry": { "type": "Point", "coordinates": [ 126.977172562038376, 37.59499549178458 ] } },
...
}

 

레퍼런슀둜 μ£Όμ‹  μ›Ήμ—λŠ” 지도 μ˜μ—­μ„ 마우슀둜 ν΄λ¦­ν•˜λ©΄, 초점이 ν•΄λ‹Ή μ§€λ„μ˜ μ€‘μ‹¬μœΌλ‘œ λ§žμΆ°μ§€λŠ” κΈ°λŠ₯이 μžˆλ‹€.

이λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄μ„œλŠ” 쀑심점 μ’Œν‘œκ°€ ν•„μš”ν–ˆλ‹€.

 

문제 상황

κ·ΈλŸ¬λ‚˜ 두가지 문제 상황이 λ°œμƒν–ˆλ‹€.

 

μ²«λ²ˆμ§ΈλŠ” μ²˜μŒμ— λ³΄λ‚΄μ£Όμ…¨λ˜ .geojson 의 지역 λ‹€κ°ν˜•(폴리곀)이 λ„ˆλ¬΄ λ³΅μž‘ν•œ μƒνƒœμ—¬μ„œ λ Œλ”λ§ ν•˜λ €κ³  ν•˜λ©΄, μžλ°”μŠ€ν¬λ¦½νŠΈ λ Œλ”λ§ 엔진이 λͺ»λ²„ν‹°κ³  heap limit Allocation failed λ₯Ό λ‚΄λŠ” λ¬Έμ œκ°€ μžˆμ—ˆλ‹€.

 

보내주신 데이터에 ν•œ 지역당 꼭짓점 μ’Œν‘œκ°€ λͺ‡κ°œμΈμ§€μ‘°μ°¨ μ…€ 수 없을 μ •λ„λ‘œ λ§Žμ•„μ„œ μ΄ˆκΈ°μ— 지도 λ‘œλ“œν•˜λŠ”λ°μ—λ„ μ‹œκ°„μ΄ λ„ˆλ¬΄ 였래걸리고 λΆ€ν•˜κ°€ μƒκΈ°λŠ” 것 κ°™λ‹€κ³  νŒλ‹¨ν•˜μ˜€κ³ , geojson 데이터가 μ§€κΈˆλ³΄λ‹€ 더 κ°€λ²Όμ›Œ 진닀면 λ Œλ”λ§μ΄ κ°€λŠ₯ν•  것 κ°™λ‹€κ³  생각이 λ“€μ–΄ κΈ°νšμžλΆ„κ»˜ QGIS λ₯Ό ν™œμš©ν•˜μ—¬ 데이터λ₯Ό 쑰금 더 κ°„μ†Œν™”ν•΄μ£Όμ‹€ 수 μžˆμ„μ§€ λΆ€νƒλ“œλ Έλ‹€. 

 

μ•Œκ³ λ³΄λ‹ˆ 상상을 μ΄ˆμ›”ν•˜κ²Œ μžμž˜μžμž˜ν–ˆλ˜ 지역듀.. γ…‹γ…‹γ…‹γ…‹γ…‹γ…‹γ…‹γ…‹

 

 

κΈ°νšμžλΆ„κ»˜μ„œ μ—΄μ‹¬νžˆ 라인 λ‹¨μˆœν™”λ₯Ό ν•΄μ£Όμ‹  덕에 데이터 크기가 많이 μ€„μ–΄λ“€μ—ˆκ³  κ·Έ κ²°κ³Ό λ Œλ”λ§μ— μ„±κ³΅ν•˜λŠ” 감격슀러운 κ²°κ³Όλ₯Ό λ‚Ό 수 μžˆμ—ˆλ‹€! γ…Žγ…Ž 

 

 

 

κ·ΈλŸ¬λ‚˜ 또 λ‹€λ₯Έ λ¬Έμ œκ°€ μžˆμ—ˆλ‹€.

 

λ‘λ²ˆμ§ΈλŠ” 이 λ‘κ°œμ˜ 데이터가 λ”°λ‘œ λΆ„λ¦¬λ˜μ–΄ 제곡된 상황이라  λ‘κ°œμ˜ 데이터λ₯Ό λͺ¨λ‘ λΆˆλŸ¬μ˜€κΈ°μ—λŠ” λΆˆν•„μš”ν•˜κ²Œ 데이터가 κ²Ή

μΉ˜λŠ” 뢀뢄이 많고 κ°œλ°œλ„ λ‘κ°œμ˜ 데이터λ₯Ό ν™œμš©ν•΄μ•Όν•΄μ„œ 쑰금 더 λ³΅μž‘ν•  κ²ƒμ΄μ—ˆλ‹€.

 

κ·Έλž˜μ„œ ν•˜λ‚˜μ˜ 지역 객체 μ•ˆμ— λ“€μ–΄κ°ˆ 수 μžˆλ„λ‘ 데이터λ₯Ό λ³‘ν•©ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‹€. 

 

data_combiner.py

import json

def merge_geojson(point_filepath, multipolygon_filepath, output_filepath):
    # 첫 번째 GeoJSON 파일 읽기 (Point 데이터)
    with open(point_filepath, 'r', encoding='utf-8') as file:
        point_data = json.load(file)

    # 두 번째 GeoJSON 파일 읽기 (MultiPolygon 데이터)
    with open(multipolygon_filepath, 'r', encoding='utf-8') as file:
        multipolygon_data = json.load(file)

    # MultiPolygon λ°μ΄ν„°μ˜ features κ°€μ Έμ˜€κΈ°
    multipolygon_features = multipolygon_data['features']

    # Point 데이터λ₯Ό sgg_cdλ₯Ό key둜 ν•˜λŠ” λ”•μ…”λ„ˆλ¦¬λ‘œ λ³€ν™˜
    point_features = {feature['properties']['sgg_cd']: feature for feature in point_data['features']}

    # MultiPolygon λ°μ΄ν„°μ˜ 각 feature에 λŒ€ν•΄ lat, lng μΆ”κ°€
    for feature in multipolygon_features:
        sgg_cd = feature['properties']['sgg_cd']
        if sgg_cd in point_features:  # λ™μΌν•œ sgg_cdλ₯Ό 가진 Point 데이터가 있으면
            point_feature = point_features[sgg_cd]
            # MultiPolygon feature의 properties에 lat, lng μΆ”κ°€
            feature['properties']['lat'] = point_feature['geometry']['coordinates'][1]
            feature['properties']['lng'] = point_feature['geometry']['coordinates'][0]

    # λ³‘ν•©λœ 데이터 생성
    merged_data = {
        "type": "FeatureCollection",
        "name": multipolygon_data['name'],
        "crs": multipolygon_data['crs'],
        "features": multipolygon_features
    }

    # JSON 파일둜 μ €μž₯
    with open(output_filepath, 'w', encoding='utf-8') as file:
        json.dump(merged_data, file, ensure_ascii=False, indent=4)

    print("Combined data saved to", output_filepath)

# 파일 경둜 μ„€μ •
#point_filepath = 'sgg_menhos_point_4326.geojson'
#multipolygon_filepath = 'sgg_menhos_4326.geojson'
#output_filepath = 'sgg_menhos_combined_4326.geojson'


point_filepath = './mhc/sgg_mhc_4326_point.geojson'
multipolygon_filepath = './mhc/sgg_mhc_4326.geojson'
output_filepath = './mhc/sgg_mhc_combined_4326.geojson'


# 병합 ν•¨μˆ˜ 호좜
merge_geojson(point_filepath, multipolygon_filepath, output_filepath)

 

 

κ·Έ κ²°κ³Ό properties μ•ˆμ— 쀑심점(lat,lng)κ³Ό 지역 정보λ₯Ό ν•œλ²ˆμ— 담은 λ‹€μŒκ³Ό 같은 데이터λ₯Ό λ§Œλ“€μ–΄λ‚Ό 수 μžˆμ—ˆλ‹€.

{
    "type": "FeatureCollection",
    "name": "sgg_mhc_4326_fin",
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
        }
    },
    "features": [
        {
            "type": "Feature",
            "properties": {
                "sgg_cd": "11010",
                "sgg_nm": "μ’…λ‘œκ΅¬",
                "sd_nm": "μ„œμšΈνŠΉλ³„μ‹œ",
                "pro_num": 12,
                "gen_num": 5,
                "etc_num": 0,
                "pop_rate": 8.6,
                "pop_rate2": 12.2,
                "pro_rate": 70.59,
                "sum": 17,
                "lat": 37.59499549178458,
                "lng": 126.97717256203838
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [
                    [
                        [
                            [
                                126.97496550662665,
                                37.62902584632239
                            ],
                            [
                                126.9799325416429,
                                37.628551385741844
                            ],
                            [
                                126.98657858922684,
                                37.613972040206576
                            ],
                            [
                                126.98666961211083,
                                37.60402408418873
                            ],
                            [
                                126.97672044866303,
                                37.59790077341985
                            ],
                            [
                                126.98922200523597,
                                37.591257335444396
                            ],
                            [
                                127.00098383034926,
                                37.592321896606414
                            ],
                            [
                                127.00863797076892,
                                37.580459930712074
                            ],
                            [
                                127.01483334226205,
                                37.58233145639781
                            ],
                            [
                                127.01809067213802,
                                37.57756672682708
                            ],
                            [
                                127.02313849528697,
                                37.5780208790036
                            ],
                            [
                                127.02335824789148,
                                37.571907275493935
                            ],
                            [
                                126.99015096691139,
                                37.56813614090069
                            ],
                            [
                                126.97320520035349,
                                37.56931893939149
                            ],
                            [
                                126.96669770508642,
                                37.565819760343544
                            ],
                            [
                                126.95355819487978,
                                37.578748855890005
                            ],
                            [
                                126.95817316711567,
                                37.580984573579705
                            ],
                            [
                                126.95903333886244,
                                37.59505902184067
                            ],
                            [
                                126.95771415697908,
                                37.598367077095006
                            ],
                            [
                                126.95306109197757,
                                37.59875862893543
                            ],
                            [
                                126.94900026132089,
                                37.62433513391512
                            ],
                            [
                                126.95864765352961,
                                37.62950023565587
                            ],
                            [
                                126.96072374569643,
                                37.629776396868195
                            ],
                            [
                                126.97508476644904,
                                37.63118349820025
                            ],
                            [
                                126.97496550662665,
                                37.62902584632239
                            ]
                        ]
                    ]
                ]
            }
        },
        
      ...
      }

 

 

지도 개발

μ΄λŸ¬ν•œ 데이터λ₯Ό λ°”νƒ•μœΌλ‘œ 지도λ₯Ό κ°œλ°œν•˜λŠ” 것은 크게 어렡지 μ•Šμ•˜λ‹€!

λ¦¬ν”Œλ › μΈ‘μ—μ„œ 도움이 λ˜λŠ” μΉœμ ˆν•œ API 듀을 많이 μ œκ³΅ν•΄μ£Όκ³  μžˆμ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

.geojson ν˜•νƒœμ˜ 데이터 자료λ₯Ό λ¦¬ν”Œλ › Map API 에 μ „λ‹¬ν•˜λ©΄ 이λ₯Ό μ•Œμ•„μ„œ ν•΄μ„ν•΄μ„œ 지도상에 지역 경계λ₯Ό κ·Έλ €μ€€λ‹€. 

 

 <GeoJSON
                  style={mapStyle}
                  data={geoJsonData}
                  onEachFeature={onEachDistrict}
                />

 

const SelectBox = () => {
    const [selectedSiDo, setSelectedSiDo] = useState('');
    const [selectedSiGunGu, setSelectedSiGunGu] = useState('');

    const SiDoOptions = [
      ...new Set(geoJsonData.map((district) => district.properties.sd_nm)),
    ].sort();

    // index μΆ”κ°€ν•œ 객체 λ°°μ—΄
    const SiDoOption = SiDoOptions.map((district, index) => ({
      value: index,
      label: district,
    }));

    // μ„ νƒν•œ μ‹œλ„μ™€ μΌμΉ˜ν•˜λŠ” μ‹œκ΅°κ΅¬ λͺ©λ‘ μΆ”μΆœ
    const SiGunGuOptions = geoJsonData.filter(
      (district) => district.properties.sd_nm === selectedSiDo
    );

    // unique ν•œ μ‹œκ΅°κ΅¬ λͺ©λ‘ μΆ”μΆœ
    let SiGunGuOption = [
      ...new Set(SiGunGuOptions.map((district) => district.properties.sgg_nm)),
    ].sort();

    SiGunGuOption = SiGunGuOption.map((district, index) => ({
      value: index,
      label: district,
    }));

    useEffect(() => {
      const searchResults = geoJsonData.filter(
        (district) =>
          district.properties.sd_nm === selectedSiDo &&
          district.properties.sgg_nm === selectedSiGunGu
      );

      if (searchResults.length) {
        // 검색 κ²°κ³Όκ°€ μ‘΄μž¬ν•œλ‹€λ©΄
        setSiDoName(searchResults[0].properties.sd_nm);
        setSiGunGuName(searchResults[0].properties.sgg_nm);

        setPercentage(searchResults[0].properties.pro_rate);
        setProCnt(searchResults[0].properties.pro_num);
        setGenCnt(searchResults[0].properties.gen_num);
        setEtcCnt(searchResults[0].properties.etc_num);

        setSearchPosition({
          lat: searchResults[0].properties.lat,
          lng: searchResults[0].properties.lng,
        });
      }
    }, [selectedSiGunGu]);

 

 // 각 지역 λ˜λŠ” λ ˆμ΄μ–΄μ— λŒ€ν•œ νŠΉμ„± μ„€μ •
  const onEachDistrict = (district, layer) => {
    layer.options.fillColor = getColor(district.properties.pro_rate); // μ •μ‹  건강 μ „λ¬Έ μš”μ› λΉ„μœ¨(0κ³Ό 100 μ‚¬μ΄μ˜ κ°’)에 λ”°λ₯Έ λ ˆμ΄μ–΄ 색 μ„€μ •

    const sido = district.properties.sd_nm;
    const sigungu = district.properties.sgg_nm;
    const percentage = district.properties.pro_rate; // μ •μ‹  건강 μ „λ¬Έ μš”μ› λΉ„μœ¨

    const pro_num = district.properties.sum; // λ ˆμ΄μ–΄μ˜ μ „λ¬Έ μš”μ› 수
    const gen_num = district.properties.gen_num;
    const etc_num = district.properties.etc_num;
    const clickedLat = district.properties.lat; // λ ˆμ΄μ–΄μ˜ lat μ„€μ •
    const clickedLng = district.properties.lng; // λ ˆμ΄μ–΄μ˜ lng μ„€μ •

    layer.on({
      mouseover: highlightFeature,
      mouseout: resetHighlight,
      click: (e) => {
        L.DomEvent.stopPropagation(e); // λ‹€λ₯Έ μ΄λ²€νŠΈμ™€ 좩돌 방지
        setSiGunGuName(sigungu);
        setSiDoName(sido);
        setPercentage(percentage);
        setProCnt(pro_num);
        setGenCnt(gen_num);
        setEtcCnt(etc_num);
        setSearchPosition({ lat: clickedLat, lng: clickedLng }); // κ²€μƒ‰μœ„μΉ˜ μ„€μ •
      },
    });
  }
  // κ²€μƒ‰ν•œ 지역 μœ„μΉ˜λ‘œ 지도 이동, 마컀둜 ν‘œμ‹œ
  const SearchMarker = () => {
    const map = useMap();

    // 화면상에 ν΄λ¦­ν•œ μ’Œν‘œλ‘œ 쀑심점 이동

    console.log(searchPosition.lat, searchPosition.lng);
    map.setView([searchPosition.lat, searchPosition.lng], 10);

    // position이 null값이면 마컀λ₯Ό ν‘œμ‹œν•˜μ§€ μ•Šκ³ , null값이 μ•„λ‹ˆλ©΄ 마컀λ₯Ό 보여쀀닀
    return <Marker position={searchPosition} icon={icon} />;
  };

 

0

 

κ³Όμ •

κΈ°νšλŒ€λ‘œ κ°œλ°œν•œ 이후, κΈ°νšμžλ‹˜κ»˜ μ˜€νƒˆμž, CSS, λ‚΄μš© λ³€κ²½ λ“± μ§€μ†μ μœΌλ‘œ ν”Όλ“œλ°±μ„ λ°›μ•„ μˆ˜μ •μ„ κ±°μΉ˜λŠ” μž‘μ—…μ„ λ°˜λ³΅ν•˜μ˜€λ‹€.

 

총 결과물

λ‹€μŒμ€ μ™Έμ£Ό 개발 총 결과물이닀!

 

https://interactive-web-gules.vercel.app/#/

 

μ‹œκ³¨ λŠ™μ€μ΄ λ§ˆμŒμ€ λˆ„κ°€ ν’€μ–΄μ£Όλ‚˜?

λ°μ΄ν„°λ‘œ λ³΄λŠ” 지역별 정신건강 λΆˆν‰λ“±

interactive-web-gules.vercel.app

 


기타 μš”κ΅¬ 사항

 

- openGraph νƒœκ·Έλ₯Ό μ΄μš©ν•œ 썸넀일 μ„€μ •

- λͺ¨λ°”일 μ μ‘ν˜• 

 

 

ν›„κΈ°

μ–΄μ©Œλ©΄ 지리와 κ°œλ°œμ„ μœ΅ν•©ν•˜λŠ”, ν‰μ†Œμ— μžμ£Όν•˜μ§€ μ•ŠλŠ” μ΅μˆ™ν•˜μ§€ μ•Šμ€ λΆ„μ•Όμ˜ μ›Ή κ°œλ°œμ΄μ—ˆλ‹€κ³  μƒκ°ν•œλ‹€.

κ·ΈλŸ¬λ‚˜ 쀑간쀑간 μƒκΈ°λŠ” 문제 μƒν™©λ“€μ˜ 원인을 잘 μ°Ύμ•„μ„œ ν•΄κ²°ν–ˆκ³ , 과거보닀 많이 μ„±μž₯ν•œ λ‚΄ μžμ‹ μ„ 확인할 수 있던 것 κ°™λ‹€! 

무엇보닀 기획자 λΆ„κ³Όμ˜ μΌ€λ―Έκ°€ 정말 μ’‹μ•˜λ˜ 것 κ°™λ‹€! γ…Žγ…Ž 덕뢄에 μ™Έμ£Ό μž‘μ—…μ΄μ§€λ§Œ λΆ€λ‹΄ λŠλΌμ§€ μ•Šκ³  νŽΈν•˜κ²Œ μž‘μ—…ν•  수 μžˆμ—ˆλ‹€!

 

 

 

κ°œλ°œμ„ 마치고 ν•œλ‹¬ 정도가 μ§€λ‚¬μ„κΉŒ? 기획자 λΆ„κ»˜ 연락이 μ™”λŠ”λ° 정말 κΈ°μ˜κ²Œλ„ μˆ˜μƒμ„ ν•˜μ…¨λ‹€κ³  ν•œλ‹€!  μ˜ˆμƒμΉ˜ λͺ»ν•˜κ²Œ 기쁜일이 생겼고 ꡉμž₯히 λΏŒλ“―ν•œ κ²½ν—˜μ΄μ—ˆλ‹€. λ°₯을 사주신닀고 ν•˜μ…”μ„œ μ΄ν›„에 μ—°λ‚¨λ™μ—μ„œ λ§›μžˆλŠ” 연어집에 κ°€μ„œ λ¨Ήμ—ˆλ‹€. γ…Žγ…Ž 😊

 

카메라가 κ³ μž₯λ‚˜μ„œ 사진은 잘 λͺ»μ°μ€ 것 κ°™μ§€λ§Œ μ•„λ¬΄νŠΌ μ§„μ§œ λ§›μžˆμ—ˆλ‹€.