London Underground geographic maps/PHP
Jump to navigation
Jump to search
This gallery has been nominated for deletion since 16 September 2024. To discuss it, please visit the nomination page.
Do not remove this tag until the deletion nomination is closed. Reason for the nomination: User:Adamant1 made a speedy deletion, with reason "CSD G2 (unused and implausible, or broken redirect)", but I think this is loss of information. There are 10 links to this page. There were discussions about this page before (Commons:Deletion requests/London Underground geographic maps/Tables and the unfinished Commons:Categories for discussion/2021/05/Category:Taipei Metro geographic maps)
| |||
|
<?PHP
set_time_limit(0); //suppress time-outs
/*
[Start: Program Information Header]
Name : Tube mapper
Purpose : ----
Syntax :
Version : 0.15
Date : 20.vii.2004
License : BSD
[End: Program Information Header]
[Start: Author Information Header]
Name : James D. Forrester
Name : Ed Sanders
[End: Author Information Header]
*/
header('Content-type: text/plain');
// POPULATE WITH MYSQL DATABASE DETAILS
$mysql_server = '';
$mysql_user = '';
$mysql_password = '';
$mysql_dbname = '';
$dbserverlink = mysql_connect($mysql_server,$mysql_user,$mysql_password) or die('Error connecting to database: '.mysql_error().'</body></html>');
mysql_select_db($mysql_dbname) or die('Error selecting database: '.mysql_error().'</body></html>');
// choose a zone limit...
$this_zone = 1;
// or a specific line (0 if using a zone)
$this_line = 0;
$width=900; $height=600;
/* Sizes I used for each line, chosen by trial and improvement */
switch($this_line)
{
case 1:
$width = 900;
$height = 600;
break;
case 2:
$width = 1200;
$height = 720;
break;
case 3:
$width = 1000;
$height = 570;
break;
case 4:
$width = 2000;
$height = 860;
break;
case 5:
$width = 320;
$height = 490;
break;
case 6:
$width = 1200;
$height = 350;
break;
case 7:
$width = 910;
$height = 580;
break;
case 8:
$width = 1280;
$height = 700;
break;
case 9:
$width = 580;
$height = 1000;
break;
case 10:
$width = 1000;
$height = 800;
break;
case 11:
$width = 470;
$height = 570;
break;
case 12:
$width = 300;
$height = 200;
break;
case 13:
$width = 800;
$height = 600;
break;
}
$header = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
id="svg2"
width="'.$width.'"
height="'.$height.'"
y="0.00000000"
x="0.00000000"
version="1.0">';
/*
== BR logo (non-free license) ==
<polygon id="rail" fill="red" stroke="none" transform="scale(0.5)"
points="5,0 12,0 21,4 29,4 29,7 21,7 14,11
29,11 29,14 14,14 23,18 16,18 7,14
0,14 0,11 7,11 14,7 0,7 0,4 14,4" />
*/
$header .= '
<defs>
<g transform="scale(0.2) translate(-186, -460)"
id="rail">
<rect
id="body"
style="fill:#808080;stroke:none;"
y="477.49323"
x="186.32202"
height="24.131897"
width="90.994476" />
<circle
id="boiler"
style="fill:#808080"
transform="translate(231.8686,481.5260)"
r="10" cy="0" cx="0" />
<circle
id="wheel1"
style="fill:#808080;stroke:#ffffff;stroke-width:3"
transform="translate(201.8686,503.5260)"
r="10" cy="0" cx="0" />
<circle
id="wheel2"
style="fill:#808080;stroke:#ffffff;stroke-width:3"
transform="translate(231.8686,503.5260)"
r="10" cy="0" cx="0" />
<circle
id="wheel3"
style="fill:#808080;stroke:#ffffff;stroke-width:3"
transform="translate(261.8686,503.5260)"
r="10" cy="0" cx="0" />
<rect
id="chimney"
style="fill:#808080;"
y="461.22095"
x="255.97266"
height="23.334524"
width="14.142136" />
<rect
id="cabin"
style="fill:none;stroke:#808080;stroke-width:4;"
y="462.04932" x="188.32202"
height="20" width="20" />
</g>
</defs>
<defs>
<circle id="intersection" cx="0" cy="0" r="4" style="fill: white; stroke: black; stroke-width: 1.5;" />
</defs>';
// NB: "latitude * 1.6" is to account for the approximate ratio of latitude to longitude
// around London. For larger maps, this will obviously require a proper projection function
// Calculate boundaries
if($this_zone)
{
$this_line_name = 'Zone '.$this_zone;
extract(mysql_fetch_assoc(mysql_query("
SELECT
MAX(longitude) - MIN(longitude) as long_diff, MAX(latitude*1.6) - MIN(latitude*1.6) as lat_diff,
MIN(longitude) as long_min, MIN(latitude*1.6) as lat_min
FROM stations
INNER JOIN links ON id=station1 OR id=station2
WHERE zone < $this_zone + 1")));
}
else
{
$this_line_name = mysql_result(mysql_query("SELECT name FROM routes WHERE line=$this_line"), 0);
extract(mysql_fetch_assoc(mysql_query("
SELECT
MAX(longitude) - MIN(longitude) as long_diff, MAX(latitude*1.6) - MIN(latitude*1.6) as lat_diff,
MIN(longitude) as long_min, MIN(latitude*1.6) as lat_min
FROM stations
INNER JOIN links ON id=station1 OR id=station2
WHERE line = $this_line")));
}
if($long_diff/$lat_diff > $width/$height)
{
$scale = ($width-100)/$long_diff;
}
else
{
$scale = ($height-100)/$lat_diff;
}
$lat_min -= (($height/$scale)-$lat_diff)/2;
$long_min -= (($width/$scale)-$long_diff)/2;
// Load stations into memory
$stations = array();
$query_handle = mysql_query("
SELECT id, longitude-$long_min as xpos, (latitude*1.6)-$lat_min as ypos, name, display_name, total_lines, rail, line
FROM stations
INNER JOIN links ON id=station1 OR id=station2") or die(mysql_error());
while($array = mysql_fetch_assoc($query_handle))
{
extract($array);
$xpos *= $scale;// $xpos += 50;
$ypos *= $scale;// $ypos += 50;
$ypos = $height - $ypos;
$stations[$id] = array('xpos' => $xpos, 'ypos' => $ypos, 'name' => $name, 'display_name' => $display_name, 'total_lines' => $total_lines, 'rail' => $rail, 'line' => $line);
}
// Load lines/routes into memory
$lines = array();
$query_handle = mysql_query("
SELECT * FROM routes") or die(mysql_error());
while($array = mysql_fetch_assoc($query_handle))
{
extract($array);
$lines[$line] = array('name' => $name, 'RR' => hexdec(substr($colour, 0, 2)), 'GG' => hexdec(substr($colour, 2, 2)), 'BB' => hexdec(substr($colour, 4, 2)), 'stripe' => $stripe, 'colour' => $colour);
}
//$query_handle = mysql_query("SELECT * FROM links WHERE line=$this_line") or die(mysql_error());
// Generate the line/route paths
$tangents = array();
$output_lines = '';
$output_stripes = '';
if($this_line == 11 or $this_zone)
{
$this_line = 11;
$route = find_path(11, 35, 274); //Victoria Line
draw_path();
}
if($this_line == 1 or $this_zone)
{
$this_line = 1;
$route = find_path(1, 114, 84); //Bakerloo Line
draw_path();
}
if($this_line == 3 or $this_zone)
{
$this_line = 3;
$route = find_path(3, 25, 25); //Circle Line
draw_path();
}
if($this_line == 7 or $this_zone)
{
$this_line = 7;
$route = find_path(7, 243, 247); //Jubille Line
draw_path();
}
if($this_line == 6 or $this_zone)
{
$this_line = 6;
$route = find_path(6, 15, 110); //Hammersmith & City Line
draw_path();
}
if($this_line == 12 or $this_zone)
{
$this_line = 12;
$route = array(279, 13); //Waterloo & City Line
draw_path();
}
/* Picadilly Line */
if($this_line == 10 or $this_zone)
{
$this_line = 10;
$route = find_path(10, 1, 57, array(73, 234)); //Acton Town to Cockfosters, not via Ealing Common or South Ealing
draw_path();
$route = find_path(10, 271, 1); //Uxbride to Acton Town
array_push($route, 265); //Following on to Turnham Green
draw_path(true);
$route = find_path(10, 116, 1, array(117, 118)); //Hatton Cross to Acton Town
array_push($route, 265); //Following on to Turnham Green
draw_path(true);
$route = find_path(10, 116, 116, array(132)); //Hatton Cross to Hatton Cross (Heathrow loop) not via Hounslow West
array_push($route, 132); //Following on to Hounslow West
draw_path(true);
}
/* Northern Line */
if($this_line == 9 or $this_zone)
{
$this_line = 9;
$route = find_path(9, 169, 121, array(165, 279, 170, 47)); //Morden to High Barnet not via Mill Hill East, Waterloo, Mornington Crescent or Chalk Farm
draw_path();
$route = find_path(9, 81, 40, array(139)); //Edgware to Camden Town not via Kentish Town
array_push($route, 170); //...to Mornington Crescent
array_push($route, 89); //...to Euston
$route = find_path(9, 277, 136, array(84), 89, $route); //...to Warren Street to Kennington not via Elephant & Catle
array_push($route, 191); //Following on to Oval
draw_path(true);
$route = array(165, 93, 77); //Mill Hill East to Finchley Central, following on to East Finchley
draw_path(true);
}
/* East London Line */
if($this_line == 5 or $this_zone)
{
$this_line = 5;
$route = find_path(5, 175, 228, array(174)); //New Cross Gate to Shoreditch not via New Cross
draw_path();
$route = array(174, 253, 41); //New Cross Gate to Shoreditch onto Canada Water not via New Cross
draw_path(true);
}
/* Central Line */
if($this_line == 2 or $this_zone)
{
$this_line = 2;
$route = find_path(2, 294, 88, array(286, 275, 215)); //West Ruislip to Epping not via West Acton, Wanstead or Roding Valley
draw_path();
$route = find_path(2, 72, 76, array(112)); //Ealing Broadway to East Acton (following on) not via Hanger Lane
draw_path(true);
$route = find_path(2, 301, 153, array(37, 241, 230)); //Woodford to Leyton (following on) not via Buckhurst Hill, South Woodford or Snaresbrook
draw_path(true);
}
/* District Line */
if($this_line == 4 or $this_zone)
{
$this_line = 4;
$route = find_path(4, 72, 267, array(108, 287, 138, 122)); //Ealing Broadway to Upminster not via Gunnersbury, West Brompton, Kensington or High Street Kensington
draw_path();
$route = find_path(4, 213, 265, array(52)); //Richmond to Turnham Green not via Chiswick Park
draw_path();
$route = find_path(4, 83, 299, array(138, 293, 99)); //Edgware Road to Wimbledon not via Kensington, West Kensington or Gloucester Road
draw_path();
$route = array(138, 74); //Kensignton to Earl's Court
draw_path();
}
/* Metropolitan Line */
if($this_line == 8 or $this_zone)
{
$this_line = 8;
$route = find_path(8, 271, 178, array(184)); //Uxbridge to Northwick Park (following on) not via North Harrow
draw_path(true);
$route = array(280, 62, 168, 179); //Watford to Croxley to Moor Park following on to Northwood
draw_path(true);
$route = array(50, 46); //Chesham to Chalfront & Latimer
draw_path();
$route = find_path(8, 6, 282, array(50, 62, 291)); //Amersham to Wembley Park not via Chesham, Croxley or West Harrow
$route = find_path(7, 172, 290, array(), 282, $route); //Neasden to West Hampstead on Jubilee line, for path following
$route = find_path(8, 94, 2, array(), 290, $route); //Finchley Road to Aldgate
draw_path();
}
/* DLR */
if($this_line == 13 or $this_zone)
{
$this_line = 13;
$route = find_path(13, 13, 19, array(4, 292, 304)); //Bank to Beckton not via All Saints or West India Quay or West Silvertown
draw_path();
$route = find_path(13, 152, 155, array(201)); //Lewisham to Limehouse (following on) not via Poplar
draw_path(true);
$route = find_path(13, 247, 42, array(284, 27)); //Stratford to Canary Wharf (following on) not via Westferry or Blackwall
draw_path(true);
$route = array(262, 225); //Tower Gateway to Shadwell
draw_path();
$route = array(307, 306, 305, 304, 43, 79); //King George V to Canning Town (following on)
draw_path(true);
}
$output_stations = '';
foreach($stations as $i => $station)
{
extract($station);
if(isset($tangents[$i]))
{
if($total_lines > 1 or $rail)
{
$output_stations .= plot_intersection($xpos, $ypos, $name);
}
else
{
$this_station = plot_station($xpos, $ypos, $i, $lines[$line]);
$output_lines .= $this_station[0];
$output_stripes .= $this_station[1];
}
$output_stations .= plot_stationname($xpos, $ypos, $name, $display_name, $rail);
}
}
$output = $header.'
<g id="lines">'.$output_lines.'
</g>';
if($stripe)
$output .= '
<g id="stripes">'.$output_stripes.'
</g>';
$output .= '
<g id="stations">'.$output_stations.'
</g>';
$output .= '
</svg>';
echo $output;
$file = fopen($this_line_name.'.svg', 'w+');
fwrite($file, $output);
fclose($file);
mysql_close($dbserverlink);
# --------------------------
function draw_path($follow_on = false)
{
global $output_lines, $output_stripes, $tangents, $stations, $route, $this_line, $lines;
$control_points = array();
for($i=0; $i<count($route); $i++)
{
if(!$i)
{
$dx = ($stations[$route[$i+1]]['xpos'] - $stations[$route[$i]]['xpos']);
$dy = ($stations[$route[$i+1]]['ypos'] - $stations[$route[$i]]['ypos']);
$cx = $stations[$route[$i]]['xpos'] + ($dx/3);
$cy = $stations[$route[$i]]['ypos'] + ($dy/3);
$tangents[$route[$i]] = $dy/$dx;
array_push($control_points, array('x' => $stations[$route[$i]]['xpos'], 'y' => $stations[$route[$i]]['ypos'])); #First station
array_push($control_points, array('x' => $cx, 'y' => $cy)); #First control point
}
else if($i+1 == count($route))
{
$dx = ($stations[$route[$i]]['xpos'] - $stations[$route[$i-1]]['xpos']);
$dy = ($stations[$route[$i]]['ypos'] - $stations[$route[$i-1]]['ypos']);
$cx = $stations[$route[$i]]['xpos'] - ($dx/3);
$cy = $stations[$route[$i]]['ypos'] - ($dy/3);
array_push($control_points, array('x' => $cx, 'y' => $cy)); #Last control point
array_push($control_points, array('x' => $stations[$route[$i]]['xpos'], 'y' => $stations[$route[$i]]['ypos'])); #Last station
$tangents[$route[$i]] = $dy/$dx;
}
else
{
$dx = ($stations[$route[$i+1]]['xpos'] - $stations[$route[$i-1]]['xpos']);
$dy = ($stations[$route[$i+1]]['ypos'] - $stations[$route[$i-1]]['ypos']);
$cx = $stations[$route[$i]]['xpos'] - ($dx/6);
$cy = $stations[$route[$i]]['ypos'] - ($dy/6);
array_push($control_points, array('x' => $cx, 'y' => $cy)); #Pre-station control point
array_push($control_points, array('x' => $stations[$route[$i]]['xpos'], 'y' => $stations[$route[$i]]['ypos'])); #Station
$tangents[$route[$i]] = $dy/$dx;
$cx = $stations[$route[$i]]['xpos'] + ($dx/6);
$cy = $stations[$route[$i]]['ypos'] + ($dy/6);
array_push($control_points, array('x' => $cx, 'y' => $cy)); #Post-station control point
}
}
extract($lines[$this_line]);
for($i=0; $i<count($control_points)-3; $i+=3)
{
if($follow_on and $i == count($control_points)-4)
break;
extract($control_points[$i], EXTR_PREFIX_ALL, 'st0');
extract($control_points[$i+1], EXTR_PREFIX_ALL, 'st1');
extract($control_points[$i+2], EXTR_PREFIX_ALL, 'st2');
extract($control_points[$i+3], EXTR_PREFIX_ALL, 'st3');
$end_line = false;
if(!$i or $i == count($control_points)-4)
$end_line = true;
$output_lines .= '
<path
d="M '.$st0_x.' '.$st0_y.' C '.$st1_x.' '.$st1_y.' '.$st2_x.' '.$st2_y.' '.$st3_x.' '.$st3_y.'"
style="stroke-width: 4.5; stroke: #'.$colour.'; fill: none;'.(!$end_line ? ' stroke-linecap: round;' : '').'" />';
if($stripe)
{
$output_stripes .= '
<path
d="M '.$st0_x.' '.$st0_y.' C '.$st1_x.' '.$st1_y.' '.$st2_x.' '.$st2_y.' '.$st3_x.' '.$st3_y.'"
style="stroke-width: 1.5; stroke: #'.$stripe.'; fill: none;'.(!$end_line ? ' stroke-linecap: round;' : '').'" />';
}
}
}
function find_path($line, $start, $end, $not_via = array(), $last_station = 0, $array = array(), $i=0)
{
array_push($array, $start);
$not_via_query = '';
if(count($not_via))
{
foreach($not_via as $not_via_station)
{
$not_via_query .= " AND (station1 <> $not_via_station AND station2 <> $not_via_station)";
}
}
$next_station = mysql_result(mysql_query("
SELECT (station1 + station2 - $start) AS next_station
FROM links
WHERE (station1 = $start OR station2 = $start)
AND (station1 <> $last_station AND station2 <> $last_station)
$not_via_query
AND line = $line"), 0);
if($next_station <> $end)
{
return find_path($line, $next_station, $end, $not_via, $start, $array, $i+1);
}
else
{
array_push($array, $end);
return $array;
}
}
function plot_intersection($xpos, $ypos, $name)
{
$name = htmlentities($name, ENT_QUOTES);
$output = '
<use id="'.$name.'" x="'.$xpos.'" y="'.$ypos.'" xlink:href="#intersection" />';
return $output;
}
function plot_station($xpos, $ypos, $i, $line)
{
global $tangents;
$output_stripes = '';
extract($line);
$ds = sqrt(1+$tangents[$i]*$tangents[$i]);
$dy = -1/$ds;
$dx = $tangents[$i]/$ds;
$output_lines = '
<line
x1="'.$xpos.'" y1="'.$ypos.'" x2="'.($xpos+(5*$dx)).'" y2="'.($ypos+(5*$dy)).'"
style="stroke-width: 4.5; stroke: #'.$colour.'; stroke-linecap: square;" />
<line
x1="'.$xpos.'" y1="'.$ypos.'" x2="'.($xpos-(5*$dx)).'" y2="'.($ypos-(5*$dy)).'"
style="stroke-width: 4.5; stroke: #'.$colour.'; stroke-linecap: square;" />';
if($stripe)
{
$output_stripes = '
<line
x1="'.$xpos.'" y1="'.$ypos.'" x2="'.($xpos+(5*$dx)).'" y2="'.($ypos+(5*$dy)).'"
style="stroke-width: 1.5; stroke: #'.$stripe.'; stroke-linecap: square;" />
<line
x1="'.$xpos.'" y1="'.$ypos.'" x2="'.($xpos-(5*$dx)).'" y2="'.($ypos-(5*$dy)).'"
style="stroke-width: 1.5; stroke: #'.$stripe.'; stroke-linecap: square;" />';
# $dy = $tangents[$i]/$ds;
# $dx = 1/$ds;
# $output .= '
# <line
# x1="'.($xpos-(2.25*$dx)).'" y1="'.($ypos-(2.25*$dy)).'" x2="'.($xpos+(2.25*$dx)).'" y2="'.($ypos+(2.25*$dy)).'"
# style="stroke-width: 1.5; stroke: #'.$stripe.'; stroke-linecap: square;" />';
}
return array($output_lines, $output_stripes);
}
function plot_stationname($xpos, $ypos, $name, $display_name, $rail)
{
$name = htmlentities($name, ENT_QUOTES);
$lines = split('<br />', ($display_name ? $display_name : $name));
$output = '';
$output .= '
<text x="'.($xpos+7).'" y="'.$ypos.'" style="font-family: Verdana; font-size: 11px;">';
foreach($lines as $line)
{
$output .= '
<tspan x="'.($xpos+7).'" y="'.($ypos+4).'">'.htmlentities($line, ENT_QUOTES).'</tspan>';
$ypos += 12;
}
$output .= '
</text>';
if($rail)
$output .= '
<use x="'.($xpos+40).'" y="'.($ypos-16).'" xlink:href="#rail" />';
return $output;
}
?>