근대 교통로 DB

역지사지(歷地思之) - 역사지리정보(HGIS) 위키
Yachagye (토론 | 기여)님의 2025년 11월 14일 (금) 16:44 판
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)
둘러보기로 이동 검색으로 이동

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) / len2d

Expression:

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단계: 네트워크 데이터셋 생성

네트워크 데이터셋 생성
  1. Catalog Pane에서 지오데이터베이스 선택
  2. 오른쪽 클릭 → New → Network Dataset
  3. 네트워크 데이터셋 이름 지정 및 폴리라인 레이어 선택
비용 속성(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!
네트워크 데이터셋 빌드
  1. 네트워크 데이터셋을 마우스 오른쪽 버튼으로 클릭
  2. Build Network 선택하여 빌드 실행

10단계: 경로 분석 실행

  1. 네트워크 데이터셋 레이어를 마우스 오른쪽 버튼으로 클릭
  2. Network Analyst 탭에서 '경로(Route)' 선택
  3. 경로 레이어에서 출발지, 도착지 추가
  4. 경로 레이어 Properties에서 임피던스(Impedance) 선택
    • hour_tob, hour_ks, length_3d, kcal_ks, kcal_tob 중 선택
  5. '비용 속성 누적'에서 추가 속성 선택 (경로 레이어 리본의 Σ 버튼)
  6. 네트워크 분석 실행

네트워크 데이터셋 속성: 제한(Restriction)

특정 구간을 회피(Avoid)하거나 선호(Prefer)하도록 설정할 수 있다.

회피(Avoid) 설정

특정 필드 값을 가진 구간에 높은 비용을 부여하여 우회하도록 유도한다.

설정 과정:

  1. Network Dataset Properties → Attributes 탭
  2. Add → Restriction 선택
  3. Restriction 이름 지정 (예: Avoid_River)
  4. Usage Type: Avoid
  5. Scale Factor 설정 (예: 2.0~5.0)
    • 값이 클수록 강한 회피 효과
  6. Evaluators 탭에서 Expression 설정

Evaluator 설정 예시 (하천 회피):

Expression:

Avoid(!ID!)

Code Block:

def Avoid(ID):
    if ID == "하천":
        return 1
    else:
        return 0

Scale Factor 가이드:

Scale Factor 효과
1.0 정상 통행 (회피 없음)
1.1~1.2 약간 우회
2.0~5.0 중간 정도 우회
10.0 이상 강한 우회

선호(Prefer) 설정

특정 구간을 우선적으로 이용하도록 설정한다.

예시: 역 인근 200m 구간 선호

  1. 역 위치 포인트와 최근접 라인 세그먼트 추출 (Export Feature)
  2. Select by Location → Within a distance geodesic (200m)
  3. 선택된 구간에 필드 값 부여 (!NEAR_FID! = 1)
  4. Restriction 속성 추가 (Usage Type: Prefer)
  5. 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는 값이 작을수록 높은 계층(중요한 도로)으로 인식함.

계층 속성 추가 과정

  1. Network Dataset Properties → Attributes 탭
  2. Add → Hierarchy 선택
  3. Evaluators 탭에서 Along, Against, Default 모두 동일 필드 지정
    • Field: !HIERARCHY!
  4. 네트워크 데이터셋 빌드

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.

외부 링크

활용 모델 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_tob

Kondo-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_k

Kondo-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_k

2단계: 출발지와 도착지 설정

  • 출발지점과 도착지점을 각각 포인트 피처로 생성
  • 좌표계: 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 알고리즘은 가중치가 있는 그래프에서 한 시작 지점으로부터 다른 모든 지점까지의 최단 경로를 구하는 기법이다. 간선의 가중치가 음수가 아닌 경우 정확한 최단 거리를 보장한다.

계산 과정:

  1. 비용 래스터 준비: 평지 비용 + 수직 계수
  2. Cost Distance 계산:
    • 초기화: 모든 셀의 누적비용을 ∞로 설정, 출발 셀만 0으로 설정
    • 가장 낮은 비용 셀 선택: Open List에서 누적비용이 가장 작은 셀을 확정(visited) 처리
    • 이웃 셀 비용 계산: 확정된 셀의 주변 8개 이웃에 대해 새비용 = 확정된 셀 비용 + 이웃 셀 비용 계산
    • 더 낮은 비용 발견 시 업데이트 및 Backlink Raster에 방향 기록
    • 목적지 도달까지 반복
  3. 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% 증가)

관련 도구

참고 문헌

  • 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일 : '네트워크 데이터셋 기반 최소 비용 경로 분석' 항목 보완 및 '래스터 기반 최소 비용 경로 분석' 항목 추가