Skip to content

Instantly share code, notes, and snippets.

@m77so
Created July 24, 2018 06:52
Show Gist options
  • Save m77so/2c5a193f1222246a96a8c533d188eaa4 to your computer and use it in GitHub Desktop.
Save m77so/2c5a193f1222246a96a8c533d188eaa4 to your computer and use it in GitHub Desktop.
import { OutputJSON } from './dataInterface'
const fs = require('fs')
const iconv = require('iconv-lite')
const path = require('path')
if (process.argv.length - 2 !== 3) {
console.warn('The number of arguments is less or much.\n\nnode marsToTSV.js mars_sd.dat mars_nn.dat outputDir')
process.exit(100)
}
const marsSdDat = process.argv[2]
const marsNnDat = process.argv[3]
const outputDir = process.argv[4]
if (!fs.existsSync(marsSdDat)) {
console.warn(`mars_sd.dat file "${marsSdDat}" does not exist.`)
process.exit(100)
}
if (!fs.existsSync(marsNnDat)) {
console.warn(`mars_nn.dat file "${marsNnDat}" does not exist.`)
process.exit(100)
}
if (!(fs.existsSync(outputDir) && fs.statSync(outputDir).isDirectory())) {
console.warn(`output directory ${outputDir} does not exist.`)
process.exit(100)
}
const output: OutputJSON = {
lineNames: [],
stationNames: [],
lines: [],
stations: [],
cities: [],
appendixFare: {
JRHkansen: { km: [], fare: [] },
JRQkansen: { km: [], fare: [] },
JRSkansen: { km: [], fare: [] }
}
}
const dataSD = fs.readFileSync(marsSdDat)
/**
* 半角カタカナを全角ひらがなに変換
* https://qiita.com/hrdaya/items/291276a5a20971592216
* @param {String} str 変換したい文字列
*/
const hankana2zenkana = function(str: string) {
const kanaMap: { [key: string]: string } = {
ガ: 'が',
ギ: 'ぎ',
グ: 'ぐ',
ゲ: 'げ',
ゴ: 'ご',
ザ: 'ざ',
ジ: 'じ',
ズ: 'ず',
ゼ: 'ぜ',
ゾ: 'ぞ',
ダ: 'だ',
ヂ: 'ぢ',
ヅ: 'づ',
デ: 'で',
ド: 'ど',
バ: 'ば',
ビ: 'び',
ブ: 'ぶ',
ベ: 'べ',
ボ: 'ぼ',
パ: 'ぱ',
ピ: 'ぴ',
プ: 'ぷ',
ペ: 'ぺ',
ポ: 'ぽ',
: 'あ',
: 'い',
: 'う',
: 'え',
: 'お',
: 'か',
: 'き',
: 'く',
: 'け',
: 'こ',
: 'さ',
: 'し',
: 'す',
: 'せ',
ソ: 'そ',
: 'た',
: 'ち',
: 'つ',
: 'て',
: 'と',
: 'な',
: 'に',
: 'ぬ',
: 'ね',
: 'の',
: 'は',
: 'ひ',
: 'ふ',
: 'へ',
: 'ほ',
: 'ま',
: 'み',
: 'む',
: 'め',
: 'も',
: 'や',
: 'ゆ',
: 'よ',
: 'ら',
: 'り',
: 'る',
: 'れ',
: 'ろ',
: 'わ',
: 'を',
: 'ん',
: 'ぁ',
: 'ぃ',
: 'ぅ',
: 'ぇ',
: 'ぉ',
: 'っ',
: 'ゃ',
: 'ゅ',
: 'ょ',
'。': '。',
'、': '、',
: 'ー',
'「': '「',
'」': '」',
'・': '・'
}
const reg = new RegExp('(' + Object.keys(kanaMap).join('|') + ')', 'g')
return str
.replace(reg, match => kanaMap[match])
.replace(//g, '゛')
.replace(//g, '゜')
}
const recordsNumSD = dataSD.length / 28
for (let r = 0; r < recordsNumSD; ++r) {
const offset = 28 * r
let cur = offset
let record = []
record.push(dataSD.readUInt8(cur++))
record.push(dataSD.readInt16LE(cur++))
cur++
record.push(dataSD.readUInt8(cur++))
record.push(iconv.decode(dataSD.slice(cur, cur + 14), 'cp932').replace(/ /g, ''))
cur += 15
record.push(iconv.decode(dataSD.slice(cur, cur + 9), 'cp932').replace(/ /g, ''))
if (!output.lines[record[0]]) {
output.lines[record[0]] = {
id: record[0],
name: record[3],
kana: hankana2zenkana(record[4]),
src: '',
dest: '',
stations: [],
stationIds: [],
kms: [],
akms: [],
dupLineStationIds: [],
chiho: false,
shinkansen: record[3].indexOf('新幹線') > -1,
company: [],
mapZairai: []
}
output.lineNames[record[0]] = record[3]
} else if (record[0] > 0) {
if (output.stationNames.includes(record[3])) {
const id = output.stationNames.indexOf(record[3])
output.stations[id].lineIds.push(record[0])
const lineIds = output.stations[id].lineIds
for (let lineId of lineIds) {
if (!output.lines[lineId].dupLineStationIds.includes(id)) {
output.lines[lineId].dupLineStationIds.push(id)
}
}
} else {
const nextId = output.stations.length
output.stations.push({
id: nextId,
name: record[3],
kana: hankana2zenkana(record[4]),
lineIds: [record[0]],
company: [],
city: -1
})
output.stationNames.push(record[3])
}
const line = output.lines[record[0]]
const stationId = output.stationNames.indexOf(record[3])
line.stations.push(record[3])
line.kms.push(record[1])
line.stationIds.push(stationId)
}
}
const dataNN = fs.readFileSync(marsNnDat)
const recordsNum = dataNN.length / 8
for (let r = 0; r < recordsNum; ++r) {
const offset = 8 * r
let cur = offset
let record = []
record.push(dataNN.readInt16LE(cur))
cur += 2
record.push(dataNN.readInt16LE(cur))
cur += 2
record.push(dataNN.readInt16LE(cur))
cur += 2
record.push(dataNN.readInt16LE(cur))
const id = output.lines[record[0]].kms.indexOf(record[1])
output.lines[record[0]].akms[id] = record[2]
}
for (let line of output.lines) {
const index = [...Array(line.stations.length).keys()].sort((a, b) => line.kms[a] - line.kms[b])
const kms = index.map(i => line.kms[i])
const stations = index.map(i => line.stations[i]) || ['']
const stationIds = index.map(i => line.stationIds[i]) || [-1]
const akms = index.map(i => line.akms[i] || 0)
line.kms = kms
line.stations = stations
line.stationIds = stationIds
line.akms = akms
line.src = stations[0]
line.dest = stations[stations.length - 1]
}
fs.writeFileSync(
path.join(outputDir, 'stations.tsv'),
output.stations.map(s => [s.id, s.name, s.kana].join('\t')).join('\n')
)
fs.writeFileSync(path.join(outputDir, 'lines.tsv'), output.lines.map(s => [s.id, s.name, s.kana].join('\t')).join('\n'))
let distanceArr = []
for (let l of output.lines) {
for (let i = 0; i < l.stationIds.length; ++i) {
distanceArr.push([l.id, l.stationIds[i], l.kms[i], l.akms[i]].join('\t'))
}
}
fs.writeFileSync(path.join(outputDir, 'distances.tsv'), distanceArr.join('\n'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment