근대 교통로 DB
DB 개요
- DB 설명
- 1910년대 제작된 1:5만 조선지형도의 도로 정보를 GIS 데이터로 구축 (기존 성신여자대학교 GIS 연구사업에서 구축한 1·2등 도로 데이터를 기초 레이어로 참조)
- 라인 벡터 데이터에 Tobler(1993), Kondo&Seino(2010)에서 발표된 보행 속도 함수를 적용하여 비등방 경로 분석을 실행할 수 있도록 구축한 네트워크 데이터셋
- 2025년 9월 시점 데이터 구축 상황 : 1910년대 조선지형도의 경기, 충청도, 경상도 내 1·2등 도로, 달로, 연로 등급까지 디지타이징 후 네트워크 데이터셋 가공 완료
- DB 구축자
- DB 설계 : 양정현
- DB 구축 : 양정현
- 데이터 검수 : 김종혁, 김현종, 박선영, 최유식
- 자료 공개
- 비영리적 활동(논문, 연구서)에 본 자료 사용시, 인용 문구만 표시하면 사용에 제한 없음.
- 영리적인 목적(프로젝트)으로 사용할 경우에는 관계자(yachagye@naver.com)와 상의 후 처리.
- 본 자료 전체를 다른 곳에서 서비스하는 것은 제한함.
- 본 DB에 오류가 발견된 경우, yachagye@naver.com에 오류 신고.
- 인용 표기 : 1910년대 한반도 도로 네트워크 데이터셋, 202X년 X월 기준, 양정현, 역지사지(https://www.hisgeo.info).
공간 데이터
- 데이터 구성
- 압축 해제 후 파일명: 도로_1914.gdb
- 하위 경로: 도로_1914.gdb / 도로_1914_5179(피처 데이터셋) / 도로_1914_10m_5179_20250831 ; 도로_1914_nd ; 도로_1914_nd_Junctions
- 도로 라인 피처: 도로_1914_10m_5179_20250831
- 네트워크 데이터셋: 도로_1914_nd
- 정션: 도로_1914_nd_Junctions
- 다운로드 링크(구글 드라이브)
필드 설계
| 필드명 | 의미 | 단위 | 타입 |
|---|---|---|---|
| length_3d | 3D 길이(표면거리) | m | DOUBLE |
| length_3dkm | 3D 길이 | km | DOUBLE |
| grade_f | 구배(From→To) | 무차원 | DOUBLE |
| grade_b | 구배(To→From) | 무차원 | DOUBLE |
| sp_tob_f | Tobler(1993) 보행 함수 속도 (From→To) | km/h | DOUBLE |
| sp_tob_b | Tobler(1993) 보행 함수 속도 (To→From) | km/h | DOUBLE |
| sp_ks_f | Kondo-Seino(2010) 보행 함수 속도 (From→To) | km/h | DOUBLE |
| sp_ks_b | Kondo-Seino(2010) 보행 함수 속도 (To→From) | km/h | DOUBLE |
| hr_tob_f | Tobler(1993) 보행 함수 시간 (From→To) | hr | DOUBLE |
| hr_tob_b | Tobler(1993) 보행 함수 시간 (To→From) | hr | DOUBLE |
| hr_ks_f | Kondo-Seino(2010) 보행 함수 시간 (From→To) | hr | DOUBLE |
| hr_ks_b | Kondo-Seino(2010) 보행 함수 시간 (To→From) | hr | DOUBLE |
| kcal_ks_f | ACSM 함수 칼로리 (From→To, Kondo-Seino 함수 시간) | kcal/kg | DOUBLE |
| kcal_ks_b | ACSM 함수 칼로리 (To→From, Kondo-Seino 함수 시간) | kcal/kg | DOUBLE |
| kcal_tob_f | ACSM 함수 칼로리 (From→To, Tobler 함수 시간) | kcal/kg | DOUBLE |
| kcal_tob_b | ACSM 함수 칼로리 (To→From, Tobler 함수 시간) | kcal/kg | DOUBLE |
| ID | 수상 영역 | - | TEXT |
활용 모델 1: 네트워크 데이터셋 기반 최소 비용 경로 분석
개요
라인 네트워크 데이터셋에 비용 속성과 평가기를 설정하여 각 세그먼트의 이동 방향(Along/Against)에 따른 비대칭(asymmetric) 비용을 반영하는 최소 비용 경로 분석 방법론이다.
비용 속성:
- Tobler(1993) 및 Kondo-Seino(2010)의 보행 속도 함수를 적용한 구간별 이동 시간
- 이동 방향에 따른 경사각의 반전(오르막과 내리막)을 구분하여 정방향과 역방향 필드로 구성
분석 프로세스
1단계: 네트워크 데이터 준비
라인 데이터 분할
도로 네트워크 레이어의 각 세그먼트에 길이 및 고도 속성을 할당하기 위해 폴리라인을 분할한다.
점 생성:
도구: Generate Points Along Lines
| 매개변수 | 설정값 |
|---|---|
| 입력 피처 | 네트워크 라인 레이어 |
| 거리 | 10m (분석 목적에 따라 조정) |
라인 분할:
도구: Split Line at Point (Data Management Tools → Features)
| 매개변수 | 설정값 |
|---|---|
| Input Features | 네트워크 라인 레이어 |
| Point Features | 생성된 점 레이어 |
| 검색 반경 | 1mm |
2단계: 좌표계 변환 (투영)
DEM 투영:
도구: Project Raster
| 매개변수 | 설정값 |
|---|---|
| 입력 래스터 | SRTM DEM |
| 출력 좌표계 | EPSG:5179 (Korea 2000 / Central Belt) |
| 리샘플링 기법 | Bilinear (이중선형 보간) |
| 셀 크기 | 원본 유지 (약 30m) |
네트워크 라인 투영:
도구: Project
| 매개변수 | 설정값 |
|---|---|
| 입력 피처 | 네트워크 라인 |
| 출력 좌표계 | EPSG:5179 |
중요: XY, Z 모두 미터 단위로 맞춰야 구배/길이 계산이 정확함.
3단계: 라인에 Z 값 보간 (3D 라인 생성)
도구: Interpolate Shape (3D Analyst)
| 매개변수 | 설정값 |
|---|---|
| Input Features | 네트워크 라인 (EPSG:5179) |
| Input Surface | DEM (EPSG:5179) |
| Sampling Distance | 0 (기본값) |
| Z Factor | 1 (기본값) |
결과: 모든 vertex에 DEM Z 값이 추가된 3D 라인
4단계: 표면거리 필드 생성 (3D 길이)
도구: Calculate Geometry (기하 계산)
필드 1: length_3d
- 데이터 타입: Double
- Geometry Properties: LENGTH (3D) = 길이(3D)
- 단위: Meters
필드 2: length_3dkm
- Expression:
!length_3d! / 1000.0 - 단위: Kilometers
품질 검증: length_3d >= Shape_Length 확인 (표면거리 ≥ 평면거리)
5단계: 구배(Grade) 계산
구배는 수평거리(2D)를 분모로 하여 계산하며, 이동 방향에 따라 부호가 반전된다.
필드 생성:
grade_f: From→To 방향 구배grade_b: To→From 방향 구배- 데이터 타입: Double
간단식 (데이터가 정상일 때)
grade_f = (!shape.lastPoint.Z! - !shape.firstPoint.Z!) / !Shape_Length!
grade_b = -!grade_f!권장식 (Z 값 NaN/None 방지)
Code Block (Python):
import math
def safe_grade(z_from, z_to, len2d):
if z_from is None or z_to is None or len2d is None:
return 0.0
try:
if math.isnan(z_from) or math.isnan(z_to) or len2d <= 0:
return 0.0
except Exception:
return 0.0
return (z_to - z_from) / len2dExpression:
grade_f = safe_grade(!shape.firstPoint.Z!, !shape.lastPoint.Z!, !Shape_Length!)
grade_b = -!grade_f!6단계: 속도 및 시간 계산
보행 속도 함수
Code Block (Python):
import math
def v_kmh_tobler(g):
v = 6.0 * math.exp(-3.5 * abs(g + 0.05))
return max(min(v, 7.5), 1.0)
def v_kmh_kondoseino(g):
if g >= -0.07:
v = 5.1 * math.exp(-2.25 * abs(g + 0.07))
else:
v = 5.1 * math.exp(-1.5 * abs(g + 0.07))
return max(v, 0.5)
def hours(len_m, v_kmh):
return (len_m/1000.0) / v_kmh if v_kmh and v_kmh > 0 else 1e6필드 생성 - 속도 (km/h):
sp_tob_f = v_kmh_tobler(!grade_f!)
sp_tob_b = v_kmh_tobler(!grade_b!)
sp_ks_f = v_kmh_kondoseino(!grade_f!)
sp_ks_b = v_kmh_kondoseino(!grade_b!)필드 생성 - 시간 (hr):
hr_tob_f = hours(!length_3d!, !sp_tob_f!)
hr_tob_b = hours(!length_3d!, !sp_tob_b!)
hr_ks_f = hours(!length_3d!, !sp_ks_f!)
hr_ks_b = hours(!length_3d!, !sp_ks_b!)7단계: 칼로리 소비량 계산
MET(Metabolic Equivalent of Task)를 이용한 칼로리 계산. ACSM 공식에 내리막 보정 계수를 적용한다.
기본 개념:
- VO₂ = 3.5 + 0.1 × S + 1.8 × S × grade (S: 속도 m/min, ACSM 공식)
- MET = VO₂/3.5 = 1 + 0.476 × v + 8.571 × v × grade_eff (v: 속도 km/h)
- 내리막 보정: grade < 0일 때 grade_eff = λ × grade (λ = 0.5 권장)
- 최소 MET = 1.0 보장
- kcal/kg = MET × 시간(hr)
Code Block (Python):
LAMBDA = 0.5
def kcal_per_kg(speed_kmh, hour_h, grade):
if speed_kmh is None or hour_h is None or grade is None:
return None
grade_eff = grade if grade >= 0 else LAMBDA * grade
mets = 1 + 0.476 * speed_kmh + 8.571 * speed_kmh * grade_eff
if mets < 1.0:
mets = 1.0
return mets * hour_h필드 생성 - 칼로리 (kcal/kg):
kcal_ks_f = kcal_per_kg(!sp_ks_f!, !hr_ks_f!, !grade_f!)
kcal_ks_b = kcal_per_kg(!sp_ks_b!, !hr_ks_b!, !grade_b!)
kcal_tob_f = kcal_per_kg(!sp_tob_f!, !hr_tob_f!, !grade_f!)
kcal_tob_b = kcal_per_kg(!sp_tob_b!, !hr_tob_b!, !grade_b!)8단계: 수상 영역 속도 및 칼로리 보정
바다 및 하천 구간은 도보가 아닌 선박 이동으로 가정하여 속도를 고정하고 칼로리를 0으로 설정한다.
| 구간 유형 | 고정 속도 (km/h) | 칼로리 (kcal/kg) |
|---|---|---|
| 바다 | 5.0 | 0 |
| 하천 | 1.2 | 0 |
| 육상 | Tobler/Kondo-Seino 함수 | MET 기반 계산 |
구현 방법:
ID필드에 "바다" 또는 "하천" 값을 가진 구간 식별- 해당 구간의 속도 필드를 고정값으로 설정
- 칼로리 필드를 0으로 설정
9단계: 네트워크 데이터셋 생성
네트워크 데이터셋 생성
- Catalog Pane에서 지오데이터베이스 선택
- 오른쪽 클릭 → New → Network Dataset
- 네트워크 데이터셋 이름 지정 및 폴리라인 레이어 선택
비용 속성(Cost Attribute) 설정
Catalog → 네트워크 데이터셋 → Properties → Attributes 탭
비용 속성 1: hour_tob (Tobler 시간)
| 설정 항목 | 값 |
|---|---|
| 속성 유형 | Cost |
| 단위 | Hours |
| Evaluator - Along | Field: !hr_tob_f!
|
| Evaluator - Against | Field: !hr_tob_b!
|
비용 속성 2: hour_ks (Kondo-Seino 시간)
| 설정 항목 | 값 |
|---|---|
| 속성 유형 | Cost |
| 단위 | Hours |
| Evaluator - Along | Field: !hr_ks_f!
|
| Evaluator - Against | Field: !hr_ks_b!
|
비용 속성 3: length_3d (3D 거리)
| 설정 항목 | 값 |
|---|---|
| 속성 유형 | Cost |
| 단위 | Kilometers |
| Evaluator - Along | Field: !length_3dkm!
|
| Evaluator - Against | Field: !length_3dkm!
|
비용 속성 4: kcal_ks (Kondo-Seino 칼로리)
| 설정 항목 | 값 |
|---|---|
| 속성 유형 | Cost |
| 단위 | Unknown (kcal/kg) |
| Evaluator - Along | Field: !kcal_ks_f!
|
| Evaluator - Against | Field: !kcal_ks_b!
|
비용 속성 5: kcal_tob (Tobler 칼로리)
| 설정 항목 | 값 |
|---|---|
| 속성 유형 | Cost |
| 단위 | Unknown (kcal/kg) |
| Evaluator - Along | Field: !kcal_tob_f!
|
| Evaluator - Against | Field: !kcal_tob_b!
|
네트워크 데이터셋 빌드
- 네트워크 데이터셋을 마우스 오른쪽 버튼으로 클릭
- Build Network 선택하여 빌드 실행
10단계: 경로 분석 실행
- 네트워크 데이터셋 레이어를 마우스 오른쪽 버튼으로 클릭
- Network Analyst 탭에서 '경로(Route)' 선택
- 경로 레이어에서 출발지, 도착지 추가
- 경로 레이어 Properties에서 임피던스(Impedance) 선택
- hour_tob, hour_ks, length_3d, kcal_ks, kcal_tob 중 선택
- '비용 속성 누적'에서 추가 속성 선택 (경로 레이어 리본의 Σ 버튼)
- 네트워크 분석 실행
네트워크 데이터셋 속성: 제한(Restriction)
특정 구간을 회피(Avoid)하거나 선호(Prefer)하도록 설정할 수 있다.
회피(Avoid) 설정
특정 필드 값을 가진 구간에 높은 비용을 부여하여 우회하도록 유도한다.
설정 과정:
- Network Dataset Properties → Attributes 탭
- Add → Restriction 선택
- Restriction 이름 지정 (예:
Avoid_River) - Usage Type: Avoid
- Scale Factor 설정 (예: 2.0~5.0)
- 값이 클수록 강한 회피 효과
- Evaluators 탭에서 Expression 설정
Evaluator 설정 예시 (하천 회피):
Expression:
Avoid(!ID!)Code Block:
def Avoid(ID):
if ID == "하천":
return 1
else:
return 0Scale Factor 가이드:
| Scale Factor | 효과 |
|---|---|
| 1.0 | 정상 통행 (회피 없음) |
| 1.1~1.2 | 약간 우회 |
| 2.0~5.0 | 중간 정도 우회 |
| 10.0 이상 | 강한 우회 |
선호(Prefer) 설정
특정 구간을 우선적으로 이용하도록 설정한다.
예시: 역 인근 200m 구간 선호
- 역 위치 포인트와 최근접 라인 세그먼트 추출 (Export Feature)
- Select by Location → Within a distance geodesic (200m)
- 선택된 구간에 필드 값 부여 (
!NEAR_FID! = 1) - Restriction 속성 추가 (Usage Type: Prefer)
- Evaluators 설정
Evaluator 설정 예시:
Expression:
Prefer(!NEAR_FID!)Code Block:
def Prefer(near_fid):
if near_fid == 1:
return 1
else:
return 0네트워크 데이터셋 속성: 계층(Hierarchy)
도로의 상대적 중요도를 정의하여 현실적인 경로 선택과 계산 속도 향상을 도모한다.
계층 속성의 역할
- 도로의 우선순위 정의 (고속도로 > 국도 > 대로 > 중로 > 소로)
- 경로 분석 시 큰 도로를 우선적으로 탐색
- 계산 효율성 증가
필드 조건
계층 속성을 추가하려면 먼저 도로 데이터에 계층 값 필드가 필요하다.
필드 예시:
- 필드명:
HIERARCHY - 데이터 타입: Short Integer
- 값 범위:
- 1 = 고속도로
- 2 = 국도
- 3 = 대로
- 4 = 중로
- 5 = 소로
중요: ArcGIS는 값이 작을수록 높은 계층(중요한 도로)으로 인식함.
계층 속성 추가 과정
- Network Dataset Properties → Attributes 탭
- Add → Hierarchy 선택
- Evaluators 탭에서 Along, Against, Default 모두 동일 필드 지정
- Field:
!HIERARCHY!
- Field:
- 네트워크 데이터셋 빌드
Travel Mode에서 계층 적용
계층 속성을 추가해도 분석에서 활성화해야 적용된다.
- Travel Mode 속성에서 Use Hierarchy = True 설정
- 또는 분석 레이어(Route, Service Area 등)에서 Use Network Hierarchy 체크
계층 값 역매핑
데이터가 반대로 저장된 경우 (큰 값 = 중요한 도로) 필드 계산기로 변환한다.
NewField = 6 - !OldValue!네트워크 데이터셋 필드 목록
| 필드명 | 의미 | 단위 | 타입 |
|---|---|---|---|
length_3d |
3D 길이(표면거리) | m | DOUBLE |
length_3dkm |
3D 길이 | km | DOUBLE |
grade_f |
구배 (From→To) | 무차원 | DOUBLE |
grade_b |
구배 (To→From) | 무차원 | DOUBLE |
sp_tob_f |
Tobler 속도 (From→To) | km/h | DOUBLE |
sp_tob_b |
Tobler 속도 (To→From) | km/h | DOUBLE |
sp_ks_f |
Kondo-Seino 속도 (From→To) | km/h | DOUBLE |
sp_ks_b |
Kondo-Seino 속도 (To→From) | km/h | DOUBLE |
hr_tob_f |
Tobler 소요시간 (From→To) | hr | DOUBLE |
hr_tob_b |
Tobler 소요시간 (To→From) | hr | DOUBLE |
hr_ks_f |
Kondo-Seino 소요시간 (From→To) | hr | DOUBLE |
hr_ks_b |
Kondo-Seino 소요시간 (To→From) | hr | DOUBLE |
kcal_ks_f |
칼로리 소비 (From→To, KS) | kcal/kg | DOUBLE |
kcal_ks_b |
칼로리 소비 (To→From, KS) | kcal/kg | DOUBLE |
kcal_tob_f |
칼로리 소비 (From→To, Tobler) | kcal/kg | DOUBLE |
kcal_tob_b |
칼로리 소비 (To→From, Tobler) | kcal/kg | DOUBLE |
ID |
수상 영역 구분 | "바다" or "하천" | TEXT |
품질 검증 (QA 체크포인트)
length_3d >= Shape_Length확인 (표면거리 ≥ 평면거리)- 오르막 구간 (
grade > 0):hr_f > hr_b - 내리막 구간 (
grade < 0):hr_f < hr_b - 샘플 구간의 속도/시간/칼로리 값이 현실적인 범위 내에 있는지 확인
필드 계산 자동화 스크립트
개요
3D 길이, 구배, 속도(Tobler/Kondo-Seino), 시간, 칼로리를 일괄 계산하는 ArcGIS Pro Python 스크립트.
주요 기능:
- Z 값이 포함된 라인 피처에서 3D 거리 및 구배 계산
- Tobler 및 Kondo-Seino 보행 속도 함수 적용
- MET 기반 칼로리 소비량 계산
- 수상 구간(바다/하천) 처리: 고정 속도, 칼로리=0
스크립트
import arcpy
import math
arcpy.env.overwriteOutput = True
in_lines = arcpy.GetParameterAsText(0)
F_ID = "ID"
F_LEN_3D = "length_3d"
F_LEN_3DKM = "length_3dkm"
F_GRADE_F = "grade_f"
F_GRADE_B = "grade_b"
F_SP_TOB_F = "sp_tob_f"
F_SP_TOB_B = "sp_tob_b"
F_SP_KS_F = "sp_ks_f"
F_SP_KS_B = "sp_ks_b"
F_HR_TOB_F = "hr_tob_f"
F_HR_TOB_B = "hr_tob_b"
F_HR_KS_F = "hr_ks_f"
F_HR_KS_B = "hr_ks_b"
F_KCAL_KS_F = "kcal_ks_f"
F_KCAL_KS_B = "kcal_ks_b"
F_KCAL_TB_F = "kcal_tob_f"
F_KCAL_TB_B = "kcal_tob_b"
V_SEA = 5.0
V_RIVER = 1.2
desc = arcpy.Describe(in_lines)
sr = desc.spatialReference
hasZ = getattr(desc, "hasZ", False)
if not hasZ:
arcpy.AddError("입력 라인에 Z가 없습니다.")
raise SystemExit(1)
def ensure_field(fc, name, ftype="DOUBLE", length=None):
names = [f.name for f in arcpy.ListFields(fc)]
if name not in names:
if ftype.upper() == "TEXT" and length is not None:
arcpy.management.AddField(fc, name, ftype, field_length=length)
else:
arcpy.management.AddField(fc, name, ftype)
for fld in [F_LEN_3D, F_LEN_3DKM, F_GRADE_F, F_GRADE_B,
F_SP_TOB_F, F_SP_TOB_B, F_SP_KS_F, F_SP_KS_B,
F_HR_TOB_F, F_HR_TOB_B, F_HR_KS_F, F_HR_KS_B,
F_KCAL_KS_F, F_KCAL_KS_B, F_KCAL_TB_F, F_KCAL_TB_B]:
ensure_field(in_lines, fld, "DOUBLE")
def v_kmh_tobler(g):
v = 6.0 * math.exp(-3.5 * abs(g + 0.05))
return max(min(v, 7.5), 1.0)
def v_kmh_kondoseino(g):
if g >= -0.07:
v = 5.1 * math.exp(-2.25 * abs(g + 0.07))
else:
v = 5.1 * math.exp(-1.5 * abs(g + 0.07))
return max(v, 0.5)
LAMBDA_DOWN = 0.5
def met_acsm_hybrid(v_kmh, g, lam=LAMBDA_DOWN):
if not v_kmh or v_kmh <= 0:
return 1.0
v_mpm = v_kmh * 1000.0 / 60.0
g_eff = g if g >= 0 else lam * g
vo2 = 0.1 * v_mpm + 1.8 * v_mpm * g_eff + 3.5
return max(vo2 / 3.5, 1.0)
def _valid_z(z):
try:
return (z is not None) and (not math.isnan(z))
except Exception:
return False
fields = ["SHAPE@", F_ID, F_LEN_3D, F_LEN_3DKM, F_GRADE_F, F_GRADE_B,
F_SP_TOB_F, F_SP_TOB_B, F_SP_KS_F, F_SP_KS_B,
F_HR_TOB_F, F_HR_TOB_B, F_HR_KS_F, F_HR_KS_B,
F_KCAL_KS_F, F_KCAL_KS_B, F_KCAL_TB_F, F_KCAL_TB_B]
IDX = {name: i for i, name in enumerate(fields)}
with arcpy.da.UpdateCursor(in_lines, fields) as cur:
for row in cur:
shp = row[IDX["SHAPE@"]]
idv = (row[IDX[F_ID]] or "").strip()
try:
l3d = shp.length3D
except AttributeError:
l3d = None
if not l3d or l3d <= 0:
l3d = shp.length
l3dkm = l3d / 1000.0
l2d = shp.length
try:
z_from = shp.firstPoint.Z
z_to = shp.lastPoint.Z
except AttributeError:
z_from = z_to = None
if not (_valid_z(z_from) and _valid_z(z_to)) or not l2d or l2d <= 0:
g_f = g_b = 0.0
else:
dz = (z_to - z_from)
g_f = dz / l2d
g_b = -g_f
sp_tob_f = v_kmh_tobler(g_f)
sp_tob_b = v_kmh_tobler(g_b)
sp_ks_f = v_kmh_kondoseino(g_f)
sp_ks_b = v_kmh_kondoseino(g_b)
fixed_mode = None
if idv == "바다":
fixed_mode = "SEA"
fixed_v = V_SEA
elif idv == "하천":
fixed_mode = "RIVER"
fixed_v = V_RIVER
if fixed_mode:
sp_tob_f = sp_tob_b = fixed_v
sp_ks_f = sp_ks_b = fixed_v
hr_tob_f = (l3dkm / sp_tob_f) if sp_tob_f > 0 else 1e6
hr_tob_b = (l3dkm / sp_tob_b) if sp_tob_b > 0 else 1e6
hr_ks_f = (l3dkm / sp_ks_f) if sp_ks_f > 0 else 1e6
hr_ks_b = (l3dkm / sp_ks_b) if sp_ks_b > 0 else 1e6
if fixed_mode:
kcal_ks_f = kcal_ks_b = kcal_tob_f = kcal_tob_b = 0.0
else:
kcal_ks_f = met_acsm_hybrid(sp_ks_f, g_f) * hr_ks_f
kcal_ks_b = met_acsm_hybrid(sp_ks_b, g_b) * hr_ks_b
kcal_tob_f = met_acsm_hybrid(sp_tob_f, g_f) * hr_tob_f
kcal_tob_b = met_acsm_hybrid(sp_tob_b, g_b) * hr_tob_b
row[IDX[F_LEN_3D]] = l3d
row[IDX[F_LEN_3DKM]] = l3dkm
row[IDX[F_GRADE_F]] = g_f
row[IDX[F_GRADE_B]] = g_b
row[IDX[F_SP_TOB_F]] = sp_tob_f
row[IDX[F_SP_TOB_B]] = sp_tob_b
row[IDX[F_SP_KS_F]] = sp_ks_f
row[IDX[F_SP_KS_B]] = sp_ks_b
row[IDX[F_HR_TOB_F]] = hr_tob_f
row[IDX[F_HR_TOB_B]] = hr_tob_b
row[IDX[F_HR_KS_F]] = hr_ks_f
row[IDX[F_HR_KS_B]] = hr_ks_b
row[IDX[F_KCAL_KS_F]] = kcal_ks_f
row[IDX[F_KCAL_KS_B]] = kcal_ks_b
row[IDX[F_KCAL_TB_F]] = kcal_tob_f
row[IDX[F_KCAL_TB_B]] = kcal_tob_b
cur.updateRow(row)
arcpy.AddMessage("완료")사용자 정의 도구 생성
Tool Properties → Parameters 설정:
| Label | Data Type | 유형 | Direction | 필터 |
|---|---|---|---|---|
| 네트워크 데이터(라인 피처) | Feature Class | 필요한 정보 | Input | 피처 유형(Polyline) |
관련 도구
참고 문헌
- Tobler, W. (1993). Three presentations on geographical analysis and modeling: Non-isotropic geographic modeling speculations on the geometry of geography global spatial analysis. Technical Report, 93-1. National Center for Geographic Information and Analysis, University of California, Santa Barbara.
- Kondo, Y., & Seino, Y. (2010). GPS-aided walking experiments and data-driven travel cost modeling on the historical road of Nakasendō-Kisoji (Central Highland Japan). In B. Frischer (Ed.), Making history interactive: Computer applications and quantitative methods in archaeology (CAA). Proceedings of the 37th international conference (pp. 158-165). Archaeopress.
- American College of Sports Medicine (ACSM). (2013). ACSM's guidelines for exercise testing and prescription (9th ed.). Lippincott Williams & Wilkins.
외부 링크
- ArcGIS Pro - What is a network dataset?
- ArcGIS Pro - Network attributes
- ArcGIS Pro - Interpolate Shape
활용 모델 2: 래스터 기반 최소 비용 경로 분석
개요
DEM(Digital Elevation Model) 기반의 비등방(anisotropic) 비용면을 구성하고, Tobler 및 Kondo-Seino 도보 함수를 수직 인자(Vertical Factor)로 정의하여 오르막/내리막에 따른 방향 비대칭 비용을 반영하는 최소 비용 경로 분석 방법론이다.
- 프로젝트 좌표계: EPSG:5179 (Korea 2000 / Central Belt)
- DEM 해상도: SRTM 30m
분석 프로세스
1단계: 평지 비용 래스터 생성
시간 비용 래스터 (단위: 초/30m)
| 지형 유형 | Tobler 함수 | Kondo-Seino 함수 |
|---|---|---|
| 평지 | 21.44 | 24.79 |
| 하천 영역 | 90 | 90 |
| 바다 영역 | 21.6 | 21.6 |
Tobler 시간 비용 래스터 생성 (Raster Calculator)
# 1단계: DEM 있는 곳을 평지 값으로
Con(~IsNull("srtm_5179"), 21.44)
# 출력: base_land_tob
# 2단계: 바다 영역 확장
Con(IsNull("바다_조선5179"), 0, "바다_조선5179")
# 출력: sea_5179
# 3단계: 바다 적용
Con("sea_5179" == 1, 21.6, "base_land_tob")
# 출력: with_sea_tob
# 4단계: 하천 영역 확장
Con(IsNull("하천_5179"), 0, "하천_5179")
# 출력: river_5179
# 5단계: 하천 적용 (최종)
Con("river_5179" == 1, 90, "with_sea_tob")
# 출력: cost_tobKondo-Seino 시간 비용 래스터 생성
# 6단계: DEM 있는 곳을 평지 값으로
Con(~IsNull("srtm_5179"), 24.79)
# 출력: base_land_ks
# 7단계: 바다 적용
Con("sea_5179" == 1, 21.6, "base_land_ks")
# 출력: with_sea_ks
# 8단계: 하천 적용 (최종)
Con("river_5179" == 1, 90, "with_sea_ks")
# 출력: cost_ks칼로리 비용 래스터 (단위: kcal/kg/30m)
| 지형 유형 | Tobler 함수 | Kondo-Seino 함수 |
|---|---|---|
| 평지 | 0.0202 | 0.0212 |
| 하천 영역 | NoData | NoData |
| 바다 영역 | NoData | NoData |
Tobler 칼로리 비용 래스터 생성
# 9단계: DEM 있는 곳을 평지 값으로
Con(~IsNull("srtm_5179"), 0.0202)
# 출력: base_land_tk
# 10단계: 바다 적용
SetNull("sea_5179" == 1, "base_land_tk")
# 출력: with_sea_tk
# 11단계: 하천 적용 (최종)
SetNull("river_5179" == 1, "with_sea_tk")
# 출력: cost_tob_kKondo-Seino 칼로리 비용 래스터 생성
# 12단계: DEM 있는 곳을 평지 값으로
Con(~IsNull("srtm_5179"), 0.0212)
# 출력: base_land_kk
# 13단계: 바다 적용
SetNull("sea_5179" == 1, "base_land_kk")
# 출력: with_sea_kk
# 14단계: 하천 적용 (최종)
SetNull("river_5179" == 1, "with_sea_kk")
# 출력: cost_ks_k2단계: 출발지와 도착지 설정
- 출발지점과 도착지점을 각각 포인트 피처로 생성
- 좌표계: EPSG:5179
3단계: 분석 범위 설정
도구: Extract by Mask (공간 분석 도구)
- 입력 래스터: 비용 래스터 (cost_tob, cost_ks 등)
- 마스크 피처: 분석 범위 폴리곤
- 목적: 분석 범위에 해당하는 비용 래스터 추출
4단계: 거리 누적 및 역방향 래스터 생성
방법 1: Distance Accumulation (ArcGIS Pro 내장 함수)
도구: Distance Accumulation
| 매개변수 | 설정값 |
|---|---|
| 입력 래스터 또는 피처 시작지점 | 출발지점 포인트 피처 |
| 입력 표면 래스터 | 마스크로 추출한 DEM |
| 입력 비용 래스터 | 마스크로 추출한 비용 래스터 |
| 결과 역방향 래스터 | (경로 지정) |
| 거리 방법 | 측지 |
| 입력 수직 래스터 | DEM |
| 수직 계수 | 하이킹 시간 (Hiking Time) |
| 임계각 | -90 ~ 90 |
특징:
- ArcGIS Pro에 내장된 Tobler(1993) 함수 근사치 사용
- 수직 상대 이동각(VRMA)에 따라 평지 대비 소요 시간 배율(VF) 자동 계산
- 오르막과 내리막이 비대칭적으로 처리됨
- 주의: 일정 경사 구간으로 나누어 근사한 함수이므로, 세밀한 지형 분석에서는 실제 Tobler 함수와 차이가 발생할 수 있음
방법 2: Path Distance (사용자 정의 수직 계수)
도구: Path Distance
| 매개변수 | 설정값 |
|---|---|
| 입력 래스터 또는 피처 소스 데이터 | 출발지점 포인트 피처 |
| 입력 비용 래스터 | 마스크로 추출한 비용 래스터 |
| 입력 표면 래스터 | 마스크로 추출한 DEM |
| 결과 백링크 래스터 | (경로 지정) |
| 입력 수직 래스터 | DEM |
| 수직 계수 | VF Table (사용자 정의) |
특징:
- Tobler 또는 Kondo-Seino 함수를 정확히 구현한 VF 테이블 사용
- 시간 비용(s/m) 및 칼로리 비용(kcal/kg/m) 모두 계산 가능
5단계: Dijkstra 알고리즘 기반 최소 비용 경로 계산
알고리즘 개요
Dijkstra 알고리즘은 가중치가 있는 그래프에서 한 시작 지점으로부터 다른 모든 지점까지의 최단 경로를 구하는 기법이다. 간선의 가중치가 음수가 아닌 경우 정확한 최단 거리를 보장한다.
계산 과정:
- 비용 래스터 준비: 평지 비용 + 수직 계수
- Cost Distance 계산:
- 초기화: 모든 셀의 누적비용을 ∞로 설정, 출발 셀만 0으로 설정
- 가장 낮은 비용 셀 선택: Open List에서 누적비용이 가장 작은 셀을 확정(visited) 처리
- 이웃 셀 비용 계산: 확정된 셀의 주변 8개 이웃에 대해 새비용 = 확정된 셀 비용 + 이웃 셀 비용 계산
- 더 낮은 비용 발견 시 업데이트 및 Backlink Raster에 방향 기록
- 목적지 도달까지 반복
- Cost Path 추출: 도착지에서 Backlink를 따라 역추적
결과물:
- Distance Raster: 출발지에서 각 셀까지의 최소 누적비용
- Backlink Raster: 각 셀에서 출발 지점으로 돌아갈 때 다음에 밟아야 할 셀의 방향 (0=소스, 1=E, 2=SE, 3=S, 4=SW, 5=W, 6=NW, 7=N, 8=NE)
Backlink 방향 코드
| 코드 | 방향 | 설명 |
|---|---|---|
| 0 | - | 소스(출발지) |
| 1 | E | 동쪽 |
| 2 | SE | 남동쪽 |
| 3 | S | 남쪽 |
| 4 | SW | 남서쪽 |
| 5 | W | 서쪽 |
| 6 | NW | 북서쪽 |
| 7 | N | 북쪽 |
| 8 | NE | 북동쪽 |
6단계: 최저비용경로 추출
Distance Accumulation 사용 시
도구: Optimal Path As Line
| 매개변수 | 설정값 |
|---|---|
| 입력 래스터 또는 피처 목적지 | 도착지점 포인트 피처 |
| 입력 거리 누적 래스터 | Distance Raster |
| 입력 역방향 또는 흐름 방향 래스터 | Backlink Raster |
| 래스터 형식 결과 최적 경로 | (경로 지정) |
| 경로 유형 | 최적(BEST_SINGLE) |
Path Distance 사용 시
도구: Cost Path
| 매개변수 | 설정값 |
|---|---|
| 래스터 또는 피처 대상 데이터 입력 | 도착지점 포인트 피처 |
| 대상 필드 | (자동 선택) |
| 입력 비용 거리 래스터 | Distance Raster |
| 입력 비용 백링크 래스터 | Backlink Raster |
| 결과 래스터 | (경로 지정) |
| 경로 유형 | 최적(BEST_SINGLE) |
7단계: 래스터를 벡터로 변환
도구: Raster to Polyline
- 입력 래스터: 최적 경로 래스터
- 폴리라인 단순화: 체크 해제
- 출력: 최적 경로 라인 피처
8단계: 구간별 시간/칼로리 계산
- 구간 분할 간격: 10m
- 사용자 정의 도구: LineCarculate
- 계산 항목: 구간별 이동 시간, 칼로리 소비량
비용 래스터 보정
특정 구간에서 비용을 조정하여 제한 요소(선호, 회피)를 반영할 수 있다.
1단계: 네트워크 라인 래스터화
도구: Feature to Raster
- 입력: 네트워크 라인 피처
- 출력 셀 크기: DEM과 동일
- 결과: 라인 셀=1, 비라인 셀=0 또는 NoData
필요시 Reclassify 도구로 NoData를 0으로 변경
2단계: 비용 조정 래스터 계산
Raster Calculator 수식:
# 네트워크 라인 구역에서 비용 1/1.6배 감소 (선호)
cost_li = "cost_" * Con("line_raster" == 1, 1/1.6, 1)
# 네트워크 라인 구역에서 비용 1.3배 증가 (회피)
cost_li = "cost_" * Con("line_raster" == 1, 1.3, 1)
# 도로는 선호(1/1.6배), 하천은 회피(1.3배)
cost_li = "cost_" * Con("도로_srtm30" == 1, 1/1.6, 1) * Con("하천_srtm30" == 1, 1.3, 1)조정 계수:
- 선호 경로: 1/1.6 ≈ 0.625 (비용 약 37.5% 감소)
- 회피 경로: 1.3 (비용 30% 증가)
관련 도구
- ArcGIS Pro
- Spatial Analyst
- Distance Accumulation
- Path Distance
- Optimal Path As Line
- Cost Path
- Raster Calculator
참고 문헌
- Tobler, W. (1993). Three presentations on geographical analysis and modeling: Non-isotropic geographic modeling speculations on the geometry of geography global spatial analysis. Technical Report, 93-1. National Center for Geographic Information and Analysis, University of California, Santa Barbara.
- Kondo, Y., & Seino, Y. (2010). GPS-aided walking experiments and data-driven travel cost modeling on the historical road of Nakasendō-Kisoji (Central Highland Japan). In B. Frischer (Ed.), Making history interactive: Computer applications and quantitative methods in archaeology (CAA). Proceedings of the 37th international conference (pp. 158-165). Archaeopress.
외부 링크
참고 문헌
- 양정현, 2023, HGIS를 통해 본 조선 전기 양주의 도로 체계와 역사적 경로 재현 - 양주 회암사의 사례를 중심으로, 남도문화연구 50
- 양정현, 2024, 조선시대 도로 네트워크 분석 방법론과 사례 연구 - 양주의 사례를 중심으로, 문화역사지리 36-3
- 양정현, 2025, '신출귀몰'의 재구성 - 역사 연구와 GIS가 연결되는 한 방식, 역사비평 153 (발행 예정)
메모
- todo: 2차 및 3차 지형도의 도로 등급 반영 후 네트워크 데이터셋에 계층 속성 추가
DB 변화 이력
- 2025년 09월 03일 : 최초 공개
- 2025년 11월 14일 : '네트워크 데이터셋 기반 최소 비용 경로 분석' 항목 보완 및 '래스터 기반 최소 비용 경로 분석' 항목 추가