I need to make several diagrams of a railway network, each of them representing different scenarios. Here is an ugly example of what I want: enter image description here And here my first attempt to reproduce it: enter image description here

As you can see, I am perfectly capable of reproducing the scenario in Tikz, but I would have to do lots of different scenarios. Can someone help me improve my code? What I need is a quick and "automatized" way of delimiting the rails (in black), the rest I can do it. What I find difficult is creating the paths with the same angles when I try to change from one side to the other and to create the end lines that represent a contact. Moreover, different scenarios have different ways of connecting both sides.




\tikzstyle{rail}=[very thick]       % m19

\draw [rail] (0,0) -- (2,0)  -- (3.5,3.8);
\draw [rail] (3.2,3.8) -- (3.8,3.8);

\draw [rail] (2.5,0) -- (5.5,0);
\draw [rail] (2.5,-0.3) -- (2.5,0.3);
\draw [rail] (5.5,-0.3) -- (5.5,0.3);

\draw [rail] (4.5,3.8) -- (6,0) -- (10.5,0);
\draw [rail] (4.2,3.8) -- (4.8,3.8);
\draw [rail] (10.5,-0.3) -- (10.5,0.3);

\node [rectangle,draw,fill=green, minimum width=1cm, minimum height=1cm] (train) at (1.5,4) {TTX2};

\draw [rail] (train) -- (9.3,4) -- (11,0) -- (13,0);
\draw [rail] (13,-0.3) -- (13,0.3);

\draw [rail](10,4) --(13,4);
\node [diamond,draw,fill=yellow] at (7.5,4) {};

\node [draw] (zone2) at (9,5.5) {Zone 2};
\draw [rail] (zone2) -- (11,5.5) -- (11.6,4.2);
\draw [rail] (11.3,4.2) -- (11.9,4.2);


  • A couple of suggestions: for the joins (I mean those terminating bars) try defining a new arrow head - though it might not be possible to make the arrow head an "absolute" angle so this might not work. For the angles, use polar coordinates. – Loop Space Sep 25 '12 at 13:24
  • I have no idea of how to define an arrow. I tried using polar coordinates, but I didn't get it... Sorry for my ignorance! – Felipe Aguirre Sep 25 '12 at 13:27
  • Is the "non-right-angle" bending neccessary? I think it would be much easier if that wasn't the case. – Tom Bombadil Sep 25 '12 at 16:02
  • Yes, it would me much easier, but it is necessary, it represents the connection that allows a train to go from one rail side to the other. – Felipe Aguirre Sep 25 '12 at 16:07
  • Just an update, I have substantially improved my code and I think that I'll be able to provide a complete answer soon enough. Thank you for your guidelines. – Felipe Aguirre Sep 26 '12 at 11:09

I defined two LaTeX macros for the arrow-like endings:

\newcommand*{\railWEend}{+ (-.3,0) -- + (.3,0) + (0,0)}
\newcommand*{\railNSend}{+ (0,.3) -- + (0,-.3) + (0,0)}

They essentially draw a .6cm long line in either north-south or west-east direction. See the full example below how they are used.

The accident diamond is put directly in the path that draws the main line. Notice the pos=.75 key. The decorations.pathreplacing library is used for the brace.




\tikzstyle{rail}=[very thick]

\newcommand*{\railWEend}{+ (-.3,0) -- + (.3,0) + (0,0)}
\newcommand*{\railNSend}{+ (0,.3) -- + (0,-.3) + (0,0)}


\draw [rail] (0,0) -- (2,0)  -- (3.5,3.8) \railWEend;

\draw [rail] (2.5,0) \railNSend -- (5.5,0) \railNSend;

\draw [rail] (4.5,3.8) \railWEend -- (6,0) -- (10.5,0) \railNSend;

\draw [decoration=brace,decorate,thick,yshift=5mm] (6,0) -- (10.5,0) node [pos=.5,above=1mm] {Maintenance zone};

\node [rectangle,draw,fill=green, minimum width=1cm, minimum height=1cm] (train) at (1.5,4) {TTX2};

\draw [rail] (train) -- node [accident,pos=.75] (acc1) {} (9.3,4) -- (11,0) -- (13,0) \railNSend;

\draw [rail](10,4) --(13,4);

\node [draw] (zone2) at (9,5.5) {Zone 2};
\draw [rail] (zone2) -- (11,5.5) -- (11.6,4.2) \railWEend;

\draw [-triangle 45,green!50!black,line width=2.5\pgflinewidth] (train) -- (acc1);



Output of code

Further annotations

I myself tried to write my own macro to design a railway network in TikZ (especially signals).
I defined a few commands and lengths that save distances or auxiliary values. I had different macros for the base of a signal (that is the same for every signal), for the top part and its name that appears near the base.

I quickly gave up because when it comes to complicated signals that have optional information (speed, direction, …) the code would have become very complex. There also already exist shapes/templates for WYSIWYG solutions like Microsoft's Visio.

I would advise you to define rules (or derive them for your technical sector of work), to follow them and use as few as possible absolute coordinates.

  • I like your solution. I grab some of your ideas for my final diagrams. Thank you very much! – Felipe Aguirre Sep 25 '12 at 19:48

I found a workaround to the problem. First, I define a macro with the set of coordinates of interest for the diagram. Then I created a macro that puts an invisible circle in a given point \limitCirc. This circle is then intersected with the line that has a "bump" and creates a coordinate \limitInter. Finally, I use this coordinate to create the line and I make use of the macro \railWEend and \railNSend created by @Qrrbrbirlbel. For the signals, I used tikz-timing package to create the "wave".

Here is the output of one of the scenarios: enter image description here


% ===================================
% ===================================



\tikzstyle{rail}=[ultra thick]
\tikzstyle{movement}=[green!50!black,line width=2.5\pgflinewidth]
\tikzstyle{ttx}=[rectangle,draw,fill=green!30, minimum width=1cm, minimum height=0.6cm]
\tikzstyle{ter}=[rectangle,draw,fill=blue!30,minimum width=1cm, minimum height=0.6cm]

    node[inner sep=2pt,rectangle,rounded corners,draw,fill=white,thin]%
    {\tikz \draw[fill=#1] circle (4pt);}
    \draw[semithick] (#1)--++(0,0.5)--++(0.7,0)\feu{red};
    \draw[semithick] (#1)--++(0,-0.5)\feu{green}--++(-0.7,0)%
    node[inner sep=2pt,rectangle,rounded corners,draw,fill=white,thin]%
    {\tikz \timing[timing/slope=0.5,thick] {HlL};};
\newcommand*{\railWEend}{+ (-.3,0) -- + (.3,0) + (0,0)}
\newcommand*{\railNSend}{+ (0,.3) -- + (0,-.3) + (0,0)}
    \draw (12.5,4.2)\railWEend--++(-0.45,1)--++(-0.5,0)
    node[draw,anchor=east,thin] {Zone 2};
    \draw (7.5,-0.2)\railWEend--++(0.45,-1.3)--++(0.5,0)
    node[draw,anchor=west,thin] {Zone 3};
    \draw [decoration=brace,decorate,thick,yshift=-5mm] (9.5,4) -- (3.5,4) node         [pos=.42,below=1mm] {\textbf{Protected zone} $\approx 10km$};
    \draw [decoration=brace,decorate,thick,yshift=5mm] (2.35,0) -- (10.65,0) node [pos=.7,above=1mm] {\textbf{Maintenance zone} $\approx 10km$};

\newcommand{\limitCirc}[1]{\node[circle,minimum width=0.5cm] (l#1) at (#1) {};}
\newcommand{\limitInter}[2]{    %
    \coordinate(i#1) at (intersection 1 of l#1 and #1--#2);
    \coordinate(i#2) at (intersection 1 of l#2 and #2--#1);
    \coordinate (10) at (0,4);
    \coordinate (1a) at (3.5,4);
    \coordinate (1b) at (4.5,4);
    \coordinate (1c) at (9.5,4);
    \coordinate (1d) at (14,4);
    \coordinate (1e) at (13.5,4);

    \coordinate (20) at (0,0);
    \coordinate (2a) at (2,0);
    \coordinate (2b) at (6,0);
    \coordinate (2c) at (11,0);
    \coordinate (2d) at (13,0);
    \coordinate (2e) at (12,0);

     \node[anchor=west,draw] (head2) at (2d) {Head 2};
    \draw [->,thick](14.5,-0.5) -- (13,-0.5);
    \node[anchor=east,draw] (head1) at (10) {Head 1};
    \draw [->,thick](-1.5,4.5) -- (0,4.5);

 % ============= scenario 5 ================


    \draw[rail]  (i1a)\railWEend -- (2a) -- (20);   

    \draw[rail]  (i2a)\railNSend -- (i2b)\railNSend;

    \draw[rail]  (1c) -- (2c)--(head2); 

    \draw[rail]  (i1e)\railWEend -- (i2e)\railWEend;    

    \draw[rail]  (i1b)\railWEend -- (2b) -- (i2c)\railNSend;
    \draw[rail] (1c) -- (1d);

    \node[ttx] (ttx2)   at (1.5,4) {TTX2};
    \node[ter,rotate=-70] (ter1)   at (10.2,2) {TER};
    \node[star,star points=10, star point ratio=2.25,fill=yellow,draw] (acci)  at (7.5,4) {};

    \draw[rail]  (ttx2)--(head1);   
    \draw [-triangle 45,movement] (ttx2) -- (acci);
    \draw [-triangle 45,movement,blue] (ter1) -- (1c)--(acci);


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.