9 Commits

Author SHA1 Message Date
cff62fa343 Remove 'checked' values from incomplete maps 2026-02-11 21:03:55 +00:00
f359938d78 Standardize junction abbreviation to Jn 2026-02-11 21:02:14 +00:00
7e68192312 Standardise & styles and improve performance on small displays.
Add inter-route linking from Junctions.
2026-02-11 20:58:01 +00:00
e94b0e811a Adjust sizes on manifest icons 2026-02-11 19:17:43 +00:00
04f6a28100 Provide new 'short_name' OB Maps to better fit on Android app drawer.
Update theme colour to accent colour to provide thematic separation of notification bar and header bar when running full screen on android.
2026-02-11 19:03:49 +00:00
54e3483a39 Include tabler icons and switch buttons to use icons 2026-02-11 19:01:24 +00:00
117d1f752e Switch to new resized logo with text 2026-02-11 18:37:10 +00:00
1207edf12b Add placeholders for next routes 2026-02-11 10:57:01 +00:00
b3d9eb6f33 Move to 'updated' and 'checked' dates, rather than 'created' 'checked & updated' 2026-02-11 10:52:15 +00:00
19 changed files with 858 additions and 91 deletions

29
package-lock.json generated
View File

@@ -13,6 +13,7 @@
"@sveltejs/adapter-node": "^5.5.2", "@sveltejs/adapter-node": "^5.5.2",
"@sveltejs/kit": "^2.50.1", "@sveltejs/kit": "^2.50.1",
"@sveltejs/vite-plugin-svelte": "^6.2.4", "@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tabler/icons-svelte": "^3.36.1",
"@types/node": "^22", "@types/node": "^22",
"eslint": "^9.39.2", "eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
@@ -1344,6 +1345,34 @@
"vite": "^6.3.0 || ^7.0.0" "vite": "^6.3.0 || ^7.0.0"
} }
}, },
"node_modules/@tabler/icons": {
"version": "3.36.1",
"resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.36.1.tgz",
"integrity": "sha512-f4Jg3Fof/Vru5ioix/UO4GX+sdDsF9wQo47FbtvG+utIYYVQ/QVAC0QYgcBbAjQGfbdOh2CCf0BgiFOF9Ixtjw==",
"dev": true,
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/codecalm"
}
},
"node_modules/@tabler/icons-svelte": {
"version": "3.36.1",
"resolved": "https://registry.npmjs.org/@tabler/icons-svelte/-/icons-svelte-3.36.1.tgz",
"integrity": "sha512-f48RDkXJr7dMbbWHho81rR91QiPleHTlOwJUM5uFhTqo7dXH4mNZxJo3tksQNmlIauh7PqoS3i+RY7YlZxg5yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@tabler/icons": ""
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/codecalm"
},
"peerDependencies": {
"svelte": ">=3 <6 || >=5.0.0-next.0"
}
},
"node_modules/@types/cookie": { "node_modules/@types/cookie": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",

View File

@@ -19,6 +19,7 @@
"@sveltejs/adapter-node": "^5.5.2", "@sveltejs/adapter-node": "^5.5.2",
"@sveltejs/kit": "^2.50.1", "@sveltejs/kit": "^2.50.1",
"@sveltejs/vite-plugin-svelte": "^6.2.4", "@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tabler/icons-svelte": "^3.36.1",
"@types/node": "^22", "@types/node": "^22",
"eslint": "^9.39.2", "eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",

View File

@@ -48,7 +48,7 @@ fs.readdirSync(inputDir).forEach((file) => {
routeId: content.routeId || null, routeId: content.routeId || null,
routeStart: content.routeStart || null, routeStart: content.routeStart || null,
routeEnd: content.routeEnd || null, routeEnd: content.routeEnd || null,
created: content.created || null, updated: content.updated || null,
checked: content.checked || null, checked: content.checked || null,
contents: Array.from(contentSet) contents: Array.from(contentSet)
}); });

View File

@@ -7,6 +7,7 @@
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"
/> />
<link rel="manifest" href="/manifest.webmanifest" /> <link rel="manifest" href="/manifest.webmanifest" />
<title>OwlBoard Maps</title>
%sveltekit.head% %sveltekit.head%
</head> </head>
<body data-sveltekit-preload-data="hover"> <body data-sveltekit-preload-data="hover">

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1,12 +1,19 @@
<script lang="ts"> <script lang="ts">
import { components } from '$lib/mapRegistry'; import { components } from '$lib/mapRegistry';
import type { ElecType } from '$lib/railStyles';
import { IconArrowNarrowRight } from '@tabler/icons-svelte';
export let feature: any; // Raw Object type featureType = "station" | "junction" | "crossovers" | "siteof" | "bridge" | "minorBridge" | "crossover" | "crossing" | "loop" | "loops" | "signallerChange" | "electrificationChange" | "default" | "tunnel";
export let activeElec: string; // Active Electrification Type export let feature: {name: string; type: featureType; goto?: string; entryPoint?: string; miles: number; chains: number; description?: string}; // Raw Object
export let activeElec: ElecType; // Active Electrification Type
export let reversed: boolean = false; export let reversed: boolean = false;
$: Icon = components[feature.type] || components.default; $: Icon = components[feature.type] || components.default;
// Linking Logic
$: isLinkable = !!(feature.goto && feature.entryPoint);
$: href = `/map/${feature.goto}#${feature.entryPoint}`;
const slugify = (str?: string) => const slugify = (str?: string) =>
str?.toLocaleLowerCase().trim().replace(/\s+/g, '-') ?? 'unknown'; str?.toLocaleLowerCase().trim().replace(/\s+/g, '-') ?? 'unknown';
</script> </script>
@@ -18,9 +25,10 @@
</div> </div>
<div class="icon-col"> <div class="icon-col">
<svelte:component this={Icon} {feature} {activeElec} {reversed} /> <svelte:component this={Icon} feature={feature as any} {activeElec} {reversed} />
</div> </div>
<svelte:element this={isLinkable ? 'a' : 'div'} {...(isLinkable ? { href } : {})} class="link-wrapper">
<div class="label-col"> <div class="label-col">
{#if feature.name} {#if feature.name}
<div class="feature-name">{feature.name}</div> <div class="feature-name">{feature.name}</div>
@@ -29,18 +37,31 @@
<div class="feature-desc">{feature.description}</div> <div class="feature-desc">{feature.description}</div>
{/if} {/if}
</div> </div>
{#if isLinkable}
<div class="link-indicator">
<IconArrowNarrowRight />
</div>
{/if}
</svelte:element>
</div> </div>
<style> <style>
a {
cursor: pointer;
text-decoration: none;
}
.row-container { .row-container {
display: grid; display: grid;
/* Balanced columns: 1fr on both sides keeps the 64px icon in the dead center */
grid-template-columns: 3.5rem 64px 1fr; grid-template-columns: 3.5rem 64px 1fr;
width: 100%; width: 100%;
height: 64px; height: 64px;
max-height: 64px;
align-items: center; align-items: center;
margin: 0; margin: 0;
padding: 0; padding: 0;
overflow: hidden;
} }
.mileage-col { .mileage-col {
@@ -50,7 +71,7 @@
padding-right: 12px; padding-right: 12px;
font-family: 'Courier New', Courier, monospace; font-family: 'Courier New', Courier, monospace;
font-size: 0.85rem; font-size: 0.85rem;
color: #64748b; /* Adjusted slightly for contrast */ color: #64748b;
} }
.miles { .miles {
@@ -62,13 +83,46 @@
font-size: 0.7rem; font-size: 0.7rem;
} }
.icon-col { .icon-col {
width: 64px; width: 64px;
height: 64px; height: 64px;
/* Ensure the icon itself is centered if the SVG is smaller than 64px */
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
overflow: hidden;
}
.link-wrapper {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
height: 100%;
text-decoration: none;
color: inherit;
padding: 0;
box-sizing: border-box;
}
.link-indicator {
display: flex;
align-items: center;
margin-left: 5px;
margin-right: 8px;
flex-shrink: 0;
color: #e1ebeb;
background-color: #3c6f79;
padding: 2px 2px;
border-radius: 999px;
transition: all 0.3s ease;
}
.link-wrapper:hover .link-indicator {
background-color: #404c55;
transform: rotate(-45deg);
} }
.label-col { .label-col {
@@ -76,20 +130,16 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
/* FIX: Allow children to manage their own wrapping */
overflow: hidden; overflow: hidden;
/* min-width: 0 is critical for flex children to allow truncation */
min-width: 0; min-width: 0;
} }
.feature-name { .feature-name {
font-weight: 700; font-weight: 700;
font-family: sans-serif;
color: #1e293b; color: #1e293b;
font-size: 0.8rem; font-size: 0.8rem;
text-transform: capitalize; text-transform: capitalize;
/* Allow the title to wrap naturally onto multiple lines */
white-space: normal; white-space: normal;
line-height: 1.2; line-height: 1.2;
margin-bottom: 2px; margin-bottom: 2px;
@@ -98,12 +148,11 @@
.feature-desc { .feature-desc {
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
font-family: sans-serif;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden; overflow: hidden;
/* Firefox Fix: Ensure white-space is normal here too */
white-space: normal; white-space: normal;
line-height: 1.2rem; line-height: 1.2rem;
max-height: 2.4rem; max-height: 2.4rem;
font-size: 0.75rem; font-size: 0.75rem;
@@ -111,21 +160,26 @@
word-break: break-word; word-break: break-word;
} }
/* Tablet and Desktop scaling */ @media (max-width: 320px) {
.feature-desc {
display: none;
}
}
@media (min-width: 480px) { @media (min-width: 480px) {
.feature-name { .feature-name {
font-size: 1rem; /* The larger title you requested */ font-size: 1rem;
margin-bottom: 4px; margin-bottom: 4px;
} }
.feature-desc { .feature-desc {
font-size: 0.85rem; /* Slightly larger desc to match */ font-size: 0.85rem;
line-height: 1.3rem; line-height: 1.3rem;
max-height: 2.6rem; max-height: 2.6rem;
} }
.label-col { .label-col {
padding-left: 24px; /* More "breathing room" on big screens */ padding-left: 24px;
} }
} }
</style> </style>

View File

@@ -9,10 +9,9 @@
$: type = feature.kind.toLowerCase(); $: type = feature.kind.toLowerCase();
$: isFoot = type === 'foot'; $: isFoot = type === 'foot';
$: filterCategory = isFoot ? 'foot' : type === 'uwc' ? 'uwc' : 'level-crossing';
</script> </script>
<svg viewBox="0 0 64 64" width="64" height="64" class={filterCategory}> <svg viewBox="0 0 64 64" width="64" height="64">
<BaseTrack {activeElec} height={64} /> <BaseTrack {activeElec} height={64} />
{#if type === 'foot'} {#if type === 'foot'}

View File

@@ -6,6 +6,8 @@
direction: 'up' | 'down'; direction: 'up' | 'down';
diverges: 'left' | 'right' | 'both'; diverges: 'left' | 'right' | 'both';
elecBranch?: string; elecBranch?: string;
goto?: string;
entryPoint?: string;
}; };
export let activeElec: any; export let activeElec: any;
export let reversed: boolean = false; export let reversed: boolean = false;

View File

@@ -1,12 +1,14 @@
<script lang="ts"> <script lang="ts">
import { IconArrowNarrowRight } from '@tabler/icons-svelte';
export let feature: { export let feature: {
routeName: string; routeName: string;
routeId: string; routeId: string;
entryPoint: string;
}; };
</script> </script>
<div class="link-wrapper"> <div class="link-wrapper">
<a href="/map/{feature.routeId}" class="wide-button"> <a href="/map/{feature.routeId}#{feature.entryPoint}" class="wide-button">
<div class="content"> <div class="content">
<div class="header-row"> <div class="header-row">
<span class="sub-text">Go to</span> <span class="sub-text">Go to</span>
@@ -16,16 +18,7 @@
</div> </div>
<div class="icon-circle"> <div class="icon-circle">
<svg viewBox="0 0 24 24" width="20" height="20"> <IconArrowNarrowRight />
<path
d="M5 12h14M12 5l7 7-7 7"
fill="none"
stroke="currentColor"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div> </div>
</a> </a>
</div> </div>
@@ -68,12 +61,14 @@
font-weight: 700; font-weight: 700;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
font-family: "urwgothic";
color: #64748b; color: #64748b;
} }
.route-id-chip { .route-id-chip {
font-size: 0.6rem; font-size: 0.6rem;
font-weight: 800; font-weight: 800;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
background: #f1f5f9; background: #f1f5f9;
color: #475569; color: #475569;
padding: 2px 6px; padding: 2px 6px;
@@ -82,6 +77,7 @@
} }
.main-text { .main-text {
font-family: "urwgothic";
font-size: 1rem; font-size: 1rem;
font-weight: 800; font-weight: 800;
color: #0f172a; color: #0f172a;
@@ -91,16 +87,15 @@
} }
.icon-circle { .icon-circle {
width: 40px;
height: 40px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: #f8fafc;
border-radius: 50%; color: #e1ebeb;
color: #94a3b8; background-color: #3c6f79;
padding: 4px 4px;
border-radius: 999px;
transition: all 0.3s ease; transition: all 0.3s ease;
margin-left: 12px;
} }
.wide-button:hover { .wide-button:hover {
@@ -110,8 +105,7 @@
} }
.wide-button:hover .icon-circle { .wide-button:hover .icon-circle {
background: #4f46e5; background-color: #404c55;
color: #ffffff;
transform: rotate(-45deg); transform: rotate(-45deg);
} }

View File

@@ -16,6 +16,7 @@ export const components = {
crossovers: Crossover, crossovers: Crossover,
siteof: SiteOf, siteof: SiteOf,
bridge: Bridge, bridge: Bridge,
minorBridge: Bridge,
crossover: Crossover, crossover: Crossover,
crossing: Crossing, crossing: Crossing,
loop: Loop, loop: Loop,

View File

@@ -84,9 +84,9 @@
</div> </div>
<div class="card-footer"> <div class="card-footer">
<span>Created on {formatDate(map.created)}</span> <span>Updated: {formatDate(map.updated)}</span>
{#if map.checked} {#if map.checked}
<span>• Checked & Updated on {formatDate(map.checked)}</span> <span>• Checked: {formatDate(map.checked)}</span>
{/if} {/if}
</div> </div>
</a> </a>

View File

@@ -4,7 +4,7 @@ export interface RouteMapIndex {
routeId: string | number; routeId: string | number;
routeStart: string; routeStart: string;
routeEnd: string; routeEnd: string;
created: string; updated: string;
checked: string; checked: string;
contents: string[]; contents: string[];
} }

View File

@@ -9,21 +9,21 @@ export const prerender = true;
export const GET: RequestHandler = ({ url }) => { export const GET: RequestHandler = ({ url }) => {
const manifest = { const manifest = {
name: 'OwlBoard Maps', name: 'OwlBoard Maps',
short_name: 'OwlBoard Maps', short_name: 'OB Maps',
start_url: '/', start_url: '/',
display: 'standalone', display: 'standalone',
theme_color: '#3c6f79', theme_color: '#4fd1d1',
background_color: '#3d4952', background_color: '#3d4952',
icons: [ icons: [
{ {
src: logo, src: logo,
sizes: 'any', sizes: '48x48 72x72 96x96 128x128 256x256 512x512 any',
type: 'image/svg+xml', type: 'image/svg+xml',
purpose: 'any' purpose: 'any'
}, },
{ {
src: maskableLogo, src: maskableLogo,
sizes: 'any', sizes: '48x48 72x72 96x96 128x128 256x256 512x512 any',
type: 'image/svg+xml', type: 'image/svg+xml',
purpose: 'maskable' purpose: 'maskable'
}, },

View File

@@ -5,6 +5,7 @@
import { resolve } from '$app/paths'; import { resolve } from '$app/paths';
import logo from '$lib/assets/round-logo.svg'; import logo from '$lib/assets/round-logo.svg';
import { IconArrowsExchange, IconSettings } from '@tabler/icons-svelte';
// data.route contains: routeStart, routeEnd, routeId, elecStart, elecEnd, routeDetail[] // data.route contains: routeStart, routeEnd, routeId, elecStart, elecEnd, routeDetail[]
export let data; export let data;
@@ -13,6 +14,7 @@
let visibleTypes = { let visibleTypes = {
station: true, station: true,
minorBridge: false,
bridge: true, bridge: true,
crossovers: true, crossovers: true,
loop: true, loop: true,
@@ -20,7 +22,8 @@
electrificationChange: true, electrificationChange: true,
siteof: true, siteof: true,
junction: true, junction: true,
tunnel: true tunnel: true,
crossing: true,
}; };
let showFilters = false; let showFilters = false;
@@ -73,7 +76,8 @@
{reversed ? data.route.routeEnd : data.route.routeStart} {reversed ? data.route.routeEnd : data.route.routeStart}
</h1> </h1>
<span class="secondary-station"> <span class="secondary-station">
to {reversed ? data.route.routeStart : data.route.routeEnd} <span class="route-stack-to">
to</span> {reversed ? data.route.routeStart : data.route.routeEnd}
</span> </span>
{/if} {/if}
</div> </div>
@@ -81,9 +85,9 @@
<div class="quick-actions"> <div class="quick-actions">
<button class="icon-btn" onclick={() => (reversed = !reversed)}> <button class="icon-btn" onclick={() => (reversed = !reversed)}>
{reversed ? 'UP' : 'DN'} <IconArrowsExchange />
</button> </button>
<button class="icon-btn" onclick={() => (showFilters = !showFilters)}> Settings </button> <button class="icon-btn" onclick={() => (showFilters = !showFilters)}> <IconSettings /> </button>
</div> </div>
</header> </header>
@@ -183,11 +187,20 @@
width: 52px; width: 52px;
height: 52px; height: 52px;
padding-left: 0; padding-left: 0;
margin-left: 0; margin-left: 15px;
margin-right: 0;
padding-right: 0;
flex-shrink: 0; flex-shrink: 0;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
@media (max-width: 350px) {
.home-link {
width: 42px;
height: 42px;
}
}
.home-link:hover { .home-link:hover {
transform: translateY(-1px) scale(1.05); transform: translateY(-1px) scale(1.05);
filter: brightness(1.1); filter: brightness(1.1);
@@ -199,8 +212,14 @@
.route-stack { .route-stack {
display: flex; display: flex;
font-family: "urwgothic";
flex-direction: column; flex-direction: column;
min-width: 0; min-width: 0;
margin-left: 0;
}
.route-stack-to {
text-transform: lowercase;
} }
.primary-station { .primary-station {
@@ -216,32 +235,30 @@
.secondary-station { .secondary-station {
font-size: 0.7rem; font-size: 0.7rem;
color: #cce9e9; color: #cce9e9;
text-transform: uppercase; text-transform: capitalize;
font-weight: 600; font-weight: 600;
} }
.quick-actions { .quick-actions {
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
margin-right: 15px;
} }
.map-spine { .map-spine {
padding-top: 72px; padding-top: 72px;
} }
@media (min-width: 768px) { @media (min-width: 536px) {
.primary-station { .primary-station {
font-size: 1.5rem; font-size: 1.5rem;
} }
.secondary-station { .secondary-station {
font-size: 1rem; font-size: 1rem;
} }
}
.top-nav { @media (min-width: 768px) {
padding: 0 2rem;
height: 80px;
}
h1 { h1 {
font-size: 1.5rem; font-size: 1.5rem;
letter-spacing: -0.03em; letter-spacing: -0.03em;
@@ -358,6 +375,12 @@
transition: all 0.3s ease; transition: all 0.3s ease;
} }
@media (max-width: 390px) {
.icon-btn {
padding: 0.3rem 0.3rem;
}
}
.icon-btn:hover { .icon-btn:hover {
background: #2d2d2d; background: #2d2d2d;
} }

View File

@@ -1,7 +1,7 @@
routeStart: Paddington routeStart: Paddington
routeEnd: Reading routeEnd: Reading
routeId: 0001 routeId: 0001
created: 2026-02-04 updated: 2026-02-09
checked: 2026-02-09 checked: 2026-02-09
signallerStart: TVSC Paddington WS signallerStart: TVSC Paddington WS
signallerEnd: TVSC Reading WS signallerEnd: TVSC Reading WS
@@ -52,7 +52,7 @@ routeDetail:
chains: 52 chains: 52
- type: crossovers - type: crossovers
name: Subway Junction name: Subway Jn
miles: 0 miles: 0
chains: 61 chains: 61
@@ -85,7 +85,7 @@ routeDetail:
chains: 18 chains: 18
- type: junction - type: junction
name: Westbourne Park Junction name: Westbourne Park Jn
diverges: left diverges: left
direction: up direction: up
description: to Crossrail Core Operating Section description: to Crossrail Core Operating Section
@@ -93,7 +93,7 @@ routeDetail:
chains: 21 chains: 21
- type: crossovers - type: crossovers
name: Portobello Junction name: Portobello Jn
miles: 1 miles: 1
chains: 33 chains: 33
@@ -120,7 +120,7 @@ routeDetail:
chains: 73 chains: 73
- type: junction - type: junction
name: Kensal Green East Junction name: Kensal Green East Jn
diverges: both diverges: both
direction: down direction: down
description: to Crossrail & North Pole Depots description: to Crossrail & North Pole Depots
@@ -177,7 +177,7 @@ routeDetail:
chains: 45 chains: 45
- type: junction - type: junction
name: Friars Junction name: Friars Jn
diverges: left diverges: left
direction: up direction: up
elecBranch: none elecBranch: none
@@ -207,7 +207,7 @@ routeDetail:
chains: 80 chains: 80
- type: junction - type: junction
name: Acton East Junction name: Acton East Jn
diverges: left diverges: left
direction: up direction: up
description: Up/Dn Poplar to Acton Wells Jn description: Up/Dn Poplar to Acton Wells Jn
@@ -312,7 +312,7 @@ routeDetail:
chains: 46 chains: 46
- type: junction - type: junction
name: West Ealing Junction name: West Ealing Jn
diverges: left diverges: left
direction: down direction: down
elecBranch: none elecBranch: none
@@ -328,7 +328,7 @@ routeDetail:
chains: 71 chains: 71
- type: junction - type: junction
name: Hanwell Junction name: Hanwell Jn
diverges: left diverges: left
direction: up direction: up
elecBranch: none elecBranch: none
@@ -394,7 +394,7 @@ routeDetail:
chains: 46 chains: 46
- type: junction - type: junction
name: Southall East Junction name: Southall East Jn
diverges: right diverges: right
direction: up direction: up
elecBranch: none elecBranch: none
@@ -423,7 +423,7 @@ routeDetail:
chains: 53 chains: 53
- type: crossovers - type: crossovers
name: Southall West Junction name: Southall West Jn
description: Southall Sidings Diverge description: Southall Sidings Diverge
miles: 9 miles: 9
chains: 70 chains: 70
@@ -490,7 +490,7 @@ routeDetail:
chains: 77 chains: 77
- type: junction - type: junction
name: Heathrow Airport Junction name: Heathrow Airport Jn
diverges: both diverges: both
direction: down direction: down
miles: 11 miles: 11
@@ -506,7 +506,7 @@ routeDetail:
chains: 28 chains: 28
- type: crossovers - type: crossovers
name: Stockley Bridge Junction name: Stockley Bridge Jn
miles: 12 miles: 12
chains: 9 chains: 9
@@ -519,7 +519,7 @@ routeDetail:
chains: 22 chains: 22
- type: crossovers - type: crossovers
name: West Drayton East Junction name: West Drayton East Jn
miles: 12 miles: 12
chains: 67 chains: 67
@@ -544,7 +544,7 @@ routeDetail:
chains: 56 chains: 56
- type: junction - type: junction
name: West Drayton Junction name: West Drayton Jn
diverges: left diverges: left
direction: down direction: down
description: Colnbrook Freight (near Heathrow) description: Colnbrook Freight (near Heathrow)
@@ -725,7 +725,7 @@ routeDetail:
chains: 42 chains: 42
- type: junction - type: junction
name: Windsor Branch Junction name: Windsor Branch Jn
diverges: right diverges: right
direction: down direction: down
description: Windsor Branch from platforms 1 & 2 Only description: Windsor Branch from platforms 1 & 2 Only
@@ -1048,7 +1048,7 @@ routeDetail:
chains: 1 chains: 1
- type: junction - type: junction
name: Henley Branch Junction name: Henley Branch Jn
diverges: left diverges: left
direction: down direction: down
description: Henley-on-Thames from Platform 4 only description: Henley-on-Thames from Platform 4 only
@@ -1169,7 +1169,7 @@ routeDetail:
chains: 77 chains: 77
- type: crossovers - type: crossovers
name: Kennet Bridge Junction name: Kennet Bridge Jn
miles: 35 miles: 35
chains: 10 chains: 10
@@ -1182,7 +1182,7 @@ routeDetail:
chains: 28 chains: 28
- type: junction - type: junction
name: Reading New Junction name: Reading New Jn
diverges: right diverges: right
direction: up direction: up
elecBranch: none elecBranch: none
@@ -1199,7 +1199,7 @@ routeDetail:
chains: 40 chains: 40
- type: junction - type: junction
name: Reading East Junction name: Reading East Jn
diverges: left diverges: left
direction: up direction: up
elecBranch: none elecBranch: none
@@ -1222,3 +1222,4 @@ routeDetail:
- type: continues - type: continues
routeName: Reading - Bristol TM routeName: Reading - Bristol TM
routeId: '0002' routeId: '0002'
entryPoint: reading

View File

@@ -1,7 +1,7 @@
routeStart: Reading routeStart: Reading
routeEnd: Bristol TM routeEnd: Bristol TM
routeId: 0002 routeId: 0002
created: 2026-02-04 updated: 2026-02-04
checked: checked:
signallerStart: TVSC Reading WS signallerStart: TVSC Reading WS
signallerEnd: TVSC Temple Meads WS signallerEnd: TVSC Temple Meads WS
@@ -14,6 +14,7 @@ routeDetail:
- type: continues - type: continues
routeName: Paddington - Reading routeName: Paddington - Reading
routeId: '0001' routeId: '0001'
entryPoint: reading
- type: station - type: station
name: Reading name: Reading
@@ -30,21 +31,25 @@ routeDetail:
- type: junction - type: junction
diverges: right diverges: right
direction: down direction: down
name: Westbury Line Junction name: Westbury Line Jn
description: to Oxford Road Jn description: to Oxford Road Jn
goto: "0201"
entryPoint: "oxford-road-jn"
miles: 36 miles: 36
chains: 17 chains: 17
- type: junction - type: junction
diverges: right diverges: right
direction: down direction: down
name: Caversham Road Junction name: Caversham Road Jn
description: Reading Feeder Main/Relief diverge and pass under Reading Viaduct to Oxford Rd Jn description: Reading Feeder Main/Relief diverge and pass under Reading Viaduct to Oxford Rd Jn
goto: "0201"
entryPoint: "oxford-road-jn"
miles: 36 miles: 36
chains: 22 chains: 22
- type: crossovers - type: crossovers
name: Reading High Level Junction name: Reading High Level Jn
description: Down Reading Festival Connects to Down Main description: Down Reading Festival Connects to Down Main
miles: 36 miles: 36
chains: 47 chains: 47
@@ -52,7 +57,9 @@ routeDetail:
- type: junction - type: junction
diverges: right diverges: right
direction: up direction: up
name: Reading West Junction name: Reading West Jn
description: to Oxford Road Junction (From relief lines only) description: to Oxford Road Junction (From relief lines only)
goto: "0201"
entryPoint: "oxford-road-jn"
miles: 37 miles: 37
chains: 17 chains: 17

View File

@@ -0,0 +1,12 @@
routeStart: Swindon Junction
routeEnd: Standish Junction
routeId: 0230
updated: 2026-02-11
checked:
signallerStart: TVSC Swindon WS
signallerEnd: Gloucester PSB
elecStart:
elec: 25kvac
eco: Didcot (TVSC)
elecEnd:
elec: none

View File

@@ -1,8 +1,8 @@
routeStart: Wootton Bassett Junction routeStart: Wootton Bassett Jn
routeEnd: Stoke Gifford Junction routeEnd: Stoke Gifford Jn
routeId: 0240 routeId: 0240
created: 2026-02-10 updated: 2026-02-11
checked: checked: 2026-02-11
signallerStart: TVSC Swindon WS signallerStart: TVSC Swindon WS
signallerEnd: TVSC Stoke Gifford WS signallerEnd: TVSC Stoke Gifford WS
elecStart: elecStart:
@@ -14,9 +14,640 @@ elecEnd:
routeDetail: routeDetail:
- type: continues - type: continues
routeName: Reading - Bristol TM routeName: Reading - Bristol TM
entryPoint: wootton-bassett-junction entryPoint: wootton-bassett-jn
routeId: '0002' routeId: '0002'
- type: junction
diverges: right
direction: down
name: Wootton Basset Jn
description: to Chippenham & Bristol via Bath
goto: "0002"
entryPoint: wootton-bassett-jn
miles: 83
chains: 7
- type: loop
name: Up Wootton Basset Goods Line
description: Loop spans junction
position: left
miles: 83
chains: 10
- type: bridge
position: over
name: Bath Road
roadName: A3102
category: aroad
miles: 83
chains: 29
- type: crossovers
name: Wootton Basset West
miles: 84
chains: 7
- type: minorBridge
name: Whitehill Lane
position: under
category: road
miles: 84
chains: 13
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 84
chains: 39
- type: bridge
position: over
name: Motorway
roadName: M4
category: motorway
miles: 84
chains: 50
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 85
chains: 15
- type: minorBridge
position: over
name: Callow Hill
category: road
miles: 85
chains: 29
- type: minorBridge
name: Farm Bridge
position: over
category: road
miles: 85
chains: 58
- type: minorBridge
name: Brinkworth Brooklands
position: over
category: road
miles: 86
chains: 75
- type: crossing
kind: foot
name: Brinkworth Foot Crossing
miles: 87
chains: 17
- type: minorBridge
name: Farm Bridge
category: road
position: over
miles: 88
chains: 12
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 88
chains: 46
- type: minorBridge
name: School Hill
position: under
category: road
miles: 88
chains: 66
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 89
chains: 9
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 89
chains: 29
- type: minorBridge
name: Idover Lane
position: under
category: road
miles: 89
chains: 46
- type: minorBridge
name: The Street
position: under
category: road
miles: 89
chains: 70
- type: bridge
name: River Avon
position: under
category: waterway
miles: 90
chains: 26
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 90
chains: 60
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 91
chains: 36
- type: minorBridge
name: Startley Road
position: under
category: road
miles: 91
chains: 50
- type: minorBridge
name: Rodbourne Lane
description: or 'Pound Hill'
position: under
category: road
miles: 92
chains: 2
- type: minorBridge
name: Cabbage Lane
position: over
category: road
miles: 92
chains: 28
- type: crossing
name: Kingway Barn Foot Crossing
kind: foot
miles: 93
chains: 7
- type: bridge
name: Kingway
position: under
category: aroad
roadName: A429
miles: 93
chains: 30
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 93
chains: 70
- type: loop
position: right
name: Down Hullavington Goods Loop
miles: 94
chains: 5
- type: minorBridge
position: under
name: Court Farm
category: road
miles: 94
chains: 9
- type: minorBridge
position: under
name: Bradfield Cottages
category: road
miles: 94
chains: 27
- type: loop
name: Up Hullavington Goods Loop
position: left
miles: 94
chains: 42
- type: crossovers
name: Hullavington
miles: 94
chains: 45
- type: minorBridge
name: Gills Hunting
position: over
category: road
miles: 94
chains: 62
- type: bridge
name: Aqueduct
position: over
category: stream
miles: 95
chains: 22
- type: minorBridge
name: Happy Lands
position: over
category: road
miles: 95
chains: 40
- type: minorBridge
name: Pig Lane
position: over
category: road
miles: 95
chains: 69
- type: minorBridge
name: Fosse Way
category: road
position: over
miles: 96
chains: 47
- type: minorBridge
name: Pipeline
category: pipeline
position: over
miles: 96
chains: 48
- type: minorBridge
name: Footbridge
position: over
category: foot
miles: 96
chains: 64
- type: tunnel
name: Alterton Tunnel
tunnelType: whole
length: 0mi 506yd
miles: 97
chains: 46
- type: signallerChange
from: TVSC Swindon WS (SW)
to: TVSC Stoke Gifford WS (BL)
miles: 98
chains: 0
- type: minorBridge
name: Footbridge
category: foot
position: over
miles: 98
chains: 2
- type: minorBridge
name: Footbridge
category: foot
positon: over
miles: 98
chains: 17
- type: minorBridge
name: Alderton Road
position: over
category: road
miles: 98
chains: 40
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 98
chains: 76
- type: minorBridge
name: Farm Bridge
position: under
category: road
miles: 99
chains: 7
- type: minorBridge
name: Footbridge
category: foot
position: over
miles: 99
chains: 40
- type: bridge
name: Luckington Road
category: road
roadName: B4040
position: over
miles: 99
chains: 46
- type: minorBridge
name: Footbridge
category: foot
position: over
miles: 99
chains: 59
- type: siteof
name: Badminton
side: centre
miles: 100
chains: 1
- type: bridge
name: Station Road
position: over
category: road
miles: 100
chains: 4
- type: minorBridge
name: Footbridge
category: foot
position: over
miles: 100
chains: 33
- type: bridge
name: Aqueduct
position: over
category: stream
miles: 100
chains: 57
- type: minorBridge
name: Footbridge
category: foot
position: over
miles: 100
chains: 65
- type: tunnel
tunnelType: whole
length: 2mi 926yd
name: Chipping Sodbury Tunnel
miles: 102
chains: 21
description: 10 telephones on Up side
- type: minorBridge
position: over
name: Footbridge
category: foot
miles: 103
chains: 63
- type: bridge
name: Frome Bridge
position: over
category: stream
miles: 103
chains: 75
- type: minorBridge
name: Colt's Green Bridge
category: road
position: over
miles: 104
chains: 19
- type: loop
name: Chipping Sodbury Goods Loop
position: left
description: Bidirectional with access to Chipping Sodbury Sidings
miles: 104
chains: 31
- type: minorBridge
name: Farm Bridge
category: road
position: over
miles: 104
chains: 56
- type: minorBridge
name: Kingrove Lane
position: over
category: road
miles: 104
chains: 77
- type: bridge
name: Aqueduct
position: over
category: stream
miles: 105
chains: 18
- type: minorBridge
name: Dodington Road
category: road
position: over
miles: 105
chains: 19
- type: bridge
name: Aqueduct
category: stream
position: over
miles: 105
chains: 38
- type: minorBridge
name: Footbridge
category: foot
position: over
miles: 106
chains: 32
- type: bridge
name: Westerleigh Road
category: road
position: under
miles: 107
chains: 4
- type: junction
diverges: left
direction: up
name: Westerleigh Jn
miles: 107
chains: 14
description: Up/Dn Charfield towards Gloucester
- type: bridge
name: Westerleigh Branch
category: rail
position: under
miles: 107
chains: 15
- type: minorBridge
name: Dodmoor Farm
category: road
position: under
miles: 107
chains: 33
- type: minorBridge
name: Farm Bridge
category: road
position: under
miles: 107
chains: 70
- type: minorBridge
name: Boxhenge Farm Lane
category: road
position: under
miles: 108
chains: 10
- type: minorBridge
name: The Dramway
position: over
category: foot
miles: 108
chains: 25
- type: minorBridge
name: Henfield Road
position: under
category: road
miles: 107
chains: 52
- type: bridge
name: Bristol Road
category: aroad
position: under
roadName: A432
miles: 108
chains: 78
- type: minorBridge
name: Park Lane
position: under
category: road
miles: 109
chains: 27
- type: bridge
name: Upford Viaduct
positon: under
category: waterway
miles: 109
chains: 58
- type: minorBridge
name: Hicks Common Lane
position: over
category: road
miles: 109
chains: 71
- type: minorBridge
name: Down Road
category: road
position: over
miles: 110
chains: 15
- type: minorBridge
name: Mill Lane
category: road
position: under
miles: 110
chains: 24
- type: bridge
name: Winterbourne Viaduct
category: road
position: under
miles: 110
chains: 38
- type: minorBridge
name: Farm Bridge
category: road
position: under
miles: 110
chains: 48
- type: bridge
name: M4 Motorway
category: motorway
roadName: M4
position: under
miles: 110
chains: 63
- type: minorBridge
name: Old Gloucester Road
category: road
roadName: B4427
position: under
miles: 110
chains: 70
- type: minorBridge
name: Curtis Lane
position: over
category: road
miles: 111
chains: 14
- type: crossovers
name: Stoke Gifford East Jn
miles: 111
chains: 20
- type: minorBridge
name: Pearson's Brick Yard
category: road
position: over
miles: 111
chains: 32
- type: station
name: Bristol Parkway
description: Stoke Gifford Dn Sidings on Down side
miles: 111
chains: 62
- type: bridge
name: Bristol Road
category: road
position: under
miles: 111
chains: 77
- type: junction
name: Stoke Gifford No.1 Jn
diverges: right
direction: down
description: Up/Dn Filton & Bristol TM
miles: 111
chains: 79
- type: continues - type: continues
routeName: Bristol TM - Cardiff West Shunt routeName: Bristol TM - Cardiff West Shunt
entryPoint: patchway-junction entryPoint: patchway-junction

View File

@@ -0,0 +1,12 @@
routeStart: Westerleigh Jn
routeEnd: Gloucester
routeId: 2420
updated: 2026-02-11
checked:
signallerStart: TVSC Swindon WS
signallerEnd: Gloucester PSB
elecStart:
elec: 25kvac
eco: Didcot (TVSC)
elecEnd:
elec: none