근대 교통로 DB 문서 원본 보기
←
근대 교통로 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 * 다운로드 링크(구글 드라이브) ** https://drive.google.com/file/d/1YWEitJ73z2QQ6n5zBoooeVujNcBPmPBq/view?usp=drive_link == 필드 설계 == {| class="wikitable" ! 필드명 !! 의미 !! 단위 !! 타입 |- | 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 {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 입력 피처 || 네트워크 라인 레이어 |- | 거리 || 10m (분석 목적에 따라 조정) |} '''라인 분할''': '''도구''': Split Line at Point (Data Management Tools → Features) {| class="wikitable" |- ! 매개변수 !! 설정값 |- | Input Features || 네트워크 라인 레이어 |- | Point Features || 생성된 점 레이어 |- | 검색 반경 || 1mm |} ==== 2단계: 좌표계 변환 (투영) ==== '''DEM 투영''': '''도구''': Project Raster {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 입력 래스터 || SRTM DEM |- | 출력 좌표계 || EPSG:5179 (Korea 2000 / Central Belt) |- | 리샘플링 기법 || Bilinear (이중선형 보간) |- | 셀 크기 || 원본 유지 (약 30m) |} '''네트워크 라인 투영''': '''도구''': Project {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 입력 피처 || 네트워크 라인 |- | 출력 좌표계 || EPSG:5179 |} '''중요''': XY, Z 모두 미터 단위로 맞춰야 구배/길이 계산이 정확함. ==== 3단계: 라인에 Z 값 보간 (3D 라인 생성) ==== '''도구''': Interpolate Shape (3D Analyst) {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 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: <code>!length_3d! / 1000.0</code> * 단위: Kilometers '''품질 검증''': <code>length_3d >= Shape_Length</code> 확인 (표면거리 ≥ 평면거리) ==== 5단계: 구배(Grade) 계산 ==== 구배는 수평거리(2D)를 분모로 하여 계산하며, 이동 방향에 따라 부호가 반전된다. '''필드 생성''': * <code>grade_f</code>: From→To 방향 구배 * <code>grade_b</code>: To→From 방향 구배 * 데이터 타입: Double ===== 간단식 (데이터가 정상일 때) ===== <syntaxhighlight lang="python"> grade_f = (!shape.lastPoint.Z! - !shape.firstPoint.Z!) / !Shape_Length! grade_b = -!grade_f! </syntaxhighlight> ===== 권장식 (Z 값 NaN/None 방지) ===== '''Code Block (Python)''': <syntaxhighlight lang="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 </syntaxhighlight> '''Expression''': <syntaxhighlight lang="python"> grade_f = safe_grade(!shape.firstPoint.Z!, !shape.lastPoint.Z!, !Shape_Length!) grade_b = -!grade_f! </syntaxhighlight> ==== 6단계: 속도 및 시간 계산 ==== ===== 보행 속도 함수 ===== '''Code Block (Python)''': <syntaxhighlight lang="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 </syntaxhighlight> '''필드 생성 - 속도 (km/h)''': <syntaxhighlight lang="python"> 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!) </syntaxhighlight> '''필드 생성 - 시간 (hr)''': <syntaxhighlight lang="python"> 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!) </syntaxhighlight> ==== 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)''': <syntaxhighlight lang="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 </syntaxhighlight> '''필드 생성 - 칼로리 (kcal/kg)''': <syntaxhighlight lang="python"> 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!) </syntaxhighlight> ==== 8단계: 수상 영역 속도 및 칼로리 보정 ==== 바다 및 하천 구간은 도보가 아닌 선박 이동으로 가정하여 속도를 고정하고 칼로리를 0으로 설정한다. {| class="wikitable" |- ! 구간 유형 !! 고정 속도 (km/h) !! 칼로리 (kcal/kg) |- | 바다 || 5.0 || 0 |- | 하천 || 1.2 || 0 |- | 육상 || Tobler/Kondo-Seino 함수 || MET 기반 계산 |} '''구현 방법''': * <code>ID</code> 필드에 "바다" 또는 "하천" 값을 가진 구간 식별 * 해당 구간의 속도 필드를 고정값으로 설정 * 칼로리 필드를 0으로 설정 ==== 9단계: 네트워크 데이터셋 생성 ==== ===== 네트워크 데이터셋 생성 ===== # Catalog Pane에서 지오데이터베이스 선택 # 오른쪽 클릭 → New → Network Dataset # 네트워크 데이터셋 이름 지정 및 폴리라인 레이어 선택 ===== 비용 속성(Cost Attribute) 설정 ===== Catalog → 네트워크 데이터셋 → Properties → Attributes 탭 '''비용 속성 1: hour_tob (Tobler 시간)''' {| class="wikitable" |- ! 설정 항목 !! 값 |- | 속성 유형 || Cost |- | 단위 || Hours |- | Evaluator - Along || Field: <code>!hr_tob_f!</code> |- | Evaluator - Against || Field: <code>!hr_tob_b!</code> |} '''비용 속성 2: hour_ks (Kondo-Seino 시간)''' {| class="wikitable" |- ! 설정 항목 !! 값 |- | 속성 유형 || Cost |- | 단위 || Hours |- | Evaluator - Along || Field: <code>!hr_ks_f!</code> |- | Evaluator - Against || Field: <code>!hr_ks_b!</code> |} '''비용 속성 3: length_3d (3D 거리)''' {| class="wikitable" |- ! 설정 항목 !! 값 |- | 속성 유형 || Cost |- | 단위 || Kilometers |- | Evaluator - Along || Field: <code>!length_3dkm!</code> |- | Evaluator - Against || Field: <code>!length_3dkm!</code> |} '''비용 속성 4: kcal_ks (Kondo-Seino 칼로리)''' {| class="wikitable" |- ! 설정 항목 !! 값 |- | 속성 유형 || Cost |- | 단위 || Unknown (kcal/kg) |- | Evaluator - Along || Field: <code>!kcal_ks_f!</code> |- | Evaluator - Against || Field: <code>!kcal_ks_b!</code> |} '''비용 속성 5: kcal_tob (Tobler 칼로리)''' {| class="wikitable" |- ! 설정 항목 !! 값 |- | 속성 유형 || Cost |- | 단위 || Unknown (kcal/kg) |- | Evaluator - Along || Field: <code>!kcal_tob_f!</code> |- | Evaluator - Against || Field: <code>!kcal_tob_b!</code> |} ===== 네트워크 데이터셋 빌드 ===== # 네트워크 데이터셋을 마우스 오른쪽 버튼으로 클릭 # 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 이름 지정 (예: <code>Avoid_River</code>) # Usage Type: '''Avoid''' # Scale Factor 설정 (예: 2.0~5.0) #* 값이 클수록 강한 회피 효과 # Evaluators 탭에서 Expression 설정 '''Evaluator 설정 예시 (하천 회피)''': Expression: <syntaxhighlight lang="python"> Avoid(!ID!) </syntaxhighlight> Code Block: <syntaxhighlight lang="python"> def Avoid(ID): if ID == "하천": return 1 else: return 0 </syntaxhighlight> '''Scale Factor 가이드''': {| class="wikitable" |- ! 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) # 선택된 구간에 필드 값 부여 (<code>!NEAR_FID! = 1</code>) # Restriction 속성 추가 (Usage Type: Prefer) # Evaluators 설정 '''Evaluator 설정 예시''': Expression: <syntaxhighlight lang="python"> Prefer(!NEAR_FID!) </syntaxhighlight> Code Block: <syntaxhighlight lang="python"> def Prefer(near_fid): if near_fid == 1: return 1 else: return 0 </syntaxhighlight> === 네트워크 데이터셋 속성: 계층(Hierarchy) === 도로의 상대적 중요도를 정의하여 현실적인 경로 선택과 계산 속도 향상을 도모한다. ==== 계층 속성의 역할 ==== * 도로의 우선순위 정의 (고속도로 > 국도 > 대로 > 중로 > 소로) * 경로 분석 시 큰 도로를 우선적으로 탐색 * 계산 효율성 증가 ==== 필드 조건 ==== 계층 속성을 추가하려면 먼저 도로 데이터에 계층 값 필드가 필요하다. '''필드 예시''': * 필드명: <code>HIERARCHY</code> * 데이터 타입: Short Integer * 값 범위: ** 1 = 고속도로 ** 2 = 국도 ** 3 = 대로 ** 4 = 중로 ** 5 = 소로 '''중요''': ArcGIS는 값이 작을수록 높은 계층(중요한 도로)으로 인식함. ==== 계층 속성 추가 과정 ==== # Network Dataset Properties → Attributes 탭 # Add → Hierarchy 선택 # Evaluators 탭에서 Along, Against, Default 모두 동일 필드 지정 #* Field: <code>!HIERARCHY!</code> # 네트워크 데이터셋 빌드 ==== Travel Mode에서 계층 적용 ==== 계층 속성을 추가해도 분석에서 활성화해야 적용된다. * Travel Mode 속성에서 '''Use Hierarchy = True''' 설정 * 또는 분석 레이어(Route, Service Area 등)에서 '''Use Network Hierarchy''' 체크 ==== 계층 값 역매핑 ==== 데이터가 반대로 저장된 경우 (큰 값 = 중요한 도로) 필드 계산기로 변환한다. <syntaxhighlight lang="python"> NewField = 6 - !OldValue! </syntaxhighlight> === 네트워크 데이터셋 필드 목록 === {| class="wikitable" |- ! 필드명 !! 의미 !! 단위 !! 타입 |- | <code>length_3d</code> || 3D 길이(표면거리) || m || DOUBLE |- | <code>length_3dkm</code> || 3D 길이 || km || DOUBLE |- | <code>grade_f</code> || 구배 (From→To) || 무차원 || DOUBLE |- | <code>grade_b</code> || 구배 (To→From) || 무차원 || DOUBLE |- | <code>sp_tob_f</code> || Tobler 속도 (From→To) || km/h || DOUBLE |- | <code>sp_tob_b</code> || Tobler 속도 (To→From) || km/h || DOUBLE |- | <code>sp_ks_f</code> || Kondo-Seino 속도 (From→To) || km/h || DOUBLE |- | <code>sp_ks_b</code> || Kondo-Seino 속도 (To→From) || km/h || DOUBLE |- | <code>hr_tob_f</code> || Tobler 소요시간 (From→To) || hr || DOUBLE |- | <code>hr_tob_b</code> || Tobler 소요시간 (To→From) || hr || DOUBLE |- | <code>hr_ks_f</code> || Kondo-Seino 소요시간 (From→To) || hr || DOUBLE |- | <code>hr_ks_b</code> || Kondo-Seino 소요시간 (To→From) || hr || DOUBLE |- | <code>kcal_ks_f</code> || 칼로리 소비 (From→To, KS) || kcal/kg || DOUBLE |- | <code>kcal_ks_b</code> || 칼로리 소비 (To→From, KS) || kcal/kg || DOUBLE |- | <code>kcal_tob_f</code> || 칼로리 소비 (From→To, Tobler) || kcal/kg || DOUBLE |- | <code>kcal_tob_b</code> || 칼로리 소비 (To→From, Tobler) || kcal/kg || DOUBLE |- | <code>ID</code> || 수상 영역 구분 || "바다" or "하천" || TEXT |} === 품질 검증 (QA 체크포인트) === * <code>length_3d >= Shape_Length</code> 확인 (표면거리 ≥ 평면거리) * 오르막 구간 (<code>grade > 0</code>): <code>hr_f > hr_b</code> * 내리막 구간 (<code>grade < 0</code>): <code>hr_f < hr_b</code> * 샘플 구간의 속도/시간/칼로리 값이 현실적인 범위 내에 있는지 확인 === 필드 계산 자동화 스크립트 === ==== 개요 ==== 3D 길이, 구배, 속도(Tobler/Kondo-Seino), 시간, 칼로리를 일괄 계산하는 ArcGIS Pro Python 스크립트. '''주요 기능''': * Z 값이 포함된 라인 피처에서 3D 거리 및 구배 계산 * Tobler 및 Kondo-Seino 보행 속도 함수 적용 * MET 기반 칼로리 소비량 계산 * 수상 구간(바다/하천) 처리: 고정 속도, 칼로리=0 ==== 스크립트 ==== <syntaxhighlight lang="python"> 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("완료") </syntaxhighlight> ==== 사용자 정의 도구 생성 ==== '''Tool Properties → Parameters 설정''': {| class="wikitable" |- ! Label !! Data Type !! 유형 !! Direction !! 필터 |- | 네트워크 데이터(라인 피처) || Feature Class || 필요한 정보 || Input || 피처 유형(Polyline) |} === 관련 도구 === * [[ArcGIS Pro]] * [[Network Analyst]] * [[3D Analyst]] * [[Network Dataset]] === 참고 문헌 === * 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. === 외부 링크 === * [https://pro.arcgis.com/en/pro-app/latest/help/analysis/networks/what-is-a-network-dataset-.htm ArcGIS Pro - What is a network dataset?] * [https://pro.arcgis.com/en/pro-app/latest/help/analysis/networks/network-attributes.htm ArcGIS Pro - Network attributes] * [https://pro.arcgis.com/en/pro-app/latest/tool-reference/3d-analyst/interpolate-shape.htm ArcGIS Pro - Interpolate Shape] [[분류:GIS]] [[분류:공간분석]] [[분류:네트워크분석]] [[분류:경로분석]] == 활용 모델 2: 래스터 기반 최소 비용 경로 분석 == === 개요 === DEM(Digital Elevation Model) 기반의 비등방(anisotropic) 비용면을 구성하고, Tobler 및 Kondo-Seino 도보 함수를 수직 인자(Vertical Factor)로 정의하여 오르막/내리막에 따른 방향 비대칭 비용을 반영하는 최소 비용 경로 분석 방법론이다. * '''프로젝트 좌표계''': EPSG:5179 (Korea 2000 / Central Belt) * '''DEM 해상도''': SRTM 30m === 분석 프로세스 === ==== 1단계: 평지 비용 래스터 생성 ==== ===== 시간 비용 래스터 (단위: 초/30m) ===== {| class="wikitable" |- ! 지형 유형 !! Tobler 함수 !! Kondo-Seino 함수 |- | 평지 || 21.44 || 24.79 |- | 하천 영역 || 90 || 90 |- | 바다 영역 || 21.6 || 21.6 |} '''Tobler 시간 비용 래스터 생성 (Raster Calculator)''' <syntaxhighlight lang="python"> # 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 </syntaxhighlight> '''Kondo-Seino 시간 비용 래스터 생성''' <syntaxhighlight lang="python"> # 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 </syntaxhighlight> ===== 칼로리 비용 래스터 (단위: kcal/kg/30m) ===== {| class="wikitable" |- ! 지형 유형 !! Tobler 함수 !! Kondo-Seino 함수 |- | 평지 || 0.0202 || 0.0212 |- | 하천 영역 || NoData || NoData |- | 바다 영역 || NoData || NoData |} '''Tobler 칼로리 비용 래스터 생성''' <syntaxhighlight lang="python"> # 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 </syntaxhighlight> '''Kondo-Seino 칼로리 비용 래스터 생성''' <syntaxhighlight lang="python"> # 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 </syntaxhighlight> ==== 2단계: 출발지와 도착지 설정 ==== * 출발지점과 도착지점을 각각 포인트 피처로 생성 * 좌표계: EPSG:5179 ==== 3단계: 분석 범위 설정 ==== '''도구''': Extract by Mask (공간 분석 도구) * '''입력 래스터''': 비용 래스터 (cost_tob, cost_ks 등) * '''마스크 피처''': 분석 범위 폴리곤 * '''목적''': 분석 범위에 해당하는 비용 래스터 추출 ==== 4단계: 거리 누적 및 역방향 래스터 생성 ==== ===== 방법 1: Distance Accumulation (ArcGIS Pro 내장 함수) ===== '''도구''': Distance Accumulation {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 입력 래스터 또는 피처 시작지점 || 출발지점 포인트 피처 |- | 입력 표면 래스터 || 마스크로 추출한 DEM |- | 입력 비용 래스터 || 마스크로 추출한 비용 래스터 |- | 결과 역방향 래스터 || (경로 지정) |- | 거리 방법 || 측지 |- | 입력 수직 래스터 || DEM |- | 수직 계수 || '''하이킹 시간''' (Hiking Time) |- | 임계각 || -90 ~ 90 |} '''특징''': * ArcGIS Pro에 내장된 Tobler(1993) 함수 근사치 사용 * 수직 상대 이동각(VRMA)에 따라 평지 대비 소요 시간 배율(VF) 자동 계산 * 오르막과 내리막이 비대칭적으로 처리됨 * '''주의''': 일정 경사 구간으로 나누어 근사한 함수이므로, 세밀한 지형 분석에서는 실제 Tobler 함수와 차이가 발생할 수 있음 ===== 방법 2: Path Distance (사용자 정의 수직 계수) ===== '''도구''': Path Distance {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 입력 래스터 또는 피처 소스 데이터 || 출발지점 포인트 피처 |- | 입력 비용 래스터 || 마스크로 추출한 비용 래스터 |- | 입력 표면 래스터 || 마스크로 추출한 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 방향 코드 ===== {| class="wikitable" |- ! 코드 !! 방향 !! 설명 |- | 0 || - || 소스(출발지) |- | 1 || E || 동쪽 |- | 2 || SE || 남동쪽 |- | 3 || S || 남쪽 |- | 4 || SW || 남서쪽 |- | 5 || W || 서쪽 |- | 6 || NW || 북서쪽 |- | 7 || N || 북쪽 |- | 8 || NE || 북동쪽 |} ==== 6단계: 최저비용경로 추출 ==== ===== Distance Accumulation 사용 시 ===== '''도구''': Optimal Path As Line {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 입력 래스터 또는 피처 목적지 || 도착지점 포인트 피처 |- | 입력 거리 누적 래스터 || Distance Raster |- | 입력 역방향 또는 흐름 방향 래스터 || Backlink Raster |- | 래스터 형식 결과 최적 경로 || (경로 지정) |- | 경로 유형 || '''최적(BEST_SINGLE)''' |} ===== Path Distance 사용 시 ===== '''도구''': Cost Path {| class="wikitable" |- ! 매개변수 !! 설정값 |- | 래스터 또는 피처 대상 데이터 입력 || 도착지점 포인트 피처 |- | 대상 필드 || (자동 선택) |- | 입력 비용 거리 래스터 || 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 수식''': <syntaxhighlight lang="python"> # 네트워크 라인 구역에서 비용 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) </syntaxhighlight> '''조정 계수''': * '''선호 경로''': 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. === 외부 링크 === * [https://pro.arcgis.com/en/pro-app/latest/tool-reference/spatial-analyst/distance-accumulation.htm ArcGIS Pro - Distance Accumulation] * [https://pro.arcgis.com/en/pro-app/latest/tool-reference/spatial-analyst/path-distance.htm ArcGIS Pro - Path Distance] * [https://pro.arcgis.com/en/pro-app/latest/tool-reference/spatial-analyst/optimal-path-as-line.htm ArcGIS Pro - Optimal Path As Line] [[분류:GIS]] [[분류:공간분석]] [[분류:래스터분석]] [[분류:경로분석]] == 참고 문헌 == * 양정현, 2023, HGIS를 통해 본 조선 전기 양주의 도로 체계와 역사적 경로 재현 - 양주 회암사의 사례를 중심으로, 남도문화연구 50 * 양정현, 2024, 조선시대 도로 네트워크 분석 방법론과 사례 연구 - 양주의 사례를 중심으로, 문화역사지리 36-3 * 양정현, 2025, '신출귀몰'의 재구성 - 역사 연구와 GIS가 연결되는 한 방식, 역사비평 153 (발행 예정) == 메모 == * todo: 2차 및 3차 지형도의 도로 등급 반영 후 네트워크 데이터셋에 계층 속성 추가 == DB 변화 이력 == * 2025년 09월 03일 : 최초 공개 * 2025년 11월 14일 : '네트워크 데이터셋 기반 최소 비용 경로 분석' 항목 보완 및 '래스터 기반 최소 비용 경로 분석' 항목 추가
근대 교통로 DB
문서로 돌아갑니다.
둘러보기 메뉴
개인 도구
한국어
로그인
이름공간
문서
토론
한국어
보기
읽기
원본 보기
역사 보기
더 보기
검색
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
사이드메뉴
모든문서
위키문법예제
위키관리
도구
여기를 가리키는 문서
가리키는 글의 최근 바뀜
특수 문서 목록
문서 정보