diff --git a/public/images/facilities/airport_london.svg b/public/images/facilities/airport_london.svg
new file mode 100644
index 00000000..3993d978
--- /dev/null
+++ b/public/images/facilities/airport_london.svg
@@ -0,0 +1,5 @@
+
diff --git a/public/images/facilities/coach_station_london.svg b/public/images/facilities/coach_station_london.svg
new file mode 100644
index 00000000..d816ac93
--- /dev/null
+++ b/public/images/facilities/coach_station_london.svg
@@ -0,0 +1,17 @@
+
diff --git a/public/images/facilities/river_craft.svg b/public/images/facilities/river_craft.svg
new file mode 100644
index 00000000..69d99f9a
--- /dev/null
+++ b/public/images/facilities/river_craft.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/components/panels/details/specific-attrs.tsx b/src/components/panels/details/specific-attrs.tsx
index c63743e9..44dea9e6 100644
--- a/src/components/panels/details/specific-attrs.tsx
+++ b/src/components/panels/details/specific-attrs.tsx
@@ -1,6 +1,6 @@
import { Text } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
-import { MiscNodeId, StnId } from '../../../constants/constants';
+import { AttrsProps, MiscNodeId, StnId } from '../../../constants/constants';
import { useRootDispatch, useRootSelector } from '../../../redux';
import { saveGraph } from '../../../redux/param/param-slice';
import { refreshEdgesThunk, refreshNodesThunk } from '../../../redux/runtime/runtime-slice';
@@ -18,7 +18,7 @@ export const NodeSpecificAttributes = () => {
const [id] = selected;
const type = window.graph.getNodeAttribute(id, 'type');
- const AttrsComponent = type in nodes && nodes[type].attrsComponent;
+ const AttrsComponent = type in nodes && (nodes[type].attrsComponent as React.FC>);
const attrs = (window.graph.getNodeAttribute(id, type) ?? {}) as any;
const handleAttrsUpdate = (selectedFirst: string, attrs: any) => {
diff --git a/src/components/svg-canvas-graph.tsx b/src/components/svg-canvas-graph.tsx
index 569c4793..1bf7b9a4 100644
--- a/src/components/svg-canvas-graph.tsx
+++ b/src/components/svg-canvas-graph.tsx
@@ -27,6 +27,13 @@ import singleColor from './svgs/lines/styles/single-color';
import miscNodes from './svgs/nodes/misc-nodes';
import { default as stations } from './svgs/stations/stations';
+const connectableNodesType = [
+ ...Object.values(StationType),
+ MiscNodeType.Virtual,
+ MiscNodeType.Master,
+ MiscNodeType.LondonArrow,
+];
+
const SvgCanvas = () => {
const dispatch = useRootDispatch();
const graph = React.useRef(window.graph);
@@ -114,7 +121,6 @@ const SvgCanvas = () => {
if (mode.startsWith('line')) {
if (!keepLastPath) dispatch(setMode('free'));
- const connectableNodesType = [...Object.values(StationType), MiscNodeType.Virtual, MiscNodeType.Master];
const couldActiveBeConnected =
graph.current.hasNode(active) &&
connectableNodesType.includes(graph.current.getNodeAttribute(active, 'type'));
diff --git a/src/components/svgs/lines/lines.ts b/src/components/svgs/lines/lines.ts
index ac49f1c7..409e1095 100644
--- a/src/components/svgs/lines/lines.ts
+++ b/src/components/svgs/lines/lines.ts
@@ -25,6 +25,10 @@ import lrtSingleColor from './styles/lrt-single-color';
import londonTubeInternalInt from './styles/london-tube-internal-int';
import londonTube10MinWalk from './styles/london-tube-10-min-walk';
import londonTubeTerminal from './styles/london-tube-terminal';
+import londonRail from './styles/london-rail';
+import londonSandwich from './styles/london-sandwich';
+import londonLutonAirportDART from './styles/london-DART';
+import londonIFSCloudCableCar from './styles/london-ifs-could-cable-car';
import guangdongIntercityRailway from './styles/guangdong-intercity-railway';
export const linePaths = {
@@ -57,5 +61,9 @@ export const lineStyles = {
[LineStyleType.LondonTubeTerminal]: londonTubeTerminal,
[LineStyleType.LondonTubeInternalInt]: londonTubeInternalInt,
[LineStyleType.LondonTube10MinWalk]: londonTube10MinWalk,
+ [LineStyleType.LondonRail]: londonRail,
+ [LineStyleType.LondonSandwich]: londonSandwich,
+ [LineStyleType.LondonLutonAirportDART]: londonLutonAirportDART,
+ [LineStyleType.LondonIFSCloudCableCar]: londonIFSCloudCableCar,
[LineStyleType.GuangdongIntercityRailway]: guangdongIntercityRailway,
};
diff --git a/src/components/svgs/lines/styles/dual-color.tsx b/src/components/svgs/lines/styles/dual-color.tsx
index ddd6bccf..100b3b6b 100644
--- a/src/components/svgs/lines/styles/dual-color.tsx
+++ b/src/components/svgs/lines/styles/dual-color.tsx
@@ -88,15 +88,17 @@ const DualColorSwitch = () => {
};
const dualColorAttrsComponent = (props: AttrsProps) => {
+ const { t } = useTranslation();
+
const fields: RmgFieldsField[] = [
{
type: 'custom',
- label: 'panel.details.lines.dualColor.swap',
+ label: t('panel.details.lines.dualColor.swap'),
component: ,
},
{
type: 'custom',
- label: 'panel.details.lines.dualColor.colorA',
+ label: t('panel.details.lines.dualColor.colorA'),
component: (
) => {
},
{
type: 'custom',
- label: 'panel.details.lines.dualColor.colorB',
+ label: t('panel.details.lines.dualColor.colorB'),
component: (
) => {
+ const { id, path, styleAttrs, handlePointerDown } = props;
+ const { color = defaultLondonLutonAirportDARTAttributes.color } =
+ styleAttrs ?? defaultLondonLutonAirportDARTAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+
+ return (
+
+
+
+
+ );
+};
+
+/**
+ * LondonLutonAirportDART specific props.
+ */
+export interface LondonLutonAirportDARTAttributes extends LinePathAttributes, AttributesWithColor {}
+
+const defaultLondonLutonAirportDARTAttributes: LondonLutonAirportDARTAttributes = {
+ color: [CityCode.London, 'rail', '#d6ae00', MonoColour.white],
+};
+
+const londonLutonAirportDARTAttrsComponent = (props: AttrsProps) => {
+ const { t } = useTranslation();
+
+ const fields: RmgFieldsField[] = [
+ {
+ type: 'custom',
+ label: t('color'),
+ component: (
+
+ ),
+ },
+ ];
+
+ return ;
+};
+
+const londonLutonAirportDART: LineStyle = {
+ component: LondonLutonAirportDART,
+ defaultAttrs: defaultLondonLutonAirportDARTAttributes,
+ attrsComponent: londonLutonAirportDARTAttrsComponent,
+ metadata: {
+ displayName: 'panel.details.lines.londonLutonAirportDART.displayName',
+ supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
+ },
+};
+
+export default londonLutonAirportDART;
diff --git a/src/components/svgs/lines/styles/london-ifs-could-cable-car.tsx b/src/components/svgs/lines/styles/london-ifs-could-cable-car.tsx
new file mode 100644
index 00000000..e1271bf0
--- /dev/null
+++ b/src/components/svgs/lines/styles/london-ifs-could-cable-car.tsx
@@ -0,0 +1,72 @@
+import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
+import { MonoColour } from '@railmapgen/rmg-palette-resources';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { AttrsProps, CityCode } from '../../../../constants/constants';
+import {
+ LinePathAttributes,
+ LinePathType,
+ LineStyle,
+ LineStyleComponentProps,
+ LineStyleType,
+} from '../../../../constants/lines';
+import { AttributesWithColor, ColorField } from '../../../panels/details/color-field';
+
+const LondonIFSCloudCableCar = (props: LineStyleComponentProps) => {
+ const { id, path, styleAttrs, handlePointerDown } = props;
+ const { color = defaultLondonIFSCloudCableCarAttributes.color } =
+ styleAttrs ?? defaultLondonIFSCloudCableCarAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+
+ return (
+
+
+
+
+
+ );
+};
+
+/**
+ * LondonIFSCloudCableCar specific props.
+ */
+export interface LondonIFSCloudCableCarAttributes extends LinePathAttributes, AttributesWithColor {}
+
+const defaultLondonIFSCloudCableCarAttributes: LondonIFSCloudCableCarAttributes = {
+ color: [CityCode.London, 'dangleway', '#dc241f', MonoColour.white],
+};
+
+const LondonIFSCloudCableCarAttrsComponent = (props: AttrsProps) => {
+ const { t } = useTranslation();
+
+ const fields: RmgFieldsField[] = [
+ {
+ type: 'custom',
+ label: t('color'),
+ component: (
+
+ ),
+ },
+ ];
+
+ return ;
+};
+
+const londonIFSCloudCableCar: LineStyle = {
+ component: LondonIFSCloudCableCar,
+ defaultAttrs: defaultLondonIFSCloudCableCarAttributes,
+ attrsComponent: LondonIFSCloudCableCarAttrsComponent,
+ metadata: {
+ displayName: 'panel.details.lines.londonIFSCloudCableCar.displayName',
+ supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
+ },
+};
+
+export default londonIFSCloudCableCar;
diff --git a/src/components/svgs/lines/styles/london-rail.tsx b/src/components/svgs/lines/styles/london-rail.tsx
new file mode 100644
index 00000000..80743033
--- /dev/null
+++ b/src/components/svgs/lines/styles/london-rail.tsx
@@ -0,0 +1,110 @@
+import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
+import { MonoColour } from '@railmapgen/rmg-palette-resources';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { AttrsProps, CityCode, Theme } from '../../../../constants/constants';
+import {
+ LinePathAttributes,
+ LinePathType,
+ LineStyle,
+ LineStyleComponentProps,
+ LineStyleType,
+} from '../../../../constants/lines';
+import { ColorField } from '../../../panels/details/color-field';
+
+const LondonRail = (props: LineStyleComponentProps) => {
+ const { id, path, styleAttrs, handlePointerDown } = props;
+ const {
+ colorBackground = defaultLondonRailAttributes.colorBackground,
+ colorForeground = defaultLondonRailAttributes.colorForeground,
+ limitedService = defaultLondonRailAttributes.limitedService,
+ } = styleAttrs ?? defaultLondonRailAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+
+ return !limitedService ? (
+
+
+
+
+ ) : (
+
+
+
+
+
+ );
+};
+
+/**
+ * LondonRail specific props.
+ */
+export interface LondonRailAttributes extends LinePathAttributes {
+ colorBackground: Theme;
+ colorForeground: Theme;
+ limitedService: boolean;
+}
+
+const defaultLondonRailAttributes: LondonRailAttributes = {
+ colorBackground: [CityCode.London, 'thameslink', '#d28db0', MonoColour.white],
+ colorForeground: [CityCode.London, 'white', '#ffffff', MonoColour.black],
+ limitedService: false,
+};
+
+const londonRailAttrsComponent = (props: AttrsProps) => {
+ const { id, attrs, handleAttrsUpdate } = props;
+ const { t } = useTranslation();
+
+ const fields: RmgFieldsField[] = [
+ {
+ type: 'switch',
+ label: t('panel.details.lines.londonRail.limitedService'),
+ oneLine: true,
+ isChecked: attrs.limitedService,
+ onChange: val => {
+ attrs.limitedService = val;
+ handleAttrsUpdate(id, attrs);
+ },
+ minW: 'full',
+ },
+ {
+ type: 'custom',
+ label: t('panel.details.lines.londonRail.colorBackground'),
+ component: (
+
+ ),
+ },
+ {
+ type: 'custom',
+ label: t('panel.details.lines.londonRail.colorForeground'),
+ component: (
+
+ ),
+ },
+ ];
+
+ return ;
+};
+
+const londonRail: LineStyle = {
+ component: LondonRail,
+ defaultAttrs: defaultLondonRailAttributes,
+ attrsComponent: londonRailAttrsComponent,
+ metadata: {
+ displayName: 'panel.details.lines.londonRail.displayName',
+ supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
+ },
+};
+
+export default londonRail;
diff --git a/src/components/svgs/lines/styles/london-sandwich.tsx b/src/components/svgs/lines/styles/london-sandwich.tsx
new file mode 100644
index 00000000..d88eb221
--- /dev/null
+++ b/src/components/svgs/lines/styles/london-sandwich.tsx
@@ -0,0 +1,83 @@
+import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
+import { MonoColour } from '@railmapgen/rmg-palette-resources';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { AttrsProps, CityCode } from '../../../../constants/constants';
+import {
+ LinePathAttributes,
+ LinePathType,
+ LineStyle,
+ LineStyleComponentProps,
+ LineStyleType,
+} from '../../../../constants/lines';
+import { AttributesWithColor, ColorField } from '../../../panels/details/color-field';
+
+const LondonSandwichPre = (props: LineStyleComponentProps) => {
+ const { id, path, styleAttrs, handlePointerDown } = props;
+ const { color = defaultLondonSandwichAttributes.color } = styleAttrs ?? defaultLondonSandwichAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+
+ return (
+
+
+
+ );
+};
+
+const LondonSandwich = (props: LineStyleComponentProps) => {
+ const { id, path, styleAttrs, handlePointerDown } = props;
+ const { color = defaultLondonSandwichAttributes.color } = styleAttrs ?? defaultLondonSandwichAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+
+ return (
+
+
+
+ );
+};
+
+/**
+ * LondonSandwich specific props.
+ */
+export interface LondonSandwichAttributes extends LinePathAttributes, AttributesWithColor {}
+
+const defaultLondonSandwichAttributes: LondonSandwichAttributes = {
+ color: [CityCode.London, 'elizabeth', '#9364cc', MonoColour.white],
+};
+
+const LondonSandwichAttrsComponent = (props: AttrsProps) => {
+ const { t } = useTranslation();
+
+ const fields: RmgFieldsField[] = [
+ {
+ type: 'custom',
+ label: t('color'),
+ component: (
+
+ ),
+ },
+ ];
+
+ return ;
+};
+
+const londonSandwich: LineStyle = {
+ component: LondonSandwich,
+ preComponent: LondonSandwichPre,
+ defaultAttrs: defaultLondonSandwichAttributes,
+ attrsComponent: LondonSandwichAttrsComponent,
+ metadata: {
+ displayName: 'panel.details.lines.londonSandwich.displayName',
+ supportLinePathType: [LinePathType.Diagonal, LinePathType.Perpendicular, LinePathType.RotatePerpendicular],
+ },
+};
+
+export default londonSandwich;
diff --git a/src/components/svgs/lines/styles/london-tube-internal-int.tsx b/src/components/svgs/lines/styles/london-tube-internal-int.tsx
index 37173c8a..1ff576ad 100644
--- a/src/components/svgs/lines/styles/london-tube-internal-int.tsx
+++ b/src/components/svgs/lines/styles/london-tube-internal-int.tsx
@@ -1,11 +1,7 @@
import React from 'react';
-import { NodeType } from '../../../../constants/constants';
import { LinePathAttributes, LinePathType, LineStyle, LineStyleComponentProps } from '../../../../constants/lines';
-import { ExternalStationAttributes, StationType } from '../../../../constants/stations';
-const X_HEIGHT = 5;
-
-const LondonTubeInternalInt = (props: LineStyleComponentProps) => {
+const LondonTubeInternalIntPre = (props: LineStyleComponentProps) => {
const { id, path, handlePointerDown } = props;
const onPointerDown = React.useCallback(
@@ -14,26 +10,13 @@ const LondonTubeInternalInt = (props: LineStyleComponentProps
+
);
};
-// Accessible stations have a large icon that the path should hide.
-const getMaskR = (type: NodeType, attr: ExternalStationAttributes) => {
- if (type === StationType.LondonTubeBasic) {
- const { stepFreeAccess } = attr[StationType.LondonTubeBasic] ?? { stepFreeAccess: 'none' };
- if (stepFreeAccess !== 'none') return 1.5 * X_HEIGHT;
- }
- if (type === StationType.LondonTubeInt) {
- const { stepFreeAccess } = attr[StationType.LondonTubeInt] ?? { stepFreeAccess: 'none' };
- if (stepFreeAccess !== 'none') return 1.5 * X_HEIGHT;
- }
- return X_HEIGHT;
-};
-
-const LondonTubeInternalIntPost = (props: LineStyleComponentProps) => {
+const LondonTubeInternalInt = (props: LineStyleComponentProps) => {
const { id, path, handlePointerDown } = props;
const onPointerDown = React.useCallback(
@@ -41,50 +24,9 @@ const LondonTubeInternalIntPost = (props: LineStyleComponentProps
- {/* TODO: The masked part is still clickable with a pointer cursor. */}
-
- {/* Everything under a white pixel will be visible. */}
-
- {/* Everything under a black pixel will be invisible. */}
- {/* `- 0.05` will hide the black edge between the icon and the path. */}
-
-
-
-
+
+
);
};
@@ -100,7 +42,7 @@ const attrsComponent = () => undefined;
const londonTubeInternalInt: LineStyle = {
component: LondonTubeInternalInt,
- postComponent: LondonTubeInternalIntPost,
+ preComponent: LondonTubeInternalIntPre,
defaultAttrs: defaultLondonTubeInternalIntAttributes,
attrsComponent,
metadata: {
diff --git a/src/components/svgs/lines/styles/single-color.tsx b/src/components/svgs/lines/styles/single-color.tsx
index 71874dc1..066dafa7 100644
--- a/src/components/svgs/lines/styles/single-color.tsx
+++ b/src/components/svgs/lines/styles/single-color.tsx
@@ -1,6 +1,7 @@
import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import { MonoColour } from '@railmapgen/rmg-palette-resources';
import React from 'react';
+import { useTranslation } from 'react-i18next';
import { AttrsProps, CityCode } from '../../../../constants/constants';
import {
LinePathAttributes,
@@ -45,10 +46,12 @@ const defaultSingleColorAttributes: SingleColorAttributes = {
};
const singleColorAttrsComponent = (props: AttrsProps) => {
+ const { t } = useTranslation();
+
const fields: RmgFieldsField[] = [
{
type: 'custom',
- label: 'color',
+ label: t('color'),
component: (
),
diff --git a/src/components/svgs/nodes/facilities.tsx b/src/components/svgs/nodes/facilities.tsx
index f4d75ba7..de561340 100644
--- a/src/components/svgs/nodes/facilities.tsx
+++ b/src/components/svgs/nodes/facilities.tsx
@@ -45,6 +45,9 @@ export enum FacilitiesType {
AirportGuangzhou = 'airport_guangzhou',
RailwayGuangzhou = 'railway_guangzhou',
IntercityGuangzhou = 'intercity_guangzhou',
+ RiverCraftLondon = 'river_craft',
+ AirportLondon = 'airport_london',
+ CoachStationLondon = 'coach_station_london',
}
const Facilities = (props: NodeComponentProps) => {
@@ -140,6 +143,9 @@ const attrsComponent = (props: AttrsProps) => {
[FacilitiesType.AirportGuangzhou]: 'Airport Guangzhou',
[FacilitiesType.RailwayGuangzhou]: 'Railway Guangzhou',
[FacilitiesType.IntercityGuangzhou]: 'Intercity Guangzhou',
+ [FacilitiesType.RiverCraftLondon]: 'River services interchange',
+ [FacilitiesType.AirportLondon]: 'Airport London',
+ [FacilitiesType.CoachStationLondon]: 'Victoria Coach Station',
},
onChange: val => {
attrs.type = val as FacilitiesType;
diff --git a/src/components/svgs/nodes/london-arrow.tsx b/src/components/svgs/nodes/london-arrow.tsx
new file mode 100644
index 00000000..696eccde
--- /dev/null
+++ b/src/components/svgs/nodes/london-arrow.tsx
@@ -0,0 +1,134 @@
+import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
+import { MonoColour } from '@railmapgen/rmg-palette-resources';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { AttrsProps, CityCode } from '../../../constants/constants';
+import { MiscNodeType, Node, NodeComponentProps } from '../../../constants/nodes';
+import { Rotate } from '../../../constants/stations';
+import { AttributesWithColor, ColorField } from '../../panels/details/color-field';
+
+const X = 5;
+const D = `M0,0 L${-X * 2},${-X * 2} L${Math.SQRT2 * X - 2 * X},${2 * -X} L${Math.SQRT2 * X},0 L${Math.SQRT2 * X - 2 * X},${2 * X} L${2 * -X},${2 * X} Z`;
+
+const LondonArrow = (props: NodeComponentProps) => {
+ const { id, x, y, attrs, handlePointerDown, handlePointerMove, handlePointerUp } = props;
+ const {
+ color = defaultLondonArrowAttributes.color,
+ rotate = defaultLondonArrowAttributes.rotate,
+ type = defaultLondonArrowAttributes.type,
+ } = attrs ?? defaultLondonArrowAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+ const onPointerMove = React.useCallback(
+ (e: React.PointerEvent) => handlePointerMove(id, e),
+ [id, handlePointerMove]
+ );
+ const onPointerUp = React.useCallback(
+ (e: React.PointerEvent) => handlePointerUp(id, e),
+ [id, handlePointerUp]
+ );
+
+ return (
+
+ {type === 'continuation' ? (
+
+ ) : type === 'sandwich' ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+/**
+ * LondonArrow specific props.
+ */
+export interface LondonArrowAttributes extends AttributesWithColor {
+ rotate: Rotate;
+ type: 'continuation' | 'sandwich' | 'tube';
+}
+
+const defaultLondonArrowAttributes: LondonArrowAttributes = {
+ color: [CityCode.London, 'thameslink', '#d28db0', MonoColour.white],
+ rotate: 0,
+ type: 'continuation',
+};
+
+const londonArrowAttrsComponent = (props: AttrsProps) => {
+ const { id, attrs, handleAttrsUpdate } = props;
+ const { t } = useTranslation();
+
+ const fields: RmgFieldsField[] = [
+ {
+ type: 'select',
+ label: t('panel.details.stations.common.rotate'),
+ value: attrs.rotate,
+ options: { 0: '0', 45: '45', 90: '90', 135: '135', 180: '180', 225: '225', 270: '270', 315: '315' },
+ onChange: val => {
+ attrs.rotate = Number(val) as Rotate;
+ handleAttrsUpdate(id, attrs);
+ },
+ minW: 'full',
+ },
+ {
+ type: 'select',
+ label: t('panel.details.nodes.londonArrow.type'),
+ value: attrs.type,
+ options: {
+ continuation: t('panel.details.nodes.londonArrow.continuation'),
+ sandwich: t('panel.details.nodes.londonArrow.sandwich'),
+ tube: t('panel.details.nodes.londonArrow.tube'),
+ },
+ onChange: val => {
+ attrs.type = val as 'continuation' | 'sandwich' | 'tube';
+ handleAttrsUpdate(id, attrs);
+ },
+ minW: 'full',
+ },
+ {
+ type: 'custom',
+ label: t('color'),
+ component: ,
+ minW: 'full',
+ },
+ ];
+
+ return ;
+};
+
+const londonArrowIcon = (
+
+);
+
+const londonArrow: Node = {
+ component: LondonArrow,
+ icon: londonArrowIcon,
+ defaultAttrs: defaultLondonArrowAttributes,
+ attrsComponent: londonArrowAttrsComponent,
+ metadata: {
+ displayName: 'panel.details.nodes.londonArrow.displayName',
+ tags: [],
+ },
+};
+
+export default londonArrow;
diff --git a/src/components/svgs/nodes/misc-nodes.ts b/src/components/svgs/nodes/misc-nodes.ts
index ce8fdd6e..71040717 100644
--- a/src/components/svgs/nodes/misc-nodes.ts
+++ b/src/components/svgs/nodes/misc-nodes.ts
@@ -16,6 +16,7 @@ import mrtLineBadge from './mrt-line-badge';
import jrEastLineBadge from './jr-east-line-badge';
import qingdaoMetroNumLineBadge from './qingdao-metro-num-line-badge';
import guangdongIntercityRailwayLineBadge from './guangdong-intercity-railway-line-badge';
+import londonArrow from './london-arrow';
import facilities from './facilities';
import text from './text';
import i18nText from './i18n-text';
@@ -39,6 +40,7 @@ const miscNodes = {
[MiscNodeType.JREastLineBadge]: jrEastLineBadge,
[MiscNodeType.QingdaoMetroNumLineBadge]: qingdaoMetroNumLineBadge,
[MiscNodeType.GuangdongIntercityRailwayLineBadge]: guangdongIntercityRailwayLineBadge,
+ [MiscNodeType.LondonArrow]: londonArrow,
[MiscNodeType.Facilities]: facilities,
[MiscNodeType.Text]: text,
[MiscNodeType.I18nText]: i18nText,
diff --git a/src/components/svgs/stations/london-river-services-interchange.tsx b/src/components/svgs/stations/london-river-services-interchange.tsx
new file mode 100644
index 00000000..aeea02fd
--- /dev/null
+++ b/src/components/svgs/stations/london-river-services-interchange.tsx
@@ -0,0 +1,183 @@
+import { RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import { AttrsProps, CanvasType, CategoriesType, CityCode } from '../../../constants/constants';
+import {
+ NameOffsetX,
+ NameOffsetY,
+ Station,
+ StationAttributes,
+ StationComponentProps,
+ StationType,
+ defaultStationAttributes,
+} from '../../../constants/stations';
+import { MultilineText } from '../common/multiline-text';
+
+const X_HEIGHT = 5;
+const FONT_SIZE = 2 * X_HEIGHT;
+const LINE_HEIGHT = 0.85 * FONT_SIZE;
+
+const D1 =
+ 'M-18.2,12.6c2.4-0.6,5.8-1.6,11.5-0.4c2.9,0.6,5.6,1.3,8.3,1.3c3.5,0,5.4-0.6,8.1-1.2c2.4-0.6,5.2-1.2,7.4-1.1c3.8,0.1,6.6,0.7,8.2,1.4l-1.2-3.1C21,8.3,15.8,7.7,9.7,9.5c-2.6,0.7-5.2,1.3-7.9,1.2c-2.5,0-4.8-0.4-7.2-1C-13,8-15.9,9.3-19.8,10.3L-18.2,12.6z';
+const D2 =
+ 'M23.8-2h-4.1l-1.8-4.8c0,0-0.1-0.6-1-1.3c-0.6-0.5-1.6-0.5-1.6-0.5H4v-2h-6.9l-1.1-1.5l0.8-1.9h-1.9l-1.5,3.5h-2.6v2h-5.8c0,0-0.8,0.1-1.2,0.3c-0.4,0.3-0.6,0.5-0.6,0.5l-4.4,5.8h-7.3l7.3,10c1.6-0.7,6.6-2,9.7-1.9c4.1,0.1,9.5,1.9,13.1,1.9c6.6,0,8.8-2,14.6-2.3c7.1-0.4,11.6,2.3,11.6,2.3L23.8-2z M-11.1-2h-7.1l1.9-2.5c0,0,0.8-1.1,1.2-1.3c0.7-0.4,1.2-0.5,1.2-0.5h2.8V-2z M-9.2-2v-4.3h7.4v4.4L-9.2-2z M7.4-2H0v-4.3h7.4V-2z M9.3-2v-4.3h5.1c0,0,0.4,0,0.8,0.4c0.3,0.2,0.5,0.7,0.5,0.7l1.2,3.3L9.3-2z';
+
+const LondonRiverServicesIntStation = (props: StationComponentProps) => {
+ const { id, x, y, attrs, handlePointerDown, handlePointerMove, handlePointerUp } = props;
+ const {
+ names = defaultStationAttributes.names,
+ nameOffsetX = defaultLondonRiverServicesIntStationAttributes.nameOffsetX,
+ nameOffsetY = defaultLondonRiverServicesIntStationAttributes.nameOffsetY,
+ } = attrs[StationType.LondonRiverServicesInt] ?? defaultLondonRiverServicesIntStationAttributes;
+
+ const onPointerDown = React.useCallback(
+ (e: React.PointerEvent) => handlePointerDown(id, e),
+ [id, handlePointerDown]
+ );
+ const onPointerMove = React.useCallback(
+ (e: React.PointerEvent) => handlePointerMove(id, e),
+ [id, handlePointerMove]
+ );
+ const onPointerUp = React.useCallback(
+ (e: React.PointerEvent) => handlePointerUp(id, e),
+ [id, handlePointerUp]
+ );
+
+ const textDx =
+ nameOffsetX === 'left'
+ ? -(X_HEIGHT / 2 + X_HEIGHT * 1.33)
+ : nameOffsetX === 'right'
+ ? X_HEIGHT / 2 + X_HEIGHT * 1.33
+ : 0;
+ const textDy =
+ nameOffsetY === 'top'
+ ? -(X_HEIGHT / 2 + X_HEIGHT * 1.33)
+ : nameOffsetY === 'bottom'
+ ? X_HEIGHT / 2 + X_HEIGHT * 1.33
+ : 0; // fixed dy for each rotation
+
+ const textAnchor = nameOffsetX === 'left' ? 'end' : nameOffsetX === 'right' ? 'start' : 'middle';
+ const dominantBaseline = nameOffsetY === 'top' ? 'auto' : nameOffsetY === 'bottom' ? 'hanging' : 'middle';
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+/**
+ * LondonRiverServicesIntStation specific props.
+ */
+export interface LondonRiverServicesIntStationAttributes extends StationAttributes {
+ nameOffsetX: NameOffsetX;
+ nameOffsetY: NameOffsetY;
+}
+
+const defaultLondonRiverServicesIntStationAttributes: LondonRiverServicesIntStationAttributes = {
+ names: ['Station'],
+ nameOffsetX: 'right',
+ nameOffsetY: 'top',
+};
+
+const londonRiverServicesIntAttrsComponent = (props: AttrsProps) => {
+ const { id, attrs, handleAttrsUpdate } = props;
+ const { t } = useTranslation();
+
+ const fields: RmgFieldsField[] = [
+ {
+ type: 'textarea',
+ label: t('panel.details.stations.common.nameEn'),
+ value: attrs.names[0],
+ onChange: val => {
+ attrs.names[0] = val.toString();
+ handleAttrsUpdate(id, attrs);
+ },
+ minW: 'full',
+ },
+ {
+ type: 'select',
+ label: t('panel.details.stations.common.nameOffsetX'),
+ value: attrs.nameOffsetX,
+ options: {
+ left: t('panel.details.stations.common.left'),
+ middle: t('panel.details.stations.common.middle'),
+ right: t('panel.details.stations.common.right'),
+ },
+ disabledOptions: attrs.nameOffsetY === 'middle' ? ['middle'] : [],
+ onChange: val => {
+ attrs.nameOffsetX = val as NameOffsetX;
+ handleAttrsUpdate(id, attrs);
+ },
+ minW: 'full',
+ },
+ {
+ type: 'select',
+ label: t('panel.details.stations.common.nameOffsetY'),
+ value: attrs.nameOffsetY,
+ options: {
+ top: t('panel.details.stations.common.top'),
+ middle: t('panel.details.stations.common.middle'),
+ bottom: t('panel.details.stations.common.bottom'),
+ },
+ disabledOptions: attrs.nameOffsetX === 'middle' ? ['middle'] : [],
+ onChange: val => {
+ attrs.nameOffsetY = val as NameOffsetY;
+ handleAttrsUpdate(id, attrs);
+ },
+ minW: 'full',
+ },
+ ];
+
+ return ;
+};
+
+const londonRiverServicesIntStationIcon = (
+
+);
+
+const londonRiverServicesIntStation: Station = {
+ component: LondonRiverServicesIntStation,
+ icon: londonRiverServicesIntStationIcon,
+ defaultAttrs: defaultLondonRiverServicesIntStationAttributes,
+ attrsComponent: londonRiverServicesIntAttrsComponent,
+ metadata: {
+ displayName: 'panel.details.stations.londonRiverServicesInt.displayName',
+ cities: [CityCode.London],
+ canvas: [CanvasType.RailMap],
+ categories: [CategoriesType.Metro],
+ tags: [],
+ },
+};
+
+export default londonRiverServicesIntStation;
diff --git a/src/components/svgs/stations/london-tube-basic.tsx b/src/components/svgs/stations/london-tube-basic.tsx
index 74546867..b76f440a 100644
--- a/src/components/svgs/stations/london-tube-basic.tsx
+++ b/src/components/svgs/stations/london-tube-basic.tsx
@@ -171,7 +171,8 @@ const LondonTubeBasicStation = (props: StationComponentProps) => {
// rotate starts from top-middle while Math.sin/cos starts from middle-right
const rad = ((rotate - 90) * Math.PI) / 180;
- const height = (terminal ? 2 : 1) * (0.66 * X_HEIGHT + X_HEIGHT / 2);
+ // 0.5 cover the gap between the station icon and the line
+ const height = terminal ? 2 * (0.66 * X_HEIGHT + X_HEIGHT / 2) : 0.66 * X_HEIGHT + 0.5;
const textDx =
ROTATE_CONST[rotate].textDx + // fixed dx for each rotation
Math.cos(rad) * Math.max(...transfer[0].map(_ => _[4])) * X_HEIGHT; // dynamic dx of n share tracks
diff --git a/src/components/svgs/stations/london-tube-int.tsx b/src/components/svgs/stations/london-tube-int.tsx
index bd36fd3b..14610204 100644
--- a/src/components/svgs/stations/london-tube-int.tsx
+++ b/src/components/svgs/stations/london-tube-int.tsx
@@ -181,7 +181,7 @@ const londonTubeIntAttrsComponent = (props: AttrsProps
-
+
);
diff --git a/src/components/svgs/stations/stations.ts b/src/components/svgs/stations/stations.ts
index b8efea0d..23359197 100644
--- a/src/components/svgs/stations/stations.ts
+++ b/src/components/svgs/stations/stations.ts
@@ -24,6 +24,7 @@ import tokyoMetroBasicStation from './tokyo-metro-basic';
import tokyoMetroIntStation from './tokyo-metro-int';
import londonTubeBasicStation from './london-tube-basic';
import londonTubeIntStation from './london-tube-int';
+import londonRiverServicesIntStation from './london-river-services-interchange';
import guangdongIntercityRailwayStation from './guangdong-intercity-railway';
const stations = {
@@ -52,6 +53,7 @@ const stations = {
[StationType.TokyoMetroInt]: tokyoMetroIntStation,
[StationType.LondonTubeBasic]: londonTubeBasicStation,
[StationType.LondonTubeInt]: londonTubeIntStation,
+ [StationType.LondonRiverServicesInt]: londonRiverServicesIntStation,
[StationType.GuangdongIntercityRailway]: guangdongIntercityRailwayStation,
};
diff --git a/src/constants/lines.ts b/src/constants/lines.ts
index 545cbb57..6a319054 100644
--- a/src/constants/lines.ts
+++ b/src/constants/lines.ts
@@ -26,6 +26,10 @@ import { LRTSingleColorAttributes } from '../components/svgs/lines/styles/lrt-si
import { LondonTubeTerminalAttributes } from '../components/svgs/lines/styles/london-tube-terminal';
import { LondonTubeInternalIntAttributes } from '../components/svgs/lines/styles/london-tube-internal-int';
import { LondonTube10MinWalkAttributes } from '../components/svgs/lines/styles/london-tube-10-min-walk';
+import { LondonRailAttributes } from '../components/svgs/lines/styles/london-rail';
+import { LondonSandwichAttributes } from '../components/svgs/lines/styles/london-sandwich';
+import { LondonLutonAirportDARTAttributes } from '../components/svgs/lines/styles/london-DART';
+import { LondonIFSCloudCableCarAttributes } from '../components/svgs/lines/styles/london-ifs-could-cable-car';
import { GuangdongIntercityRailwayAttributes } from '../components/svgs/lines/styles/guangdong-intercity-railway';
export enum LinePathType {
@@ -65,6 +69,10 @@ export enum LineStyleType {
LondonTubeTerminal = 'london-tube-terminal',
LondonTubeInternalInt = 'london-tube-internal-int',
LondonTube10MinWalk = 'london-tube-10-min-walk',
+ LondonRail = 'london-rail',
+ LondonSandwich = 'london-sandwich',
+ LondonLutonAirportDART = 'london-DART',
+ LondonIFSCloudCableCar = 'london-dangleway',
GuangdongIntercityRailway = 'gd-intercity-rwy',
}
@@ -91,6 +99,10 @@ export interface ExternalLineStyleAttributes {
[LineStyleType.LondonTubeTerminal]?: LondonTubeTerminalAttributes;
[LineStyleType.LondonTubeInternalInt]?: LondonTubeInternalIntAttributes;
[LineStyleType.LondonTube10MinWalk]?: LondonTube10MinWalkAttributes;
+ [LineStyleType.LondonRail]?: LondonRailAttributes;
+ [LineStyleType.LondonSandwich]?: LondonSandwichAttributes;
+ [LineStyleType.LondonLutonAirportDART]?: LondonLutonAirportDARTAttributes;
+ [LineStyleType.LondonIFSCloudCableCar]?: LondonIFSCloudCableCarAttributes;
[LineStyleType.GuangdongIntercityRailway]?: GuangdongIntercityRailwayAttributes;
}
@@ -106,6 +118,10 @@ export const LineStylesWithColor = [
LineStyleType.JREastSingleColor,
LineStyleType.JREastSingleColorPattern,
LineStyleType.LRTSingleColor,
+ LineStyleType.GuangdongIntercityRailway,
+ LineStyleType.LondonRail,
+ LineStyleType.LondonSandwich,
+ LineStyleType.LondonLutonAirportDART,
];
/* ----- Below are core types for all lines, DO NOT TOUCH. ----- */
diff --git a/src/constants/nodes.ts b/src/constants/nodes.ts
index f7ee4c29..240932a9 100644
--- a/src/constants/nodes.ts
+++ b/src/constants/nodes.ts
@@ -16,6 +16,7 @@ import { JREastLineBadgeAttributes } from '../components/svgs/nodes/jr-east-line
import { QingdaoMetroNumLineBadgeAttributes } from '../components/svgs/nodes/qingdao-metro-num-line-badge';
import { MRTLineBadgeAttributes } from '../components/svgs/nodes/mrt-line-badge';
import { GuangdongIntercityRailwayLineBadgeAttributes } from '../components/svgs/nodes/guangdong-intercity-railway-line-badge';
+import { LondonArrowAttributes } from '../components/svgs/nodes/london-arrow';
import { FacilitiesAttributes } from '../components/svgs/nodes/facilities';
import { TextAttributes } from '../components/svgs/nodes/text';
import { I18nTextAttributes } from '../components/svgs/nodes/i18n-text';
@@ -39,6 +40,7 @@ export enum MiscNodeType {
QingdaoMetroNumLineBadge = 'qingdao-metro-num-line-badge',
MRTLineBadge = 'mrt-line-badge',
GuangdongIntercityRailwayLineBadge = 'gd-intercity-rwy-line-badge',
+ LondonArrow = 'london-arrow',
Facilities = 'facilities',
Text = 'text',
I18nText = 'i18n-text',
@@ -63,6 +65,7 @@ export interface MiscNodeAttributes {
[MiscNodeType.QingdaoMetroNumLineBadge]?: QingdaoMetroNumLineBadgeAttributes;
[MiscNodeType.MRTLineBadge]?: MRTLineBadgeAttributes;
[MiscNodeType.GuangdongIntercityRailwayLineBadge]?: GuangdongIntercityRailwayLineBadgeAttributes;
+ [MiscNodeType.LondonArrow]?: LondonArrowAttributes;
[MiscNodeType.Facilities]?: FacilitiesAttributes;
[MiscNodeType.Text]?: TextAttributes;
[MiscNodeType.I18nText]?: I18nTextAttributes;
diff --git a/src/constants/stations.ts b/src/constants/stations.ts
index be3b4056..141feb46 100644
--- a/src/constants/stations.ts
+++ b/src/constants/stations.ts
@@ -24,6 +24,7 @@ import { TokyoMetroBasicStationAttributes } from '../components/svgs/stations/to
import { TokyoMetroIntStationAttributes } from '../components/svgs/stations/tokyo-metro-int';
import { LondonTubeBasicStationAttributes } from '../components/svgs/stations/london-tube-basic';
import { LondonTubeIntStationAttributes } from '../components/svgs/stations/london-tube-int';
+import { LondonRiverServicesIntStationAttributes } from '../components/svgs/stations/london-river-services-interchange';
import { GuangdongIntercityRailwayStationAttributes } from '../components/svgs/stations/guangdong-intercity-railway';
export enum StationType {
@@ -52,6 +53,7 @@ export enum StationType {
TokyoMetroInt = 'tokyo-metro-int',
LondonTubeBasic = 'london-tube-basic',
LondonTubeInt = 'london-tube-int',
+ LondonRiverServicesInt = 'london-river-int',
GuangdongIntercityRailway = 'gd-intercity-rwy',
}
@@ -81,6 +83,7 @@ export interface ExternalStationAttributes {
[StationType.TokyoMetroInt]?: TokyoMetroIntStationAttributes;
[StationType.LondonTubeBasic]?: LondonTubeBasicStationAttributes;
[StationType.LondonTubeInt]?: LondonTubeIntStationAttributes;
+ [StationType.LondonRiverServicesInt]?: LondonRiverServicesIntStationAttributes;
[StationType.GuangdongIntercityRailway]?: GuangdongIntercityRailwayStationAttributes;
}
diff --git a/src/i18n/translations/en.json b/src/i18n/translations/en.json
index f6fb0265..8352c3be 100644
--- a/src/i18n/translations/en.json
+++ b/src/i18n/translations/en.json
@@ -135,6 +135,13 @@
"guangdongIntercityRailwayLineBadge": {
"displayName": "Guangdong Intercity Railway line badge"
},
+ "londonArrow": {
+ "displayName": "London arrow",
+ "type": "Type",
+ "continuation": "Continuation",
+ "sandwich": "Sandwich",
+ "tube": "Tube"
+ },
"master": {
"displayName": "Master node",
"type": "Master node type",
@@ -339,6 +346,9 @@
"londonTubeInt": {
"displayName": "London Tube interchange station"
},
+ "londonRiverServicesInt": {
+ "displayName": "London river services interchange station"
+ },
"guangdongIntercityRailway": {
"displayName": "Guangdong Intercity Railway station"
}
@@ -439,6 +449,21 @@
"londonTubeTerminal": {
"displayName": "London Tube terminal style"
},
+ "londonRail": {
+ "displayName": "London rail style",
+ "limitedService": "Limited service/Peak hours only",
+ "colorBackground": "Color background",
+ "colorForeground": "Color foreground"
+ },
+ "londonSandwich": {
+ "displayName": "London sandwich style"
+ },
+ "londonLutonAirportDART": {
+ "displayName": "London Luton Airport DART style"
+ },
+ "londonIFSCloudCableCar": {
+ "displayName": "London IFS Cloud Cable Car style"
+ },
"guangdongIntercityRailway": {
"displayName": "Guangdong Intercity Railway style"
}
@@ -552,7 +577,7 @@
"undo": "Undo.",
"redo": "Redo."
},
- "procedures":{
+ "procedures": {
"title": "Procedures",
"translate": {
"title": "Translate nodes' coordinates",
diff --git a/src/i18n/translations/ja.json b/src/i18n/translations/ja.json
index bec59ca3..9b436a86 100644
--- a/src/i18n/translations/ja.json
+++ b/src/i18n/translations/ja.json
@@ -126,8 +126,8 @@
"isTram": "LRT路線バッジです"
},
"jrEastLineBadge": {
- "displayName": "JR東日本路線番号徽章",
- "crosshatchPatternFill": "網目模様で塗りつぶす"
+ "displayName": "JR東日本路線番号徽章",
+ "crosshatchPatternFill": "網目模様で塗りつぶす"
},
"qingdaoMetroNumLineBadge": {
"displayName": "青島地下鉄番号線徽章",
@@ -137,6 +137,13 @@
"guangdongIntercityRailwayLineBadge": {
"displayName": "広東省都市間鉄道線徽章"
},
+ "londonArrow": {
+ "displayName": "ロンドン矢印",
+ "type": "種類",
+ "continuation": "継続",
+ "sandwich": "サンドイッチ",
+ "tube": "地下鉄"
+ },
"master": {
"displayName": "大師節点",
"type": "大師節点種類",
@@ -271,18 +278,18 @@
"displayName": "シンガポールMRT乗り換え駅"
},
"jrEastBasic": {
- "displayName": "JR東日本基本駅",
- "nameOffset": "名前の補正値",
- "textOneLine": "1行での名前",
- "textVertical": "垂直の名前",
- "important": "重要な駅",
- "lines": "乗り換え線の補正値"
+ "displayName": "JR東日本基本駅",
+ "nameOffset": "名前の補正値",
+ "textOneLine": "1行での名前",
+ "textVertical": "垂直の名前",
+ "important": "重要な駅",
+ "lines": "乗り換え線の補正値"
},
"jrEastImportant": {
- "displayName": "JR東日本重要駅",
- "textVertical": "垂直の名前",
- "mostImportant": "最も重要な駅",
- "minLength": "駅の最小長"
+ "displayName": "JR東日本重要駅",
+ "textVertical": "垂直の名前",
+ "mostImportant": "最も重要な駅",
+ "minLength": "駅の最小長"
},
"foshanMetroBasic": {
"displayName": "仏山地鐵基本車站",
@@ -339,6 +346,9 @@
"londonTubeInt": {
"displayName": "ロンドン地下鉄乗換駅"
},
+ "londonRiverServicesInt": {
+ "displayName": "ロンドン川サービス乗換駅"
+ },
"guangdongIntercityRailway": {
"displayName": "広東省都市間鉄道駅"
}
@@ -439,6 +449,21 @@
"londonTubeTerminal": {
"displayName": "ロンドン地下鉄終着風格"
},
+ "londonRail": {
+ "displayName": "ロンドン鉄道風格",
+ "limitedService": "限定サービス/ピーク時のみ",
+ "colorBackground": "背景色",
+ "colorForeground": "前景色"
+ },
+ "londonSandwich": {
+ "displayName": "ロンドンサンドイッチ風格"
+ },
+ "londonLutonAirportDART": {
+ "displayName": "ロンドンルートン空港DART風格"
+ },
+ "londonIFSCloudCableCar": {
+ "displayName": "ロンドンIF雲索道風格"
+ },
"guangdongIntercityRailway": {
"displayName": "広東省都市間鉄道風格"
}
diff --git a/src/i18n/translations/ko.json b/src/i18n/translations/ko.json
index 8b07526c..932e2d0f 100644
--- a/src/i18n/translations/ko.json
+++ b/src/i18n/translations/ko.json
@@ -135,6 +135,13 @@
"guangdongIntercityRailwayLineBadge": {
"displayName": "광동 시외 철도 노선 표지판"
},
+ "londonArrow": {
+ "displayName": "런던 화살표",
+ "type": "유형",
+ "continuation": "계속",
+ "sandwich": "샌드위치",
+ "tube": "튜브"
+ },
"master": {
"displayName": "마스터 노드",
"type": "마스터 노드 유형",
@@ -338,6 +345,9 @@
"londonTubeInt": {
"displayName": "런던 지하철 환승역"
},
+ "londonRiverServicesInt": {
+ "displayName": "런던 강 서비스 환승역"
+ },
"guangdongIntercityRailway": {
"displayName": "광둥 시외 기차역"
}
@@ -438,6 +448,21 @@
"londonTubeTerminal": {
"displayName": "런던 지하철 종착 스타일"
},
+ "londonRail": {
+ "displayName": "런던 철도 스타일",
+ "limitedService": "제한 서비스/혼잡 시간대만",
+ "colorBackground": "배경 색상",
+ "colorForeground": "전경 색상"
+ },
+ "londonSandwich": {
+ "displayName": "런던 샌드위치 스타일"
+ },
+ "londonLutonAirportDART": {
+ "displayName": "런던 루튼 공항 DART 스타일"
+ },
+ "londonIFSCloudCableCar": {
+ "displayName": "런던 IFS 클라우드 케이블카 스타일"
+ },
"guangdongIntercityRailway": {
"displayName": "광동성 도시간 철도 스타일"
}
diff --git a/src/i18n/translations/zh-Hans.json b/src/i18n/translations/zh-Hans.json
index 89b726be..70269b2a 100644
--- a/src/i18n/translations/zh-Hans.json
+++ b/src/i18n/translations/zh-Hans.json
@@ -124,8 +124,8 @@
"isTram": "是LRT线路标识"
},
"jrEastLineBadge": {
- "displayName": "JR东日本线路标识",
- "crosshatchPatternFill": "用网状图案填充"
+ "displayName": "JR东日本线路标识",
+ "crosshatchPatternFill": "用网状图案填充"
},
"qingdaoMetroNumLineBadge": {
"displayName": "青岛地铁数字线路标识",
@@ -135,6 +135,13 @@
"guangdongIntercityRailwayLineBadge": {
"displayName": "广东城际铁路线路标识"
},
+ "londonArrow": {
+ "displayName": "伦敦箭头",
+ "type": "类型",
+ "continuation": "延续",
+ "sandwich": "三明治",
+ "tube": "地铁"
+ },
"master": {
"displayName": "大师节点",
"type": "大师节点类型",
@@ -338,6 +345,9 @@
"londonTubeInt": {
"displayName": "伦敦地铁换乘车站"
},
+ "londonRiverServicesInt": {
+ "displayName": "伦敦河流服务换乘站"
+ },
"guangdongIntercityRailway": {
"displayName": "广东城际铁路车站"
}
@@ -438,6 +448,21 @@
"londonTubeTerminal": {
"displayName": "伦敦地铁终点站样式"
},
+ "londonRail": {
+ "displayName": "伦敦铁路样式",
+ "limitedService": "有限服务/仅限高峰时段",
+ "colorBackground": "背景颜色",
+ "colorForeground": "前景颜色"
+ },
+ "londonSandwich": {
+ "displayName": "伦敦三明治样式"
+ },
+ "londonLutonAirportDART": {
+ "displayName": "伦敦卢顿机场DART样式"
+ },
+ "londonIFSCloudCableCar": {
+ "displayName": "伦敦IFS云缆车样式"
+ },
"guangdongIntercityRailway": {
"displayName": "广东城际铁路样式"
}
diff --git a/src/i18n/translations/zh-Hant.json b/src/i18n/translations/zh-Hant.json
index 3048e627..c4bedaf1 100644
--- a/src/i18n/translations/zh-Hant.json
+++ b/src/i18n/translations/zh-Hant.json
@@ -124,8 +124,8 @@
"isTram": "是LRT線路標識"
},
"jrEastLineBadge": {
- "displayName": "JR東日本線路標識",
- "crosshatchPatternFill": "用網狀圖案填充"
+ "displayName": "JR東日本線路標識",
+ "crosshatchPatternFill": "用網狀圖案填充"
},
"qingdaoMetroNumLineBadge": {
"displayName": "青島地鐵數位線路標識",
@@ -135,6 +135,13 @@
"guangdongIntercityRailwayLineBadge": {
"displayName": "廣東城際鐵路線標識"
},
+ "londonArrow": {
+ "displayName": "倫敦箭頭",
+ "type": "類型",
+ "continuation": "延續",
+ "sandwich": "三明治",
+ "tube": "地鐵"
+ },
"master": {
"displayName": "大師節點",
"type": "大師節點類型",
@@ -268,18 +275,18 @@
"displayName": "新加坡MRT換乘車站"
},
"jrEastBasic": {
- "displayName": "JR東日本基本車站",
- "nameOffset": "名稱偏移",
- "textOneLine": "名稱在一行中",
- "textVertical": "垂直名稱",
- "important": "重要車站",
- "lines": "轉乘線偏移"
+ "displayName": "JR東日本基本車站",
+ "nameOffset": "名稱偏移",
+ "textOneLine": "名稱在一行中",
+ "textVertical": "垂直名稱",
+ "important": "重要車站",
+ "lines": "轉乘線偏移"
},
"jrEastImportant": {
- "displayName": "JR東日本重要車站",
- "textVertical": "垂直名稱",
- "mostImportant": "最重要車站",
- "minLength": "車站的最小長度"
+ "displayName": "JR東日本重要車站",
+ "textVertical": "垂直名稱",
+ "mostImportant": "最重要車站",
+ "minLength": "車站的最小長度"
},
"foshanMetroBasic": {
"displayName": "佛山地鐵基本車站",
@@ -338,6 +345,9 @@
"londonTubeInt": {
"displayName": "倫敦地鐵換乘車站"
},
+ "londonRiverServicesInt": {
+ "displayName": "倫敦河流服務換乘站"
+ },
"guangdongIntercityRailway": {
"displayName": "廣東城際鐵路車站"
}
@@ -438,6 +448,21 @@
"londonTubeTerminal": {
"displayName": "倫敦地鐵終點站樣式"
},
+ "londonRail": {
+ "displayName": "倫敦鐵路樣式",
+ "limitedService": "有限服務/只限繁忙時段",
+ "colorBackground": "背景顏色",
+ "colorForeground": "前景顏色"
+ },
+ "londonSandwich": {
+ "displayName": "倫敦三明治樣式"
+ },
+ "londonLutonAirportDART": {
+ "displayName": "倫敦盧頓機場DART樣式"
+ },
+ "londonIFSCloudCableCar": {
+ "displayName": "倫敦IFS雲纜車樣式"
+ },
"guangdongIntercityRailway": {
"displayName": "廣東城際鐵路樣式"
}