+76
@@ -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)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user