728x90
저번 글에서 TSP 를 이용해서 순번을 만들었습니다.
https://tobee.tistory.com/entry/OSRM-vroom%EA%B3%BC-OSRM%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-TSP
이제 만들어진 이 순번을 이용해서 각각 지점별 경로를 생성해 보는 것을 해봐야 겠습니다.
위와 같이 TSP 가 나왔습니다.
nodejs 를 이용해서 만들어 보는 것으로 가닥을 잡아 보겠습니다.
1.경로 생성하기
우선 만들어진 output.json 파일을 이용해서 경로를 생성해야 합니다. 이를 route.json 으로 하겠습니다.
const axios = require('axios');
const fs = require('fs');
// OSRM 서버 URL
const osrmUrl = 'http://localhost:5000/route/v1/driving';
// VROOM output.json 경로
const outputJsonPath = 'output.json'; // 실제 경로로 변경
const routeJsonPath = 'route.json'; // 저장할 경로 설정
// OSRM 경로 요청 함수
async function getRouteFromOSRM(coords) {
const url = `${osrmUrl}/${coords.join(';')}?overview=full&geometries=geojson`;
try {
const response = await axios.get(url);
if (!response.data || !response.data.routes || response.data.routes.length === 0) {
console.error('OSRM 응답 데이터가 비어 있습니다.');
return null;
}
return response.data.routes[0]; // 첫 번째 경로 반환
} catch (error) {
console.error('OSRM 요청 실패:', error.message);
return null;
}
}
// VROOM output.json 처리 및 route.json 저장
async function processVroomOutput() {
try {
const data = JSON.parse(fs.readFileSync(outputJsonPath, 'utf8'));
if (!data.routes || data.routes.length === 0) {
console.error('VROOM output에 경로 정보가 없습니다.');
return;
}
const steps = data.routes[0].steps; // 첫 번째 경로의 steps 가져오기
const sequence = steps.map(step => step.location); // 좌표 추출
console.log('경로 계산 및 저장을 시작합니다...');
const routeData = [];
for (let i = 0; i < sequence.length - 1; i++) {
const coords = [sequence[i], sequence[i + 1]].map(loc => loc.join(','));
const route = await getRouteFromOSRM(coords);
if (route) {
routeData.push({
from: sequence[i],
to: sequence[i + 1],
distance: route.legs[0].distance,
duration: route.legs[0].duration,
geometry: route.geometry
});
}
}
// route.json 파일로 저장
fs.writeFileSync(routeJsonPath, JSON.stringify(routeData, null, 2));
console.log(`경로 데이터가 ${routeJsonPath}에 저장되었습니다.`);
} catch (error) {
console.error('Error processing VROOM output:', error.message);
}
}
// 실행
processVroomOutput();
위 자바스크립트 코드를 실행하기 위해서는 nodejs가 필요 합니다.
다음 파일을 이용해서 nodejs 를 만들었습니다.
node-v22.11.0-win-x64
그런 다음, 모듈을 하나 설치해 줍니다.
▶ 이때 주의 할 점은 아래 설치는 위 스크립크가 위치한 곳에 설치해야 한다는 것을 명심하십시오
npm install axios
그런 다음 경로 파일을 생성해 보겠습니다.
C:\DEV\GIS\OSRM_exec\TSP>node tsp_route_out_with_step.js
경로 계산 및 저장을 시작합니다...
경로 데이터가 route_step.json에 저장되었습니다.
2. 지도 위에 표시 result.json
그럼 leaflet 을 이용해서 지도 상에 표시하는 코드를 작성해 봅니다.
물론 Chat gpt 교수님이 하실 겁니다.
<!DOCTYPE html>
<html>
<head>
<title>OSRM Routes on Map</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
#map {
height: 100vh;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
// Leaflet 지도 초기화
const map = L.map('map').setView([37.497942, 127.027621], 13); // 강남구 중심 좌표
// OpenStreetMap 타일 레이어 추가
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
}).addTo(map);
// route.json 파일 로드
fetch('route.json')
.then(response => response.json())
.then(routeData => {
routeData.forEach(route => {
// GeoJSON 경로 추가
const geoJson = L.geoJSON(route.geometry, {
style: {
color: 'blue',
weight: 3,
opacity: 0.7
}
}).addTo(map);
// 출발점 마커 추가
L.marker([route.from[1], route.from[0]]).addTo(map);
// 도착점 마커 추가
L.marker([route.to[1], route.to[0]]).addTo(map);
});
// 지도 영역 설정
const bounds = L.latLngBounds(
routeData.flatMap(route => [
[route.from[1], route.from[0]],
[route.to[1], route.to[0]]
])
);
map.fitBounds(bounds);
})
.catch(err => console.error('Error loading route.json:', err));
</script>
</body>
</html>
3. 결과 확인
결과를 확인해 보겠습니다.
728x90
'프로그래밍 > GIS' 카테고리의 다른 글
[OSRM] Chat GPT와 함께하는 TSP - 마무리 (1) | 2024.12.06 |
---|---|
[OSRM] Chat GPT와 함께하는 TSP - 5 시각 정보 강화 (1) | 2024.12.05 |
[OSRM] Chat GPT와 함께하는 TSP - 3 (1) | 2024.12.03 |
vroom - Vehicle Routing Open-source Optimization Machine (0) | 2024.11.30 |
[OSRM] Chat GPT와 함께하는 TSP - 2 (2) | 2024.11.29 |