Skip to content

Commit

Permalink
Merge pull request #18 from SchweizerischeBundesbahnen/feature/10-com…
Browse files Browse the repository at this point in the history
…mand-line-interface

Feature/10 command line interface
  • Loading branch information
munterfi authored Dec 2, 2024
2 parents 160fc19 + 685b6ab commit 8eb9e9f
Show file tree
Hide file tree
Showing 10 changed files with 437 additions and 110 deletions.
6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 96 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,99 @@ the [Netzgrafik-Editor](https://github.com/SchweizerischeBundesbahnen/netzgrafik
the entire service
day in different formats, as for example GTFS static or MATSim transit schedules.

## Usage

### Command line

Run the command line tool to convert a network graphic to either a GTFS or MATSim timetable:

```text
Usage: convert [-htV] [-e=<serviceDayEnd>] [-f=<outputFormat>]
[-s=<serviceDayStart>] [-v=<validationStrategy>]
<networkGraphicFile> <outputDirectory>
Converts network graphics into timetables in various formats.
<networkGraphicFile> The network graphic file to convert.
<outputDirectory> The output directory for the converted timetable.
-e, --service-day-end=<serviceDayEnd>
Service day end time (HH:mm).
-f, --format=<outputFormat>
Output format (GTFS or MATSim).
-h, --help Show this help message and exit.
-s, --service-day-start=<serviceDayStart>
Service day start time (HH:mm).
-t, --train-names Use train names as route or line IDs (true/false).
-v, --validation=<validationStrategy>
Validation strategy (SKIP_VALIDATION,
WARN_ON_ISSUES, FAIL_ON_ISSUES, FIX_ISSUES).
-V, --version Print version information and exit.
```

Example:

```sh
# configure arguments
NETWORK_GRAPHIC_FILE=src/test/resources/ng/scenarios/realistic.json
OUTPUT_DIRECTORY=integration-test/output/cmd

# run the Spring command line runner app to convert to GTFS format
./mvnw spring-boot:run -Dspring-boot.run.arguments="$NETWORK_GRAPHIC_FILE $OUTPUT_DIRECTORY -f GTFS"

# run the Spring command line runner app to convert to MATSim format with custom service day times
./mvnw spring-boot:run -Dspring-boot.run.arguments="$NETWORK_GRAPHIC_FILE $OUTPUT_DIRECTORY -f MATSIM -s 04:30 -e 26:00"
```

### Converter in Java

In most cases, the repositories for infrastructure, rolling stock, and vehicle circuits used by the supply builder will
be custom. To configure the converter with these custom repositories, inject them into the supply builder of the
selected timetable output format (refer to the Design section for details) and run the conversion:

```java

public class Example {

public static final Path NETWORK_GRAPHIC_FILE = Path.of("path/to/networkGraphic.json");
public static final Path OUTPUT_DIRECTORY = Path.of("path/to/outputDirectory");
public static final NetworkGraphicConverterConfig CONFIG = NetworkGraphicConverterConfig.builder().build();

public static void main(String[] args) throws IOException {

// define network graphic source
NetworkGraphicSource source = new JsonFileReader(NETWORK_GRAPHIC_FILE);

// instantiate custom implementations of the repositories
RollingStockRepository customRollingStockRepository = new CustomRollingStockRepository();
InfrastructureRepository customInfrastructureRepository = new CustomInfrastructureRepository();
VehicleCircuitsPlanner customVehicleCircuitsPlanner = new CustomVehicleCircuitsPlanner(
customRollingStockRepository);

// convert to GTFS
setupGtfsConverter(customInfrastructureRepository, customVehicleCircuitsPlanner, source).run();

// convert to MATSim
setupMatsimConverter(customInfrastructureRepository, customVehicleCircuitsPlanner, source).run();
}

private static NetworkGraphicConverter<Scenario> setupMatsimConverter(InfrastructureRepository customInfrastructureRepository, VehicleCircuitsPlanner customVehicleCircuitsPlanner, NetworkGraphicSource source) {
SupplyBuilder<Scenario> builder = new MatsimSupplyBuilder(customInfrastructureRepository,
customVehicleCircuitsPlanner);
ConverterSink<Scenario> sink = new TransitScheduleXmlWriter(Example.OUTPUT_DIRECTORY, "");

return new NetworkGraphicConverter<>(CONFIG, source, builder, sink);
}

private static NetworkGraphicConverter<GtfsSchedule> setupGtfsConverter(InfrastructureRepository customInfrastructureRepository, VehicleCircuitsPlanner customVehicleCircuitsPlanner, NetworkGraphicSource source) {
SupplyBuilder<GtfsSchedule> builder = new GtfsSupplyBuilder(customInfrastructureRepository,
customVehicleCircuitsPlanner);
ConverterSink<GtfsSchedule> sink = new GtfsScheduleWriter(Example.OUTPUT_DIRECTORY);

return new NetworkGraphicConverter<>(CONFIG, source, builder, sink);
}

}

```

## Design

The converter has a modular design (DI):
Expand All @@ -17,22 +110,13 @@ The converter has a modular design (DI):
- **validation**: Network graphic ID validator and sanitizer.
- **adapter**: Format-specific transit schedule builder, implementing the supply builder interface.
- **io**: Provides implementations for network graphic sources and converter output sinks.
- **app**: Command line application.
- **utils**: Utilities used across multiple domains.

The class diagram outlines the core classes and their relationships:
The class diagram outlines core classes and their relationships:

![Class diagram](docs/uml/class-diagram.svg)

## Usage

```sh
# configure arguments
NETWORK_GRAPHIC_FILE=src/test/resources/ng/scenarios/realistic.json
OUTPUT_DIRECTORY=integration-test/output/

# run spring command line runner app
./mvnw spring-boot:run -Dspring-boot.run.arguments="$NETWORK_GRAPHIC_FILE $OUTPUT_DIRECTORY"
```

## License

This project is licensed under GNU [GPL-3.0](LICENSE).
Expand Down
50 changes: 31 additions & 19 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<version>3.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>ch.sbb.pfi.netzgrafikeditor</groupId>
<artifactId>netzgrafik-editor-converter</artifactId>
<version>2.7.0-SNAPSHOT</version>
<name>netzgrafik-editor-matsim-converter</name>
<version>1.0.0-SNAPSHOT</version>
<name>netzgrafik-editor-converter</name>
<description>Converter to expand network graphics from the Netzgrafik-Editor into timetables for the entire service
day in different formats
</description>
Expand All @@ -30,6 +30,17 @@

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand All @@ -53,9 +64,10 @@
</repositories>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
Expand All @@ -64,34 +76,34 @@
</dependency>

<dependency>
<groupId>org.matsim</groupId>
<artifactId>matsim</artifactId>
<version>${matsim.version}</version>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<!-- enable autocomplete for configuration properties,
see https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
<groupId>info.picocli</groupId>
<artifactId>picocli-spring-boot-starter</artifactId>
<version>4.7.6</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<groupId>org.matsim</groupId>
<artifactId>matsim</artifactId>
<version>${matsim.version}</version>
</dependency>

<!-- test -->

<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.1.0</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.1.0</version>
<scope>test</scope>
</dependency>

Expand Down
79 changes: 0 additions & 79 deletions src/main/java/ch/sbb/pfi/netzgrafikeditor/Application.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ch.sbb.pfi.netzgrafikeditor.converter.app;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import picocli.CommandLine;

@SpringBootApplication
public class CommandLineConverter implements CommandLineRunner, ExitCodeGenerator {

private static final String FOOTER_KEY = "footer";

private final CommandLine.IFactory factory;
private final ConvertCommand convertCommand;
private int exitCode;

CommandLineConverter(CommandLine.IFactory factory, ConvertCommand convertCommand) {
this.factory = factory;
this.convertCommand = convertCommand;
}

public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(CommandLineConverter.class, args)));
}

@Override
public void run(String... args) {
CommandLine commandLine = new CommandLine(convertCommand, factory);
commandLine.getHelpSectionMap().put(FOOTER_KEY, convertCommand.new FooterProvider());
exitCode = commandLine.execute(args);
}

@Override
public int getExitCode() {
return exitCode;
}
}
Loading

0 comments on commit 8eb9e9f

Please sign in to comment.