mirror of
https://github.com/morgan9e/KorailMap
synced 2026-04-15 00:44:13 +09:00
init
This commit is contained in:
289
index.html
Normal file
289
index.html
Normal file
@@ -0,0 +1,289 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Korail GIS</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""/>
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||
crossorigin=""></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
#map {
|
||||
height: calc(100vh - 60px);
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.station-label {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.train-marker {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bottombar {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.bottombar .left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bottombar .left input[type="checkbox"] {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.bottombar .right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bottombar .loading {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
#reloadTrains {
|
||||
padding: 5px 10px;
|
||||
background-color: #007BFF;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#reloadTrains:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<div class="bottombar">
|
||||
<div class="left">
|
||||
<input type="checkbox" id="layer0"> Express
|
||||
<input type="checkbox" id="layer1"> Semi
|
||||
<input type="checkbox" id="layer2"> Normal
|
||||
<input type="checkbox" id="layer3"> Passenger
|
||||
<input type="checkbox" id="layer4"> Subway
|
||||
<input type="checkbox" id="layer5"> Logis
|
||||
</div>
|
||||
<div class="right">
|
||||
<span class="loading" id="loading">Loading...</span>
|
||||
<button id="reloadTrains">Reload</button>
|
||||
<input type="checkbox" id="autoReload"> Auto
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
async function myFetch(url, options = {}) {
|
||||
let headers = options.headers
|
||||
let f = fetch('https://proxy.devpg.net', {
|
||||
headers: {
|
||||
'X-Proxy-URL': url,
|
||||
'X-Proxy-Header': JSON.stringify(headers),
|
||||
'X-Proxy-Cache': '0'
|
||||
}
|
||||
});
|
||||
console.log(`fetch(${url}, headers=${JSON.stringify(headers)}`, f);
|
||||
return f
|
||||
}
|
||||
|
||||
const trainAPI = 'https://gis.korail.com/api/train?bbox=120.6263671875,28.07910949377748,134.0736328125,45.094739803960664'
|
||||
|
||||
const server = ''
|
||||
const map = L.map('map').setView([36.5, 128], 7.5);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
const railLayers = {
|
||||
express: L.layerGroup().addTo(map),
|
||||
normal: L.layerGroup().addTo(map),
|
||||
semi: L.layerGroup().addTo(map),
|
||||
logis: L.layerGroup().addTo(map)
|
||||
};
|
||||
|
||||
const stationLayers = [];
|
||||
|
||||
for (let i = 0; i < 64; i++) {
|
||||
const layerGroup = L.layerGroup().addTo(map);
|
||||
stationLayers.push(layerGroup);
|
||||
}
|
||||
|
||||
for (let layer of stationLayers) {
|
||||
map.removeLayer(layer);
|
||||
}
|
||||
|
||||
const trainLayer = L.layerGroup().addTo(map);
|
||||
|
||||
function startSpinner() {
|
||||
document.getElementById("loading").classList.remove("hidden");
|
||||
}
|
||||
function clearSpinner() {
|
||||
document.getElementById("loading").classList.add("hidden");
|
||||
}
|
||||
|
||||
function loadRail(type) {
|
||||
fetch(`${server}/api/rail/${type}`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Network response was not ok ${response.statusText}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
L.geoJSON(data, {
|
||||
style: {
|
||||
color: type === 'express' ? 'blue' : type === 'normal' ? 'green' : type === 'semi' ? 'orange' : 'red'
|
||||
}
|
||||
}).addTo(railLayers[type]);
|
||||
})
|
||||
.catch(error => console.error(`Error fetching ${type} rail data: `, error));
|
||||
}
|
||||
|
||||
function loadStations() {
|
||||
fetch(`${server}/api/station`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
L.geoJSON(data, {
|
||||
pointToLayer: function (feature, latlng) {
|
||||
const shownLayer = parseInt(feature.properties.shown_layer.slice(2), 2);
|
||||
|
||||
const marker = L.marker(latlng, {
|
||||
icon: L.divIcon({
|
||||
className: 'station-label',
|
||||
html: `<div>${feature.properties.name}</div>`,
|
||||
iconSize: [100, 0]
|
||||
})
|
||||
});
|
||||
if (stationLayers[shownLayer]) {
|
||||
stationLayers[shownLayer].addLayer(marker);
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(error => console.error('Error fetching station data: ', error));
|
||||
}
|
||||
|
||||
function loadTrains() {
|
||||
startSpinner();
|
||||
myFetch(trainAPI, {
|
||||
headers: {
|
||||
"x-requested-with": "com.korail.talk",
|
||||
"referer": "https://gis.korail.com/korailTalk/entrance",
|
||||
"user-agent": "korailtalk AppVersion/6.3.3"
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
trainLayer.clearLayers();
|
||||
|
||||
L.geoJSON(data, {
|
||||
pointToLayer: function (feature, latlng) {
|
||||
const trainIconHtml = `
|
||||
<div style="position: relative; text-align: center;">
|
||||
<div style="background-color: #007bff;
|
||||
border-radius: 50%;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
border: 2px solid white;"></div>
|
||||
<div style="font-size: 12px;
|
||||
color: black;
|
||||
background-color: white;
|
||||
border: 1px solid black;
|
||||
margin-top: 2px;
|
||||
padding: 1px 3px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
white-space: nowrap;">${feature.properties.trn_case} ${feature.properties.trn_no}</div>
|
||||
</div>`;
|
||||
return L.marker(latlng, {
|
||||
icon: L.divIcon({
|
||||
className: 'train-marker',
|
||||
html: trainIconHtml,
|
||||
iconSize: [30, 42],
|
||||
iconAnchor: [15, 21]
|
||||
})
|
||||
}).bindPopup(`${feature.properties.trn_case} ${feature.properties.trn_no}<br>
|
||||
(${feature.properties.dpt_stn_nm} -> ${feature.properties.arv_stn_nm})<br>
|
||||
${feature.properties.now_stn} ${feature.properties.next_stn}`);
|
||||
}
|
||||
}).addTo(trainLayer);
|
||||
clearSpinner();
|
||||
})
|
||||
.catch(error => console.error('Error fetching train data: ', error));
|
||||
}
|
||||
|
||||
loadRail('express');
|
||||
loadRail('normal');
|
||||
loadRail('semi');
|
||||
loadRail('logis');
|
||||
|
||||
|
||||
for (let f = 0; f < 6; f++) {
|
||||
document.getElementById(`layer${f}`).addEventListener('change', function () { // lable0: 0b 1XXXXX, label1: 0bX1XXXX, ...
|
||||
for (let i = 0; i < 64; i++) {
|
||||
if ( i & (1 << (5 - 0)) ) {
|
||||
if (this.checked) {
|
||||
map.addLayer(stationLayers[i]);
|
||||
} else {
|
||||
map.removeLayer(stationLayers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
document.getElementById('reloadTrains').addEventListener('click', loadTrains);
|
||||
document.getElementById('autoReload').addEventListener('click', autoReload);
|
||||
|
||||
let reloadInterval = null
|
||||
function autoReload() {
|
||||
if (this.checked) {
|
||||
reloadInterval = setInterval(loadTrains, 2000);
|
||||
}
|
||||
else {
|
||||
if (reloadInterval) {
|
||||
clearInterval(reloadInterval);
|
||||
reloadInterval = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
loadStations();
|
||||
loadTrains();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user