Es ist ein kleiner alter Artikel, aber ich habe "Wie man Stammdaten von Stationen und Routen erhält - Qiita" gelesen und festgestellt, dass es CSV-Daten von Routen gibt. Es war. Erstellen wir eine U-Bahn-Karte von Tokio mithilfe der in diesem Artikel vorgestellten CSV-Datei in "Station data.jp". Die verwendete Java-Version ist 14. Verwenden Sie yEd --Graph Editor, um das Diagramm anzuzeigen. Den gesamten Quellcode finden Sie hier [https://gist.github.com/saka1029/7d08fef8744a508b29e1c8206510f21e].
Laden Sie Routendaten, Stationsdaten und verbundene Stationsdaten von Meine Seite | Stationsdaten kostenlos herunterladen "Stationsdaten.jp" herunter.
Sie müssen ein kostenloses Konto zum Herunterladen erstellen.
Erstellen Sie ein allgemeines Programm, das eine CSV-Datei liest und in List <List <String >>
konvertiert.
static final Charset CHARSET = StandardCharsets.UTF_8;
static final Path DIRECTORY = Paths.get("data", "eki");
static final Path LINE_CSV = DIRECTORY.resolve("line20200619free.csv");
static final Path STATION_CSV = DIRECTORY.resolve("station20200619free.csv");
static final Path JOIN_CSV = DIRECTORY.resolve("join20200619.csv");
static final Path GML = DIRECTORY.resolve("metro.gml");
static List<List<String>> readCSV(Path file) throws IOException {
return Files.readAllLines(file, CHARSET).stream()
.map(line -> List.of(line.split(",")))
.collect(toList());
}
Jeder Artikel ist nicht in Anführungszeichen eingeschlossen, sodass er leicht gelesen werden kann.
Lesen Sie zuerst die Routendaten. Da wir eine U-Bahn-Karte von Tokio erstellen, werden nur diejenigen extrahiert, deren Liniennamen mit "Tokyo Metro" oder "Toei" beginnen.
//U-Bahnlinie Tokio
List<List<String>> lines = readCSV(LINE_CSV).stream()
.filter(line -> line.get(2).startsWith("Tokyo Metro") || line.get(2).startsWith("Toei"))
.collect(toList());
Als nächstes werden wir die Stationsdaten lesen, aber wir werden eine Liste von Routencodes erstellen, um nur diejenigen zu extrahieren, die den Routencodes der zuvor gelesenen Routendaten entsprechen. (Sollte anstelle von Liste gesetzt worden sein)
//Liste der U-Bahn-Liniencodes von Tokio
List<String> lineCodes = lines.stream()
.map(line -> line.get(0))
.collect(toList());
Es werden nur die Stationen mit den Routencodes in dieser Liste extrahiert.
//U-Bahnstation Tokio
List<List<String>> stations = readCSV(STATION_CSV).stream()
.filter(station -> lineCodes.contains(station.get(5)))
.collect(toList());
Lesen Sie abschließend die Daten der Verbindungsstation. Auch hier werden nur diejenigen extrahiert, die sich auf den U-Bahn-Liniencode von Tokio beziehen.
//Verbindung zur U-Bahnstation Tokio
List<List<String>> joins = readCSV(JOIN_CSV).stream()
.filter(line -> lineCodes.contains(line.get(0)))
.collect(toList());
Erstellen Sie aus den gelesenen Daten ein Diagramm. Diagramme werden mit yEd --Graph Editor gelesen. Erstellen Sie daher Textdaten im Format GML (Graphic Modeling Language).
//Diagramm erstellen
try (PrintWriter w = new PrintWriter(Files.newBufferedWriter(GML))) {
w.println("graph [");
for (List<String> s : stations) {
w.println(" node [");
w.println(" id " + s.get(0)); //Stationscode
w.println(" label \"" + s.get(2) + "\""); //Stationsname
w.println(" ]");
}
for (List<String> j : joins) {
w.println(" edge [");
w.println(" source " + j.get(1)); //Verbindungsstationscode 1
w.println(" target " + j.get(2)); //Verbindungsstationscode 2
w.println(" ]");
}
w.println("]");
}
Erstellen Sie eine Station als Knoten und eine Verbindungsstation als Kante.
Lesen Sie mit yEd und formatieren Sie wie folgt.
Dann sieht das Diagramm so aus. 13 Routen wurden separat erstellt. Sie können sehen, dass oben links die Oedo-Linie ist, weil sie die Kreislinie enthält, und die Marunouchi-Linie, die die Honancho-Zweiglinie enthält, weil sie daneben Y-förmig ist.
Dies ist jedoch keine Routenkarte. Der Grund dafür ist, dass dieselbe Station für jede Leitung separat registriert wird.
Die Stationscodes werden von Personen mit demselben Stationsnamen zusammengefasst. Das Ergebnis ist eine Karte der Liste, wobei der Schlüssel der Stationsname und der Wert die Liste der Stationscodes mit diesem Stationsnamen ist. Zum Beispiel "Shinjuku = [2800218, 9930128, 9930401]".
//Stationscode gruppiert nach Stationsname(ex.Shinjuku=[2800218, 9930128, 9930401])
Map<String, List<String>> stationNameMap = stations.stream()
.collect(groupingBy(e -> e.get(2),
mapping(e -> e.get(0), toList())));
Um die Codes, die Shinjuku darstellen, zu einem zu kombinieren, erstellen wir eine Karte, um den Stationscode in den repräsentativen Stationscode umzuwandeln. Der Stationscode, der oben in der Stationscodeliste angezeigt wird, ist der repräsentative Stationscode. Im Fall von Shinjuku ist dies "2800218 = 2800218, 9930128 = 2800218, 9930401 = 2800218".
//Karte vom Stationscode zum repräsentativen Stationscode(ex. 2800218=2800218, 9930128=2800218, 9930401=2800218)
Map<String, String> stationCodeMap = stationNameMap.values().stream()
.flatMap(codes -> codes.stream().map(code -> Map.entry(code, codes.get(0))))
.collect(toMap(Entry::getKey, Entry::getValue));
Erstellen Sie ein Diagramm, in dem dieselben Stationsnamen zusammengefasst sind.
//Diagramm erstellen
try (PrintWriter w = new PrintWriter(Files.newBufferedWriter(GML))) {
w.println("graph [");
for (Entry<String, List<String>> e : stationNameMap.entrySet()) { //Verwendet nach Stationsnamen aggregierte Daten
w.println(" node [");
w.println(" id " + e.getValue().get(0)); //Repräsentativer Stationscode
w.println(" label \"" + e.getKey() + "\""); //Stationsname
w.println(" ]");
}
for (List<String> j : joins) {
w.println(" edge [");
w.println(" source " + stationCodeMap.get(j.get(1))); //In repräsentativen Stationscode konvertieren
w.println(" target " + stationCodeMap.get(j.get(2))); //In repräsentativen Stationscode konvertieren
w.println(" ]");
}
w.println("]");
}
Wenn ich es mit yEd lese und formatiere, sieht es so aus.
Es sieht aus wie eine Streckenkarte, aber es gibt zwei Ichigaya.
Wenn Sie genau hinschauen, können Sie sehen, dass es aufgrund des Unterschieds zwischen "ke" und "ga" zwei Ichigaya-Stationen gibt. Wenn Sie Ichigaya Station auf Wikipedia nachschlagen, Dies ist geschrieben.
Die U-Bahnhöfe JR East und Tokyo werden als "Ichigaya" und die U-Bahn-Stationen Toei als "Ichigaya" bezeichnet.
In der Grafik
Da dies der Fall ist, können Sie sehen, dass die Station data.jp diesen Unterschied genau ausdrückt. Um diesen Unterschied auszugleichen, ändern Sie den Messwert der oben beschriebenen Stationsdaten wie folgt.
//U-Bahnstation Tokio
List<List<String>> stations = readCSV(STATION_CSV).stream()
.filter(station -> lineCodes.contains(station.get(5)))
.map(station -> station.stream()
.map(item -> item.replace('Monat', 'Ke')).collect(toList())) // 市Monat谷と市Ke谷を統一
.collect(toList());
Hier habe ich beschlossen, es mit dem Tokyo Metro-Stil zu vereinheitlichen.
Die endgültige Form des Diagramms sieht folgendermaßen aus.
"Otemachi" befindet sich in der Nähe des Zentrums, aber wenn Sie genau hinschauen, finden Sie "Nishifunabashi" am linken Ende, "Ogikubo" am rechten Ende, "Nishimagome" am oberen Ende und "Nishitakashimadaira" am unteren Ende. Es fühlt sich an, als wären Ost und West und Nord und Süd umgekehrt. Dies ist unvermeidlich, da der Graph nur phasengeometrische Informationen enthält. Da die Stationsdaten jedoch auch Informationen zum Breiten- und Längengrad der Station enthalten, erstellen Sie eine geografisch genaue Routenkarte. Wird in der Lage sein. Der GML-Knoten verfügt außerdem über ein Farbattribut, sodass Sie jede Route farblich kennzeichnen können. yEd ist in verschiedenen Layouts erhältlich, daher ist es interessant, mit ihnen zu experimentieren. Die meisten Programme, die ich dieses Mal erstellt habe, verwenden die Stream-API. Ich fand es sehr praktisch, weil die meisten von ihnen mit "one liner" kurz beschrieben werden können.
Recommended Posts