
\documentclass[tikz]{standalone}

\usepackage{tikz}
\usepackage{fontspec}
\usepackage{contour}

\setmainfont{Atkinson Hyperlegible}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usetikzlibrary{arrows.meta}

\definecolor{one}{RGB}{237,28,36}
\definecolor{two}{RGB}{53,175,63}
\definecolor{three}{RGB}{247,146,16}
\definecolor{four}{RGB}{240,51,163}
\definecolor{five}{RGB}{9,148,206}
% \definecolor{six}{RGB}{149,107,37}
% \definecolor{seven}{RGB}{255,204,0}
% \definecolor{fifteen}{RGB}{247,171,99}
% \definecolor{sixteen}{RGB}{94,107,175}
% \definecolor{twentyone}{RGB}{227,0,11}
% \definecolor{twentytwo}{RGB}{253,195,0}
% \definecolor{twentythree}{RGB}{228,142,0}
% \definecolor{twentyfour}{RGB}{140,29,117}
% \definecolor{twentysix}{RGB}{243,155,154}

\input{../shapes.tex}

\pgfdeclarelayer{bg}
\pgfdeclarelayer{lines}
\pgfdeclarelayer{stops}
\pgfdeclarelayer{labels}
\pgfdeclarelayer{legend}
\pgfsetlayers{bg,lines,stops,labels,main,legend}

\contourlength{.2ex}

\begin{document}

\begin{tikzpicture}[
    river/.style = {
      line width=0.5cm,
      cyan!50,
      rounded corners=0.5cm,
      -{Triangle Cap},
    },
    railway line/.style = {
      color=gray,
      line width=0.075cm,
      rounded corners=0.5cm,
    },
    railway/.style = {
      railway line,
      {Latex[length=5mm]}-{Latex[length=5mm]},
    },
    stop/.style = {
      rounded corners=0.1cm, 
      line width=0.05cm,
      fill=white, 
      draw,
      shape=stop,
      anchor=center,
      minimum height=0.2cm,
    },
    stop1/.style = {
      stop,
      minimum width=0.2cm, 
    },
    stop2/.style = {
      stop,
      minimum width=0.4cm, 
    },
    stop3/.style = {
      stop,
      minimum width=0.6cm, 
    },
    stop4/.style = {
      stop,
      minimum width=0.8cm, 
    },
    line/.style = {
      line width=0.15cm,
      rounded corners=0.1cm,
    },
    label/.style = {
      font=\scriptsize,
    },
    line name/.style = {
      label, 
      color=white, 
      minimum width=1em, 
      minimum height=1em, 
      inner sep=0pt,
    },
  ]

  % \begin{pgfonlayer}{legend}
  %   % \draw[railway line] (-7,-8.5) -- ++(0,0.5);
  %   \node[stop2] (Legend2) at (-7,-8.5) {};
  %   \node[stop1, above=0.4cm of Legend2.two half] (Legend1) {};
  %   \node[stop1, above=0.3cm of Legend1] (Legend0) {};
  %   \draw[line] (Legend2.south two half) -- (Legend1.north center) -- (Legend0);
  %   \draw[line] (Legend2.south one half) -- ++(0,0.5) -- ++(-0.3,0);
  %   \node[stop2] (Legend2) at (-7,-8.5) {};
  %   \node[stop1, above=0.4cm of Legend2.two half] (Legend1) {};
  %   \node[stop1, above=0.3cm of Legend1] (Legend0) {};
  %   \node[line name, fill=black, above=0.2cm of Legend0] {\bf E};
  %   \node[label, left=0.05cm of Legend1] {Karlsplatz};
  %   \node[label, left=0.05cm of Legend0] {Museum};
  %   \node[label, left=0.05cm of Legend2] {Bahnhof};
  %
  %   \node[label, anchor=west] at (-6.7,-8.5) {Halt mit Umstieg};
  %   \node[label, anchor=west] at (-6.7,-8.0) {Halt};
  %   \node[label, anchor=west] at (-6.7,-7.5) {Endhaltestelle};
  % \end{pgfonlayer}

  \begin{pgfonlayer}{bg}
    % \draw[help lines, color=gray!10] (-10, -15) grid[step=0.1] (10, 10);
    % \draw[help lines, color=gray!50] (-10, -15) grid (10, 10);
    \draw[river] (-14,-1.5) -- (3.7, -1.5) -- ++(4,4) -- ++(4,0);
  \end{pgfonlayer}

  \begin{pgfonlayer}{stops}
    \node[stop4, rotate=90] (Bertoldsbrunnen) at (2.5, 0) {};
    \node[stop4, rotate=90] (Stadttheater) at (1, 0) {};
    \node[stop4, rotate=90] (Hauptbahnhof) at (-0.5, 0) {};
    \node[stop4, rotate=90] (Eschholzstrasse) at (-2, 0) {};
    \node[stop4, rotate=90] (Rathaus) at (-3.5, 0) {};
    \node[stop2] (Robert-Koch-Str) at (-3.9, 1.5) {};
    \node[stop1] (Killianstr) at ($(Robert-Koch-Str)-(1, -0.4)$) {};
    \node[stop1, left=1cm of Killianstr] (Berliner Allee) {};
    \node[stop1] (Elsässer Str) at ($(Berliner Allee)-(0.3,-1)$) {};
    \node[stop1, above=1cm of Elsässer Str] (Technische Fakultät) {};
    \node[stop1, above left=1cm of Technische Fakultät.north two half] (Europa-Park-Stadium) {};
    \node[stop1, above left=1cm of Europa-Park-Stadium] (Messe) {};
    \node[stop2, above=1.7cm of Bertoldsbrunnen.south two half, anchor=two half] (Europaplatz) {};
    \node[stop1, above=0.7cm of Europaplatz.two half] (Tennenbacher Str) {};
    \node[stop1, above=0.7cm of Tennenbacher Str] (Hauptstr) {};
    \node[stop1, above=0.7cm of Hauptstr] (Okenstr) {};
    \node[stop2, above=0.7cm of Okenstr, anchor=two half] (Hornusstr) {};
    \node[stop1, above=0.7cm of Hornusstr.two half] (Tullastr) {};
    \node[stop1, above=0.7cm of Tullastr] (Reutebachgasse) {};
    \node[stop1, above=0.7cm of Reutebachgasse] (Berggasse) {};
    \node[stop1, above=0.7cm of Berggasse] (Glottertalstr) {};
    \node[stop1, above=0.7cm of Glottertalstr] (Gundelfinger Str) {};

    \node[stop1, below left = 1cm of Hornusstr.south one half] (Eugen-Martin-Str) {};
    \node[stop1] (Friedrich-Ebert-Platz) at ($(Robert-Koch-Str)-(-1.4, -0.4)$) {};
    \node[stop1, below left = 1cm of Eugen-Martin-Str] (Zollhallenplatz) {};
    \node[stop1, below left = 1cm of Zollhallenplatz] (Hauptfriedhof) {};
    \node[stop2, below = 0.7cm of Bertoldsbrunnen.south one half, anchor=one half] (Holzmarkt) {};
    \node[stop2, below =2.1cm of Holzmarkt] (Johanneskirche) {};
    \node[stop1, below=0.7 cm of Johanneskirche.two half] (Lorettostr) {};
    \node[stop1, below=0.7 cm of Lorettostr] (Holbeinstr) {};
    \node[stop1, below=0.7 cm of Holbeinstr] (Wonnhalde) {};
    \node[stop1, below right = 1.7cm of Wonnhalde.south two half] (Wiesenweg) {};
    \node[stop1, below right = 0.7cm of Wiesenweg] (Klosterplatz) {};
    \node[stop1, below right = 0.7cm of Klosterplatz] (Günterstal Dorfstr) {};


    \node[stop1, above=1.5cm of Stadttheater.three quarter] (Fahnenbergplatz) {};
    \node[stop1, below=0.7cm of Stadttheater.one half, anchor=center] (Erbprinzenstr) {};
    \node[stop1,below left = 2.1cm of Erbprinzenstr.south one half] (Mattenstr) {};
    \node[stop2, rotate=90] (Heinrich-von-Stephan-Str) at ($(Mattenstr)-(1,0.7)$) {};
    \node[stop1, right=0.7cm of Heinrich-von-Stephan-Str.one half] (Reiterstr) {};
    \node[stop1, left=1cm of Heinrich-von-Stephan-Str.two half] (Pressehaus) {};
    \node[stop1, left=0.7cm of Pressehaus] (Haslach Bad) {};
    \node[stop1, left=0.7cm of Haslach Bad] (Scherrerplatz) {};
    \node[stop1, left=0.7cm of Scherrerplatz] (Dorfbrunnen) {};
    \node[stop1, left=0.7cm of Dorfbrunnen] (Krozinger Str) {};
    \node[stop2, rotate=90, left=1.5cm of Krozinger Str, anchor=one half] (Am Lindenwäldle) {};
    \node[stop1, left=1.4cm of Am Lindenwäldle.one half] (Geschwister-Scholl-Platz) {};
    \node[stop1, left=0.7cm of Geschwister-Scholl-Platz] (Maria-von-Rudloff-Platz) {};
    \node[stop1, left=0.7cm of Maria-von-Rudloff-Platz] (Bollerstaudenstr) {};

    \node[stop2, rotate=90, left=0.7 of Rathaus.one half, anchor=one half] (Runzmattenweg) {};
    \node[stop1, below left=0.7cm of Runzmattenweg.north one half] (Bissier Str) {};
    \node[stop1, below left=1.4cm of Bissier Str] (Rohrgraben) {};
    \node[stop1, below left=0.65cm of Rohrgraben] (Bugginger Str) {};
    \node[stop1] (VAG-Zentrum) at ($(Am Lindenwäldle.north one half)-(0.3, 1.7)$) {};
    \node[stop1, below =0.7cm of VAG-Zentrum] (Munzinger Str) {};
    \node[stop1] (Weddingenstr) at ($(Heinrich-von-Stephan-Str.one half)-(0.3,1.6)$) {};
    \node[stop1, below=0.7cm of Weddingenstr] (Peter-Thumb-Str) {};
    \node[stop1, below left=1cm of Peter-Thumb-Str] (Paula-Modersohn-Platz) {};
    \node[stop1, left=0.7cm of Paula-Modersohn-Platz] (Vauban Mitte) {};
    \node[stop1, left=0.7cm of Vauban Mitte] (Innsbrucker Str) {};

    \node[stop1, left=2.4cm of Runzmattenweg.two half] (Am Bischofskreuz) {};
    \node[stop1, left=1.7cm of Am Bischofskreuz] (Betzenhauser Torplatz) {};
    \node[stop1] (Paduaallee) at ($(Betzenhauser Torplatz)-(0.7,-0.3)$) {};
    \node[stop1, above=0.7cm of Paduaallee] (Moosgrund) {};
    \node[stop1, above left = 1.7cm of Moosgrund.north two half] (Diakoniekrankenhaus) {};
    \node[stop1, above left = 1.7cm of Diakoniekrankenhaus] (Moosweiher) {};
    \node[stop1, right=1.7cm of Bertoldsbrunnen.two quarter] (Oberlinden) {};
    \node[stop1, below right = 1.4cm of Oberlinden.east, anchor=west] (Schwabentorbrücke) {};
    \node[stop1, right=0.7 cm of Schwabentorbrücke] (Brauerei Ganter) {};
    \node[stop1, right=0.7cm of Brauerei Ganter] (Maria-Hilf-Kirche) {};
    \node[stop1, right=0.7cm of Maria-Hilf-Kirche] (Alter Messplatz) {};
    \node[stop1, right=0.7cm of Alter Messplatz] (Musikhochschule) {};
    \node[stop1, right=0.7cm of Musikhochschule] (Emil-Gött-Str) {};
    \node[stop1, right=0.7cm of Emil-Gött-Str] (Hasemannstr) {};
    \node[stop1, right=0.7cm of Hasemannstr] (Römerhof) {};
    \node[stop1, right=0.7cm of Römerhof] (Laßbergstr) {}; 
  \end{pgfonlayer}

  \begin{pgfonlayer}{lines}
    \pgfmathparse{0.1*tan(45/2)}
    \let\offset\pgfmathresult

    \draw[railway] ($(Gundelfinger Str)+(3.9,-1)$) 
      node[label, left, anchor=south west] {Karlsruhe}
      -- ($(Hauptbahnhof)+(0,1.7)$)
      -- ($(Hauptbahnhof)$)
      -- ++(0, -1)
      -- ($(Pressehaus)+(0.5,0)$) 
      -- ++(0,-5)
      node[label, right, anchor=south west] {Basel};
    
    \draw[railway] ($(Moosweiher)-(1,0)$)
      node[label, right, anchor=south east] {Breisach}
      -- ($(Moosweiher)$)
      -| ($(Hauptbahnhof)$)
      -- ++(0, -1)
      -- ($(Pressehaus)+(0.5,0)$) 
      -- ++(0, -2.3)
      -- ++(3.3, 0)
      -- ++(3,3)
      -- ++(3,0)
      node[label, left, anchor=south east] {Villingen-Schwenningen}
    ;


    \draw[line, one]
    (Laßbergstr)
      -- (Römerhof)
      -- (Hasemannstr)
      -- (Emil-Gött-Str)
      -- (Musikhochschule)
      -- (Alter Messplatz)
      -- (Maria-Hilf-Kirche)
      -- (Brauerei Ganter)
      -- (Schwabentorbrücke)
      -- (Schwabentorbrücke.west)
      -- (Oberlinden.east)
      -- (Oberlinden)
      -- (Bertoldsbrunnen.two quarter)
      -- (Stadttheater.two quarter)
      -- (Hauptbahnhof.two quarter)
      -- (Eschholzstrasse.two quarter)
      -- (Rathaus.two quarter)
      -- (Runzmattenweg.two half)
      -- (Am Bischofskreuz)
      -- (Betzenhauser Torplatz)
      -| (Paduaallee)
      -- (Moosgrund)
      -- (Moosgrund.north two half)
      -- (Diakoniekrankenhaus)
      -- (Moosweiher)
    ;

    \draw[line, two]
      (Günterstal Dorfstr)
      -- (Klosterplatz)
      -- (Wiesenweg)
      -- (Wonnhalde.south two half)
      -- (Wonnhalde)
      -- (Holbeinstr)
      -- (Lorettostr)
      -- (Johanneskirche.two half)
      -- (Holzmarkt.two half)
      {[rounded corners=0.15cm]
        |- (Bertoldsbrunnen.three quarter)
      }
      -- (Stadttheater.three quarter)
      -- (Hauptbahnhof.three quarter)
      -- (Eschholzstrasse.three quarter)
      -- (Rathaus.three quarter)
      -| (Robert-Koch-Str.two half)
      |- (Friedrich-Ebert-Platz)
      -- (Friedrich-Ebert-Platz.two quarter)
      -- ($(Hauptfriedhof)-(0.675,0.675)$)
      -- (Hauptfriedhof)
      -- (Zollhallenplatz)
      -- (Eugen-Martin-Str)
      -- (Hornusstr.south one half)
      -- (Hornusstr.one half)
    ;

    \draw[line, three]
      (Innsbrucker Str)
      -- (Vauban Mitte)
      -- (Paula-Modersohn-Platz)
      -| (Peter-Thumb-Str)
      -- (Weddingenstr)
      |- (Heinrich-von-Stephan-Str.one half)
      -| (Johanneskirche.one half)
      -- (Holzmarkt.one half)
      |- (Bertoldsbrunnen.one half)
      -- (Stadttheater.one half)
      -- (Hauptbahnhof.one half)
      -- (Eschholzstrasse.one half)
      -- (Rathaus.one half)
      -- (Runzmattenweg.one half)
      -- (Runzmattenweg.north one half)
      -- (Bissier Str)
      -- (Rohrgraben)
      -- (Bugginger Str)
      -- ++(-0.45,-0.45)
      -- (Am Lindenwäldle.two half)
      -| (VAG-Zentrum)
      -- (Munzinger Str)
    ;

    \draw[line, four]
      (Gundelfinger Str)
      -- (Glottertalstr)
      -- (Berggasse)
      -- (Reutebachgasse)
      -- (Tullastr)
      -- (Hornusstr.two half)
      -- (Okenstr)
      -- (Hauptstr)
      -- (Tennenbacher Str)
      -- (Europaplatz.two half)
      -- (Bertoldsbrunnen.south two half)
      -- (Bertoldsbrunnen.two half)
      -- (Stadttheater.two half)
      -- (Hauptbahnhof.two half)
      -- (Eschholzstrasse.two half)
      -- (Rathaus.two half)
      -| (Robert-Koch-Str.one half)
      |- (Killianstr)
      -- (Berliner Allee)
      -| (Elsässer Str)
      -- (Technische Fakultät)
      -- (Technische Fakultät.north two half)
      -- (Europa-Park-Stadium)
      -- (Messe)
    ;

    \draw[line, five]
      (Europaplatz)
      -| (Stadttheater)
      -- (Erbprinzenstr)
      -- (Erbprinzenstr.south two half)
      -- (Mattenstr)
      -- ($(Mattenstr)-(0.6,0.6)$)
      -- (Heinrich-von-Stephan-Str.two half)
      -- (Pressehaus)
      -- (Haslach Bad)
      -- (Scherrerplatz)
      -- (Dorfbrunnen)
      -- (Krozinger Str)
      -- (Am Lindenwäldle.one half)
      -- (Geschwister-Scholl-Platz)
      -- (Maria-von-Rudloff-Platz)
      -- (Bollerstaudenstr)
    ;

  \end{pgfonlayer}

  \begin{pgfonlayer}{labels}
    \node[font=\scriptsize, color=white] at (4.0,1.5){Neckar};
    \node[font=\scriptsize, color=white, rotate=-45] at (-3.5,3.5) {Neckar};
    \foreach\stop/\placement/\anchor/\rotate in {
      Hauptbahnhof/left/north east/45,
      Eschholzstrasse/left/north east/45,
      Rathaus/right/west/45,
      Stadttheater/below right/south west/45,
      Bertoldsbrunnen/right/north west/45,
      Robert-Koch-Str/below right/west/0,
      Killianstr/above/west/45,
      Berliner Allee/above/west/45,
      Elsässer Str/left/east/0,
      Technische Fakultät/right/south west/0,
      Europa-Park-Stadium/right/west/0,
      Messe/right/west/0,
      Europaplatz/right/west/0,
      Gundelfinger Str/right/west/0,
      Glottertalstr/right/west/0,
      Berggasse/right/west/0,
      Reutebachgasse/right/west/0,
      Tullastr/right/west/0,
      Hornusstr/right/west/0,
      Okenstr/right/west/0,
      Hauptstr/right/west/0,
      Tennenbacher Str/right/west/0,
      Fahnenbergplatz/below left/north east/0,
      Friedrich-Ebert-Platz/above/south/0,
      Eugen-Martin-Str/left/east/0,
      Zollhallenplatz/left/east/0,
      Hauptfriedhof/left/east/0,
      Holzmarkt/right/west/0,
      Johanneskirche/right/west/0,
      Lorettostr/right/west/0,
      Holbeinstr/right/west/0,
      Wonnhalde/right/west/0,
      Wiesenweg/right/west/0,
      Klosterplatz/right/west/0,
      Günterstal Dorfstr/right/west/0,
      Erbprinzenstr/left/east/45,
      Mattenstr/right/west/0,
      Reiterstr/below left/east/45,
      Heinrich-von-Stephan-Str/below left/east/45,
      Pressehaus/below left/east/45,
      Haslach Bad/below left/east/45,
      Scherrerplatz/below left/east/45,
      Dorfbrunnen/below left/east/45,
      Krozinger Str/below left/east/45,
      Am Lindenwäldle/below left/east/45,
      Bissier Str/right/west/0,
      Rohrgraben/left/east/0,
      Bugginger Str/right/west/0,
      Runzmattenweg/right/east/-45,
      Geschwister-Scholl-Platz/above left/west/45,
      Maria-von-Rudloff-Platz/above left/west/45,
      Bollerstaudenstr/above left/west/45,
      VAG-Zentrum/right/west/0,
      Munzinger Str/right/west/0,
      Weddingenstr/right/west/0,
      Peter-Thumb-Str/right/west/0,
      Paula-Modersohn-Platz/below left/east/45,
      Vauban Mitte/below left/east/45,
      Innsbrucker Str/below left/east/45,
      Am Bischofskreuz/above/south/0,
      Betzenhauser Torplatz/above left/west/45,
      Paduaallee/left/east/0,
      Moosgrund/left/east/0,
      Diakoniekrankenhaus/right/west/0,
      Moosweiher/above right/south west/0,
      Oberlinden/above/west/45,
      Schwabentorbrücke/above/west/45,
      Brauerei Ganter/above/west/45,
      Maria-Hilf-Kirche/above/west/45,
      Alter Messplatz/above/west/45,
      Musikhochschule/above/west/45,
      Emil-Gött-Str/above/west/45,
      Hasemannstr/above/west/45,
      Römerhof/above/west/45,
      Laßbergstr/above/west/45%
    } \node[label, \placement=0.05cm of \stop, rotate=\rotate, anchor=\anchor] {\contour{white}{\stop}};
    \node[line name, fill=four, left=0.2cm of Messe] {\bf 4};
    \node[line name, fill=four, above=0.2cm of Gundelfinger Str] {\bf 4};
    \node[line name, fill=two, left=0.2cm of Hornusstr] {\bf 2};
    \node[line name, fill=two, below=0.2cm of Günterstal Dorfstr] {\bf 2};
    \node[line name, fill=five] at ($(Europaplatz)+(0.5,0.4)$) {\bf 5};
    \node[line name, fill=five, left=0.2cm of Bollerstaudenstr] {\bf 5};
    \node[line name, fill=three, left=0.2cm of Munzinger Str] {\bf 3};
    \node[line name, fill=three, above=0.2cm of Innsbrucker Str] {\bf 3};
    \node[line name, fill=one, above=0.2cm of Moosweiher] {\bf 1};
    \node[line name, fill=one, below=0.2cm of Laßbergstr] {\bf 1};
  \end{pgfonlayer}

\end{tikzpicture}

\end{document}
% vim: nospell conceallevel=0
