Initial Commit

Signed-off-by: Pascal Syma <pascal@syma.dev>
This commit is contained in:
2020-10-01 22:19:17 +02:00
commit d6dea5cbf2
19 changed files with 11505 additions and 0 deletions
+205
View File
@@ -0,0 +1,205 @@
# Created by https://www.toptal.com/developers/gitignore/api/webstorm+all,node
# Edit at https://www.toptal.com/developers/gitignore?templates=webstorm+all,node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
### WebStorm+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### WebStorm+all Patch ###
# Ignores the whole .idea folder and all .iml files
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
.idea/
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
*.iml
modules.xml
.idea/misc.xml
*.ipr
# Sonarlint plugin
.idea/sonarlint
# End of https://www.toptal.com/developers/gitignore/api/webstorm+all,node
dist/
+173
View File
@@ -0,0 +1,173 @@
<!--
~ Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
~ All rights reserved.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Editor</title>
<style>
body {
margin: 0;
height: 0;
user-select: none; /* standard syntax */
-webkit-user-select: none; /* webkit (safari, chrome) browsers */
-moz-user-select: none; /* mozilla browsers */
-khtml-user-select: none; /* webkit (konqueror) browsers */
-ms-user-select: none; /* IE10+ */
}
div {
position: fixed;
right: 0;
margin: 8px;
text-align: right;
}
</style>
</head>
<body>
<div>
<table id="stops">
<thead>
<tr>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<label><textarea id="inp" rows="3"></textarea></label>
</div>
<canvas id="canvas"></canvas>
<script>
Number.prototype.mod = function (n) {
return ((this % n) + n) % n;
};
let stops = [];
let i = 0;
let canvas = document.getElementById("canvas");
canvas.focus()
let ctx = canvas.getContext("2d");
let tbl = document.getElementById("stops");
let inp = document.getElementById("inp");
inp.addEventListener('input', () => {
if (inp.value === null || inp.value === '')
return;
stops = inp.value.split('\n').map(l => {
return {
name: l,
x: null,
y: null
}
})
inp.value = ''
i = 0;
canvas.focus();
draw()
})
let map = new Image();
map.onload = () => {
canvas.width = map.width;
canvas.height = map.height
draw()
canvas.addEventListener('contextmenu', ev => {
// right
ev.preventDefault();
stops.splice(i, 0, {
name: null,
x: ev.offsetX,
y: ev.offsetY
})
i = (i + 1).mod(stops.length)
draw();
return false;
}, false);
canvas.addEventListener('click', ev => {
// left
ev.preventDefault();
stops[i].x = ev.offsetX
stops[i].y = ev.offsetY
i = (i + 1).mod(stops.length)
draw();
return false;
}, false);
document.addEventListener('keydown', e => {
if (e.which === 38) {
// up
i = (i - 1).mod(stops.length)
draw()
e.preventDefault()
} else if (e.which === 40) {
// down
i = (i + 1).mod(stops.length)
draw()
e.preventDefault()
} else if (e.which === 13) {
// enter
let output = stops.map(s => `${s.x},${s.y}` + (s.name ? `,,${s.name}` : '')).join('\n')
console.log(output)
}
})
}
map.src = "map.png";
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(map, 0, 0)
tbl.getElementsByTagName('tbody')[0].innerHTML = "";
let last = null;
stops.forEach((s, index) => {
const tr = document.createElement('tr');
const tdName = document.createElement('td');
tdName.innerText = s.name ? s.name : '-';
const tdI = document.createElement('td');
if (index === i)
tdI.innerText = '<';
tr.append(tdName, tdI);
tbl.getElementsByTagName('tbody')[0].append(tr)
if (s.y === null && s.x === null)
return;
if (s.name !== null) {
ctx.beginPath()
ctx.arc(s.x, s.y, 5, 0, 2 * Math.PI);
ctx.lineWidth = 1;
ctx.strokeStyle = index === i ? '#f00' : '#000'
ctx.stroke()
ctx.closePath()
ctx.fillStyle = '#000'
ctx.textAlign = "center";
ctx.fillText(s.name, s.x, s.y - 10);
}
if (last) {
ctx.beginPath()
ctx.moveTo(last.x, last.y)
ctx.lineWidth = 3;
ctx.lineTo(s.x, s.y)
ctx.strokeStyle = '#000'
ctx.stroke()
ctx.closePath()
}
last = s;
})
}
</script>
</body>
</html>
+72
View File
@@ -0,0 +1,72 @@
<!--
~ Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
~ All rights reserved.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
height: 0;
}
#buttons {
position: fixed;
margin: 8px;
}
#settings {
position: fixed;
margin: 8px;
right: 0;
bottom: 0;
}
#bus {
position: fixed;
right: 0;
margin: 8px;
text-align: center;
}
button {
width: 30px;
height: 30px;
}
</style>
</head>
<body>
<div id="buttons">
<button id="minus">-1</button>
<button id="play">></button>
<button id="real">></button>
<button id="plus">+1</button>
<button disabled id="display" style="width: 70px">00:00</button>
</div>
<table id="bus">
<thead>
<tr>
<th style="width: 200px">Next Stop</th>
<th>Line</th>
<th>Offset</th>
<th>Delay</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="settings">
<label style="display: grid">
<input id="mpm" max="10000" min="1" type="number" value="180"> Minutes per Minute
</label>
<label>
<input id="showMap" type="checkbox"> Show Map?
</label>
</div>
<canvas id="canvas"></canvas>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+10198
View File
File diff suppressed because it is too large Load Diff
+34
View File
@@ -0,0 +1,34 @@
{
"name": "realtime-oepnv-tracker",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack/prod.js",
"start": "webpack-dev-server --config webpack/base.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"csv-loader": "^3.0.3",
"favicons-webpack-plugin": "^4.2.0",
"file-loader": "^6.1.0",
"html-webpack-plugin": "^4.5.0",
"raw-loader": "^4.0.1",
"source-map": "^0.7.3",
"terser-webpack-plugin": "^4.2.2",
"ts-loader": "^8.0.4",
"typescript": "^4.0.3",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^5.1.4",
"workbox-webpack-plugin": "^5.1.4"
}
}
+76
View File
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
import Line from "./Line";
import Coordinate from "./Coordinate";
export default class Bus {
readonly offset: number;
readonly line: Line;
public delay: number = 0;
public td: HTMLTableDataCellElement;
constructor(line: Line, offset: number = 0) {
this.line = line;
this.offset = offset
}
draw(ctx: CanvasRenderingContext2D, s: number) {
// @ts-ignore
const progress = (this.offset + s - this.delay).mod(this.line.duration);
let position = this.getCurrentPosition(progress);
ctx.beginPath()
if (this.delay === 0)
ctx.fillStyle = '#0f0'
else if (this.delay > 0 && this.delay < 5)
ctx.fillStyle = '#ff0'
else {
ctx.fillStyle = '#f00'
ctx.fillText("+" + this.delay, position.x, position.y - 3);
}
ctx.arc(position.x, position.y, 3, 0, 2 * Math.PI);
ctx.fill()
ctx.closePath()
if (this.td)
this.td.innerText = this.getNextStop(progress);
}
public getNextStop(progress: number = 0): string {
let br = 0
for (; br < this.line.stopBreaks.length && progress > this.line.stopBreaks[br]; br++) {
}
return this.line.stops[br].name;
}
public getCurrentPosition(progress: number = 0): Coordinate {
let br = 0
for (; br < this.line.breaks.length && progress > this.line.breaks[br]; br++) {
}
let top = this.line.coords[br];
// @ts-ignore
let bottomBr = (br - 1).mod(this.line.breaks.length);
let bottom = this.line.coords[bottomBr];
if (progress < this.line.breaks[0])
return this.line.coords[0];
if (!bottom) {
return top;
}
let percentToBr = (progress - this.line.breaks[bottomBr]) / (this.line.breaks[br] - this.line.breaks[bottomBr]);
return new Coordinate(
bottom.x + percentToBr * (top.x - bottom.x),
bottom.y + percentToBr * (top.y - bottom.y)
)
}
}
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
export default class Coordinate {
readonly x: number;
readonly y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
distance(other: Coordinate): number {
if (this.equals(other))
return 0;
if (!other)
return 0;
return Math.sqrt(Math.pow(other.x - this.x, 2) + Math.pow(other.y - this.y, 2))
}
equals(other: Coordinate = null): boolean {
if (!other)
return false;
return this.x === other.x && this.y === other.y;
}
}
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
import Stop from "./Stop";
import Coordinate from "./Coordinate";
export default class Line {
readonly name: String;
readonly stops: Stop[] = [];
readonly breaks: number[] = [];
readonly stopBreaks: number[] = [];
readonly duration: number = 0;
readonly coords: Coordinate[];
readonly color: string = '#000';
constructor(name: String, stops: string, color: string) {
this.color = color
this.name = name;
let coords = stops.split("\n").map(e => {
let a = e.split(',');
return a.length > 2 ? new Stop(Number.parseFloat(a[0]), Number.parseFloat(a[1]), Number.parseFloat(a[2]), a[3]) : new Coordinate(Number.parseFloat(a[0]), Number.parseFloat(a[1]));
});
this.coords = coords;
let lastStop = <Stop>coords[0];
let length = 0;
let breaks: number[] = [];
for (let i = 0; i < coords.length; i++) {
if (coords[i] instanceof Stop) {
let stop = <Stop>coords[i];
this.stops.push(stop)
this.stopBreaks.push(stop.minute)
const td = stop.minute - lastStop.minute
if (coords[i - 1])
length += coords[i - 1].distance(stop)
breaks.map(e => lastStop.minute + (e / length) * td).forEach(e => this.breaks.push(e));
this.breaks.push(stop.minute)
length = 0;
breaks = [];
lastStop = stop
} else {
let len = coords[i - 1].distance(coords[i]);
length += len;
breaks.push(length)
}
}
this.duration = lastStop.minute
}
draw(ctx: CanvasRenderingContext2D) {
let last: Coordinate = null;
this.coords.forEach(c => {
ctx.beginPath()
ctx.textAlign = "center";
if (c instanceof Stop) {
let stop: Stop = c;
ctx.arc(c.x, c.y, 5, 0, 2 * Math.PI);
ctx.strokeStyle = this.color
ctx.fillStyle = '#000'
ctx.fillText(stop.name, c.x, c.y - 10);
}
ctx.stroke()
ctx.closePath()
if (last) {
ctx.beginPath()
ctx.moveTo(last.x, last.y)
ctx.lineWidth = 3;
ctx.lineTo(c.x, c.y)
ctx.strokeStyle = this.color
ctx.stroke()
ctx.closePath()
}
last = c;
})
}
}
+17
View File
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
import Coordinate from "./Coordinate";
export default class Stop extends Coordinate {
readonly name: string;
readonly minute: number;
constructor(x: number, y: number, minute: number, name: string) {
super(x, y);
this.minute = minute;
this.name = name;
}
}
+175
View File
@@ -0,0 +1,175 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
Number.prototype.mod = function (n) {
return ((this % n) + n) % n;
};
import mapSrc from "../map.png";
import Bus from "./Bus";
import Line from "./Line";
import stops201 from './lines/201.csv';
import stops204 from './lines/204.csv';
import stops205 from './lines/205.csv';
import stops206 from './lines/206.csv';
let line201 = new Line("201", stops201, '#fbce18');
let line204 = new Line("204", stops204, '#99207e');
let line205 = new Line("205", stops205, '#009fe3');
let line206 = new Line("206", stops206, '#1c60b2');
console.log(line201);
let canvas = document.getElementById("canvas");
let btnMinus = document.getElementById("minus");
let btnPlay = document.getElementById("play");
let btnReal = document.getElementById("real");
let btnPlus = document.getElementById("plus");
let btnDisplay = document.getElementById("display");
let tblBus = document.getElementById("bus");
let chkMap = document.getElementById("showMap");
let inpMpm = document.getElementById("mpm");
chkMap.addEventListener('change', () => run(0));
inpMpm.addEventListener('change', () => mpm = parseInt(inpMpm.value))
let ctx = canvas.getContext("2d");
let map = new Image();
map.onload = () => {
canvas.width = map.width;
canvas.height = map.height
run(0)
}
map.src = mapSrc;
let isRunning = false;
let realIsRunning = false;
let interval;
let progress = 0;
let mpm = parseInt(inpMpm.value);
let busses = [
new Bus(line201),
new Bus(line201, 30),
new Bus(line201, 60),
new Bus(line201, 90),
new Bus(line204),
new Bus(line204, 30),
new Bus(line204, 60),
new Bus(line204, 90),
new Bus(line205),
new Bus(line205, 30),
new Bus(line205, 60),
new Bus(line206),
new Bus(line206, 30),
new Bus(line206, 60),
];
busses.forEach(b => {
const tr = document.createElement('tr');
const tdNext = document.createElement('td');
b.td = tdNext;
const tdLine = document.createElement('td');
tdLine.innerText = b.line.name
const tdOffset = document.createElement('td');
tdOffset.innerText = b.offset.toString()
const tdDelay = document.createElement('td');
const inputDelay = document.createElement('input')
inputDelay.type = 'number'
inputDelay.min = '0'
inputDelay.max = '120'
inputDelay.value = b.delay.toString()
inputDelay.addEventListener('change', () => b.delay = parseInt(inputDelay.value))
tdDelay.append(inputDelay)
tr.append(tdNext, tdLine, tdOffset, tdDelay);
tblBus.getElementsByTagName('tbody')[0].append(tr)
})
function run(s) {
if (s instanceof Date) {
const hours = s.getHours()
const minutes = s.getMinutes();
const seconds = s.getSeconds();
progress = (60 * hours) + minutes + (seconds / 60);
} else
progress += s;
const mprogress = progress.mod(60);
const hours = Math.floor(progress / 60);
const minutes = Math.floor(mprogress);
const seconds = Math.floor((mprogress * 60).mod(60))
btnDisplay.innerText = (hours > 9 ? hours : "0" + hours) + ":" + (minutes > 9 ? minutes : "0" + minutes) + ":" + (seconds > 9 ? seconds : "0" + seconds)
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (chkMap.checked)
ctx.drawImage(map, 0, 0)
else {
line201.draw(ctx)
line204.draw(ctx)
line205.draw(ctx)
line206.draw(ctx)
}
busses.forEach(b => b.draw(ctx, progress))
}
btnMinus.addEventListener('click', () => {
run(-1);
})
btnPlus.addEventListener('click', () => {
run(1);
})
btnPlay.addEventListener('click', () => {
if (realIsRunning) {
clearInterval(interval)
btnReal.innerText = '>'
realIsRunning = false
}
if (isRunning) {
clearInterval(interval)
btnPlay.innerText = '>'
} else {
interval = setInterval(() => {
run(mpm / 600);
}, 100)
btnPlay.innerText = '||'
}
isRunning = !isRunning;
})
btnReal.addEventListener('click', () => {
if (isRunning) {
clearInterval(interval)
btnPlay.innerText = '>'
isRunning = false
}
if (realIsRunning) {
clearInterval(interval)
btnReal.innerText = '>'
} else {
interval = setInterval(() => {
run(new Date());
}, 100)
btnReal.innerText = '||'
}
realIsRunning = !realIsRunning;
})
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./service-worker.js').catch(() => {
}).then();
});
}
+97
View File
@@ -0,0 +1,97 @@
1567,455,11,Roland-Center
1553,448
1558,431
1559,408,12,Obervielander Str.
1569,391
1566,364
1553,351,13,Carl-Hurtzig-Str.
1517,303,14,Zum Huchtinger Bhf.
1455,310,15,Harriersand
1386,325,16,Mittelshuchtinger Dorfstr.
1337,332,16,Brüsseler Str.
1261,335,17,Varrelgraben
1135,338
1099,332,19,Kleiner Tannenweg
1023,324,20,Bahnhof Heidkrug
972,346,21,Sommerweg
927,370,22,Masurenstr.
892,386,22,Tannenbergstr.
845,383,23,Feldstr.
794,380,23,Hamburger Weg
731,379,24,Am Fuhrenkamp
693,382,25,Syker Str.
685,372
682,349
663,339
652,341,27,Otto-Jenzok-Str.
638,345
640,358
624,359
627,367,28,Museum
529,410,33,Bahnhof / ZOB
529,410,39,Bahnhof / ZOB
501,431,40,Post
503,443,43,Markt
553,491,45,Parkstr.
581,492,47,Arthur-Fitger-Str.
612,507,48,Uferweg
658,574,49,Karlsbader Str.
690,617,50,Amundsenstr.
725,662,51,Schollendamm
762,715,52,Riedeweg
793,746,53,Helgolandstr.
766,777,53,Nachtigalstr.
739,808,54,Wissmannstr.
724,819,55,Bahnhof Annenheide
703,864,56,Steller Str.
689,915,57,Annenheide
689,915,60,Annenheide
714,947
742,920,61,Feldhusstr.
748,907
703,864,62,Steller Str.
724,819,63,Bahnhof Annenheide
739,808,64,Wissmannstr.
793,746,65,Helgolandstr.
762,715,66,Riedeweg
725,662,67,Schollendamm
690,617,68,Amundsenstr.
658,574,69,Karlsbader Str.
612,507,70,Uferweg
581,492,71,Arthur-Fitger-Str.
553,491,73,Parkstr.
503,443,74,Markt
501,431,75,Post
529,410,78,Bahnhof / ZOB
529,410,84,Bahnhof / ZOB
627,367,87,Museum
624,359
640,358
638,345
652,341,88,Otto-Jenzok-Str.
663,339
682,349
685,372
693,382,89,Syker Str.
731,379,91,Am Fuhrenkamp
794,380,91,Hamburger Weg
845,383,92,Feldstr.
892,386,93,Tannenbergstr.
927,370,94,Masurenstr.
972,346,95,Sommerweg
1023,324,96,Bahnhof Heidkrug
1099,332,97,Kleiner Tannenweg
1135,338
1261,335,98,Varrelgraben
1337,332,99,Brüsseler Str.
1386,325,100,Mittelshuchtinger Dorfstr.
1455,310,101,Harriersand
1517,303,101,Zum Huchtinger Bhf.
1553,351,102,Carl-Hurtzig-Str.
1566,364
1569,391
1559,408,103,Obervielander Str.
1558,431
1553,448
1567,455,106,Roland-Center
1567,455,120,Roland-Center
1 1567,455,11,Roland-Center
2 1553,448
3 1558,431
4 1559,408,12,Obervielander Str.
5 1569,391
6 1566,364
7 1553,351,13,Carl-Hurtzig-Str.
8 1517,303,14,Zum Huchtinger Bhf.
9 1455,310,15,Harriersand
10 1386,325,16,Mittelshuchtinger Dorfstr.
11 1337,332,16,Brüsseler Str.
12 1261,335,17,Varrelgraben
13 1135,338
14 1099,332,19,Kleiner Tannenweg
15 1023,324,20,Bahnhof Heidkrug
16 972,346,21,Sommerweg
17 927,370,22,Masurenstr.
18 892,386,22,Tannenbergstr.
19 845,383,23,Feldstr.
20 794,380,23,Hamburger Weg
21 731,379,24,Am Fuhrenkamp
22 693,382,25,Syker Str.
23 685,372
24 682,349
25 663,339
26 652,341,27,Otto-Jenzok-Str.
27 638,345
28 640,358
29 624,359
30 627,367,28,Museum
31 529,410,33,Bahnhof / ZOB
32 529,410,39,Bahnhof / ZOB
33 501,431,40,Post
34 503,443,43,Markt
35 553,491,45,Parkstr.
36 581,492,47,Arthur-Fitger-Str.
37 612,507,48,Uferweg
38 658,574,49,Karlsbader Str.
39 690,617,50,Amundsenstr.
40 725,662,51,Schollendamm
41 762,715,52,Riedeweg
42 793,746,53,Helgolandstr.
43 766,777,53,Nachtigalstr.
44 739,808,54,Wissmannstr.
45 724,819,55,Bahnhof Annenheide
46 703,864,56,Steller Str.
47 689,915,57,Annenheide
48 689,915,60,Annenheide
49 714,947
50 742,920,61,Feldhusstr.
51 748,907
52 703,864,62,Steller Str.
53 724,819,63,Bahnhof Annenheide
54 739,808,64,Wissmannstr.
55 793,746,65,Helgolandstr.
56 762,715,66,Riedeweg
57 725,662,67,Schollendamm
58 690,617,68,Amundsenstr.
59 658,574,69,Karlsbader Str.
60 612,507,70,Uferweg
61 581,492,71,Arthur-Fitger-Str.
62 553,491,73,Parkstr.
63 503,443,74,Markt
64 501,431,75,Post
65 529,410,78,Bahnhof / ZOB
66 529,410,84,Bahnhof / ZOB
67 627,367,87,Museum
68 624,359
69 640,358
70 638,345
71 652,341,88,Otto-Jenzok-Str.
72 663,339
73 682,349
74 685,372
75 693,382,89,Syker Str.
76 731,379,91,Am Fuhrenkamp
77 794,380,91,Hamburger Weg
78 845,383,92,Feldstr.
79 892,386,93,Tannenbergstr.
80 927,370,94,Masurenstr.
81 972,346,95,Sommerweg
82 1023,324,96,Bahnhof Heidkrug
83 1099,332,97,Kleiner Tannenweg
84 1135,338
85 1261,335,98,Varrelgraben
86 1337,332,99,Brüsseler Str.
87 1386,325,100,Mittelshuchtinger Dorfstr.
88 1455,310,101,Harriersand
89 1517,303,101,Zum Huchtinger Bhf.
90 1553,351,102,Carl-Hurtzig-Str.
91 1566,364
92 1569,391
93 1559,408,103,Obervielander Str.
94 1558,431
95 1553,448
96 1567,455,106,Roland-Center
97 1567,455,120,Roland-Center
+81
View File
@@ -0,0 +1,81 @@
1567,455,23,Roland-Center
1542,478,24,Willakedamm
1525,509,24,Hohenhorster Weg
1473,575,25,Rotterdamer Str.
1457,600,26,Friedhof Huchting
1441,637,28,Varreler Landstr.
1419,631,28,Henstedter Str.
1341,606,29,Meenheit
1284,642,30,Grüne Str.
1188,682,32,Schulstr.
1106,675,33,Johann-Eilers-Weg
1040,661,34,Mühle Unger
992,597,35,Pultern
922,513,37,Langenwischstr.
882,488,38,An der Riede
826,457,39,Kieler Weg
784,437,40,Lüneburger Str.
759,422,41,Leipziger Weg
728,405,41,Pestalozziweg
694,384,43,Syker Str.
623,399,44,Heinrichstr.
530,409,48,Bahnhof / ZOB
530,409,54,Bahnhof / ZOB
506,429,55,Post
506,441,58,Markt
555,489,60,Parkstr.
582,536,62,Max-Planck-Str.
588,572,63,Breslauer Str.
540,617,64,Lethestr.
506,641,64,Elbinger Str.
467,696,65,Brendelweg
495,718,66,Ziethenweg
474,755,66,Graf-von-Galen-Str.
447,800,67,Könzgenstr.
428,825,68,Letterhausstr.
376,830,69,Schlutterdamm
327,937,70,Holzkamper Damm
332,1036,71,Abernettistr.
293,1055,72,Boelckestr.
254,1075,73,Adelheide Kaserne
254,1075,74,Adelheide Kaserne
293,1055,75,Boelckestr.
332,1036,76,Abernettistr.
327,937,77,Holzkamper Damm
376,830,78,Schlutterdamm
428,825,79,Letterhausstr.
447,800,80,Könzgenstr.
474,755,81,Graf-von-Galen-Str.
495,718,81,Ziethenweg
467,696,83,Brendelweg
506,641,83,Elbinger Str.
540,617,84,Lethestr.
588,572,85,Breslauer Str.
582,536,87,Max-Planck-Str.
555,489,88,Parkstr.
506,441,89,Markt
506,429,90,Post
530,409,93,Bahnhof / ZOB
530,409,99,Bahnhof / ZOB
623,399,101,Heinrichstr.
694,384,102,Syker Str.
728,405,103,Pestalozziweg
759,422,104,Leipziger Weg
784,437,105,Lüneburger Str.
826,457,106,Kieler Weg
882,488,106,An der Riede
922,513,107,Langenwischstr.
992,597,109,Pultern
1040,661,110,Mühle Unger
1106,675,111,Johann-Eilers-Weg
1188,682,112,Schulstr.
1284,642,114,Grüne Str.
1341,606,115,Meenheit
1419,631,116,Henstedter Str.
1441,637,117,Varreler Landstr.
1457,600,118,Friedhof Huchting
1473,575,119,Rotterdamer Str.
1525,509,120,Hohenhorster Weg
1542,478,121,Willakedamm
1567,455,124,Roland-Center
1567,455,150,Roland-Center
1 1567 455 23 Roland-Center
2 1542 478 24 Willakedamm
3 1525 509 24 Hohenhorster Weg
4 1473 575 25 Rotterdamer Str.
5 1457 600 26 Friedhof Huchting
6 1441 637 28 Varreler Landstr.
7 1419 631 28 Henstedter Str.
8 1341 606 29 Meenheit
9 1284 642 30 Grüne Str.
10 1188 682 32 Schulstr.
11 1106 675 33 Johann-Eilers-Weg
12 1040 661 34 Mühle Unger
13 992 597 35 Pultern
14 922 513 37 Langenwischstr.
15 882 488 38 An der Riede
16 826 457 39 Kieler Weg
17 784 437 40 Lüneburger Str.
18 759 422 41 Leipziger Weg
19 728 405 41 Pestalozziweg
20 694 384 43 Syker Str.
21 623 399 44 Heinrichstr.
22 530 409 48 Bahnhof / ZOB
23 530 409 54 Bahnhof / ZOB
24 506 429 55 Post
25 506 441 58 Markt
26 555 489 60 Parkstr.
27 582 536 62 Max-Planck-Str.
28 588 572 63 Breslauer Str.
29 540 617 64 Lethestr.
30 506 641 64 Elbinger Str.
31 467 696 65 Brendelweg
32 495 718 66 Ziethenweg
33 474 755 66 Graf-von-Galen-Str.
34 447 800 67 Könzgenstr.
35 428 825 68 Letterhausstr.
36 376 830 69 Schlutterdamm
37 327 937 70 Holzkamper Damm
38 332 1036 71 Abernettistr.
39 293 1055 72 Boelckestr.
40 254 1075 73 Adelheide Kaserne
41 254 1075 74 Adelheide Kaserne
42 293 1055 75 Boelckestr.
43 332 1036 76 Abernettistr.
44 327 937 77 Holzkamper Damm
45 376 830 78 Schlutterdamm
46 428 825 79 Letterhausstr.
47 447 800 80 Könzgenstr.
48 474 755 81 Graf-von-Galen-Str.
49 495 718 81 Ziethenweg
50 467 696 83 Brendelweg
51 506 641 83 Elbinger Str.
52 540 617 84 Lethestr.
53 588 572 85 Breslauer Str.
54 582 536 87 Max-Planck-Str.
55 555 489 88 Parkstr.
56 506 441 89 Markt
57 506 429 90 Post
58 530 409 93 Bahnhof / ZOB
59 530 409 99 Bahnhof / ZOB
60 623 399 101 Heinrichstr.
61 694 384 102 Syker Str.
62 728 405 103 Pestalozziweg
63 759 422 104 Leipziger Weg
64 784 437 105 Lüneburger Str.
65 826 457 106 Kieler Weg
66 882 488 106 An der Riede
67 922 513 107 Langenwischstr.
68 992 597 109 Pultern
69 1040 661 110 Mühle Unger
70 1106 675 111 Johann-Eilers-Weg
71 1188 682 112 Schulstr.
72 1284 642 114 Grüne Str.
73 1341 606 115 Meenheit
74 1419 631 116 Henstedter Str.
75 1441 637 117 Varreler Landstr.
76 1457 600 118 Friedhof Huchting
77 1473 575 119 Rotterdamer Str.
78 1525 509 120 Hohenhorster Weg
79 1542 478 121 Willakedamm
80 1567 455 124 Roland-Center
81 1567 455 150 Roland-Center
+59
View File
@@ -0,0 +1,59 @@
515,881,1,Gothaer Str.
467,864,1,Dresdener Str.
475,826,2,Blücherweg
498,787,3,Jenaer Str.
529,750,4,Overbergstr.
553,770,5,Jägerstr.
588,717,6,Danziger Str.
583,682,7,Görlitzer Str.
576,654,8,Liegnitzer Str.
567,628,9,Königsberger Str.
583,571,10,Breslauer Str.
578,536,12,Max-Planck-Str.
548,492,13,Parkstr.
499,446,14,Markt
498,432,15,Post
529,401,18,Bahnhof / ZOB
529,401,24,Bahnhof / ZOB
564,357,26,Am Wollepark
558,318,27,Thüringer Str.
546,260,27,Schönemoorer Str.
555,227,28,Hansastr.
574,187,29,Nordstr.
532,190,30,Lessingstr.
526,140,31,Andersenstr.
532,106,31,Kleistweg
543,78,32,Gorch-Fock-Str.
590,83,33,Friedhof
644,75,33,Brauereiweg
658,47,34,Bungerhof
658,47,50,Bungerhof
644,75,51,Brauereiweg
590,83,52,Friedhof
543,78,53,Gorch-Fock-Str.
532,106,53,Kleistweg
526,140,54,Andersenstr.
532,190,55,Lessingstr.
574,187,56,Nordstr.
555,227,57,Hansastr.
546,260,58,Schönemoorer Str.
558,318,59,Thüringer Str.
564,357,60,Am Wollepark
529,401,63,Bahnhof / ZOB
529,401,69,Bahnhof / ZOB
498,432,70,Post
499,446,73,Markt
548,492,75,Parkstr.
578,536,77,Max-Planck-Str.
583,571,78,Breslauer Str.
567,628,79,Königsberger Str.
576,654,80,Liegnitzer Str.
583,682,81,Görlitzer Str.
588,717,81,Danziger Str.
553,770,82,Jägerstr.
529,750,83,Overbergstr.
498,787,84,Jenaer Str.
525,828,86,Chemnitzer Str.
539,875,86,Altenburger Str.
515,881,88,Gothaer Str.
515,881,90,Gothaer Str.
1 515 881 1 Gothaer Str.
2 467 864 1 Dresdener Str.
3 475 826 2 Blücherweg
4 498 787 3 Jenaer Str.
5 529 750 4 Overbergstr.
6 553 770 5 Jägerstr.
7 588 717 6 Danziger Str.
8 583 682 7 Görlitzer Str.
9 576 654 8 Liegnitzer Str.
10 567 628 9 Königsberger Str.
11 583 571 10 Breslauer Str.
12 578 536 12 Max-Planck-Str.
13 548 492 13 Parkstr.
14 499 446 14 Markt
15 498 432 15 Post
16 529 401 18 Bahnhof / ZOB
17 529 401 24 Bahnhof / ZOB
18 564 357 26 Am Wollepark
19 558 318 27 Thüringer Str.
20 546 260 27 Schönemoorer Str.
21 555 227 28 Hansastr.
22 574 187 29 Nordstr.
23 532 190 30 Lessingstr.
24 526 140 31 Andersenstr.
25 532 106 31 Kleistweg
26 543 78 32 Gorch-Fock-Str.
27 590 83 33 Friedhof
28 644 75 33 Brauereiweg
29 658 47 34 Bungerhof
30 658 47 50 Bungerhof
31 644 75 51 Brauereiweg
32 590 83 52 Friedhof
33 543 78 53 Gorch-Fock-Str.
34 532 106 53 Kleistweg
35 526 140 54 Andersenstr.
36 532 190 55 Lessingstr.
37 574 187 56 Nordstr.
38 555 227 57 Hansastr.
39 546 260 58 Schönemoorer Str.
40 558 318 59 Thüringer Str.
41 564 357 60 Am Wollepark
42 529 401 63 Bahnhof / ZOB
43 529 401 69 Bahnhof / ZOB
44 498 432 70 Post
45 499 446 73 Markt
46 548 492 75 Parkstr.
47 578 536 77 Max-Planck-Str.
48 583 571 78 Breslauer Str.
49 567 628 79 Königsberger Str.
50 576 654 80 Liegnitzer Str.
51 583 682 81 Görlitzer Str.
52 588 717 81 Danziger Str.
53 553 770 82 Jägerstr.
54 529 750 83 Overbergstr.
55 498 787 84 Jenaer Str.
56 525 828 86 Chemnitzer Str.
57 539 875 86 Altenburger Str.
58 515 881 88 Gothaer Str.
59 515 881 90 Gothaer Str.
+71
View File
@@ -0,0 +1,71 @@
658,47,5,Bungerhof
644,75,6,Brauereiweg
636,85
590,83,7,Friedhof
543,78,8,Gorch-Fock-Str.
498,75,8,Hebbelweg
468,68
463,75,9,Friedensstr.
470,134,10,Scheffelstr.
480,198,11,Dwostr.
482,216
518,239,12,Rilkeweg
546,260,13,Schönemoorer Str.
554,319,14,Thüringer Str.
560,359,15,Am Wollepark
566,386
563,392
548,396
527,398,18,Bahnhof / ZOB J
527,398,24,Bahnhof / ZOB J
509,402
493,415
494,432,25,Post
496,445,28,Markt A
474,456
450,463
442,471,30,Holbeinstr./Graft Therme
412,533
411,530,32,Berufsschule
362,505,33,Feuerbachstr.
336,491,34,Schumannstr.
299,519,35,Brahmsstr.
242,520,36,Mozartstr.
220,514,37,Josef-Hospital
199,569,38,Hanse-Wissenschaftsk.
199,569,48,Hanse-Wissenschaftsk.
220,514,49,Josef-Hospital
242,520,50,Mozartstr.
299,519,51,Brahmsstr.
336,491,52,Schumannstr.
362,505,53,Feuerbachstr.
411,530,54,Berufsschule
412,533
442,471,55,Holbeinstr./Graft Therme
450,463
474,456
496,445,59,Markt C1
494,432,60,Post
493,415
509,402
527,398,63,Bahnhof / ZOB D
527,398,69,Bahnhof / ZOB D
548,396
563,392
566,386
560,359,71,Am Wollepark
554,319,72,Thüringer Str.
546,260,73,Schönemoorer Str.
518,239,74,Rilkeweg
482,216
480,198,74,Dwostr.
470,134,75,Scheffelstr.
463,75,76,Friedensstr.
468,68
498,75,77,Hebbelweg
543,78,77,Gorch-Fock-Str.
590,83,78,Friedhof
636,85
644,75,78,Brauereiweg
658,47,79,Bungerhof
658,47,90,Bungerhof
1 658,47,5,Bungerhof
2 644,75,6,Brauereiweg
3 636,85
4 590,83,7,Friedhof
5 543,78,8,Gorch-Fock-Str.
6 498,75,8,Hebbelweg
7 468,68
8 463,75,9,Friedensstr.
9 470,134,10,Scheffelstr.
10 480,198,11,Dwostr.
11 482,216
12 518,239,12,Rilkeweg
13 546,260,13,Schönemoorer Str.
14 554,319,14,Thüringer Str.
15 560,359,15,Am Wollepark
16 566,386
17 563,392
18 548,396
19 527,398,18,Bahnhof / ZOB J
20 527,398,24,Bahnhof / ZOB J
21 509,402
22 493,415
23 494,432,25,Post
24 496,445,28,Markt A
25 474,456
26 450,463
27 442,471,30,Holbeinstr./Graft Therme
28 412,533
29 411,530,32,Berufsschule
30 362,505,33,Feuerbachstr.
31 336,491,34,Schumannstr.
32 299,519,35,Brahmsstr.
33 242,520,36,Mozartstr.
34 220,514,37,Josef-Hospital
35 199,569,38,Hanse-Wissenschaftsk.
36 199,569,48,Hanse-Wissenschaftsk.
37 220,514,49,Josef-Hospital
38 242,520,50,Mozartstr.
39 299,519,51,Brahmsstr.
40 336,491,52,Schumannstr.
41 362,505,53,Feuerbachstr.
42 411,530,54,Berufsschule
43 412,533
44 442,471,55,Holbeinstr./Graft Therme
45 450,463
46 474,456
47 496,445,59,Markt C1
48 494,432,60,Post
49 493,415
50 509,402
51 527,398,63,Bahnhof / ZOB D
52 527,398,69,Bahnhof / ZOB D
53 548,396
54 563,392
55 566,386
56 560,359,71,Am Wollepark
57 554,319,72,Thüringer Str.
58 546,260,73,Schönemoorer Str.
59 518,239,74,Rilkeweg
60 482,216
61 480,198,74,Dwostr.
62 470,134,75,Scheffelstr.
63 463,75,76,Friedensstr.
64 468,68
65 498,75,77,Hebbelweg
66 543,78,77,Gorch-Fock-Str.
67 590,83,78,Friedhof
68 636,85
69 644,75,78,Brauereiweg
70 658,47,79,Bungerhof
71 658,47,90,Bungerhof
View File
+14
View File
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"jsx": "react",
"allowJs": true,
"moduleResolution": "node"
},
"exclude": [
"node_modules"
]
}
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "eval-source-map",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.(ogg|mp3|wav|mpe?g|gif|png|jpe?g|svg|xml)$/i,
use: "file-loader"
},
{
test: /\.csv$/i,
use: 'raw-loader',
},
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new CleanWebpackPlugin({
root: path.resolve(__dirname, "../")
}),
new HtmlWebpackPlugin({
template: "./index.html"
})
]
};
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2020. Pascal Syma <pascal@syma.dev>.
* All rights reserved.
*/
const {merge} = require('webpack-merge');
const path = require("path");
const base = require("./base");
const TerserPlugin = require("terser-webpack-plugin");
const WorkboxPlugin = require('workbox-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
module.exports = merge(base, {
mode: "production",
output: {
filename: "bundle.min.js"
},
devtool: false,
performance: {
maxEntrypointSize: 900000,
maxAssetSize: 900000
},
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
output: {
comments: false
}
}
})
]
},
plugins: [
new WorkboxPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true,
}),
new FaviconsWebpackPlugin({
logo: './map.png',
publicPath: "./",
favicons: {
manifestRelativePaths: true,
start_url: "../",
appName: 'RT Delbus',
appDescription: 'Real-Time Delbus',
appShortName: "rt-delbus",
developerName: 'Syma.Dev',
developerURL: "https://syma.dev",
background: '#000',
theme_color: '#333',
logging: false,
icons: {
android: true,
appleIcon: true,
appleStartup: false,
coast: false,
favicons: true,
firefox: true,
windows: true,
yandex: false
}
}
})
]
});