[JAVA] Erstellen Sie eine U-Bahn-Karte von Tokio aus der CSV-Datei von station data.jp

Einführung

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].

herunterladen

Laden Sie Routendaten, Stationsdaten und verbundene Stationsdaten von Meine Seite | Stationsdaten kostenlos herunterladen "Stationsdaten.jp" herunter.

マイページ _ 駅データ 無料ダウンロード 『駅データ.jp』 - Google Chrome 2020_07_15 8_04_35.png

Sie müssen ein kostenloses Konto zum Herunterladen erstellen.

CSV-Datei lesen

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.

Routendaten lesen

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());

Stationsdaten lesen

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());

Daten der Verbindungsstation lesen

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());

Diagramm erstellen

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.

Erste Grafik

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.

metro-最初のプログラム.png

Dies ist jedoch keine Routenkarte. Der Grund dafür ist, dass dieselbe Station für jede Leitung separat registriert wird.

Aggregiert mit demselben Stationsnamen

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 eines Diagramms, in dem dieselben Stationsnamen zusammengefasst sind

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.

metro-市ケ谷問題あり.png

Integration von Ichigaya und Ichigaya

Es sieht aus wie eine Streckenkarte, aber es gibt zwei Ichigaya.

metro-市ケ谷問題あり-拡大.png

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.

Grafik abgeschlossen

Die endgültige Form des Diagramms sieht folgendermaßen aus.

metro.png

Zusammenfassung

"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

Erstellen Sie eine U-Bahn-Karte von Tokio aus der CSV-Datei von station data.jp
Ich habe ein Tool erstellt, um den Unterschied zwischen CSV-Dateien auszugeben
Erstellen Sie mit dem Befehl eine JAR-Datei
Finden Sie den Unterschied von einem Vielfachen von 10
Erstellen Sie eine Mehrschlüsselkarte mit einer Standardbibliothek
Versuchen Sie, ein dreidimensionales Modell (PLY-Format) aus der numerischen topografischen Karte DSM der gesamten Präfektur Hyogo zu erstellen
3. Erstellen Sie eine Datenbank für den Zugriff über das Webmodul
Erstellen Sie eine Jar-Datei mit zwei Befehlszeilen
Extrahieren Sie ein bestimmtes Element aus der Liste der Objekte
21 Lesen Sie das Skript aus der Datei und führen Sie es aus
Eine Aufzeichnung über das Studium des Spring Framework von Grund auf neu
So erstellen Sie ein Formular zur Auswahl eines Datums aus dem Kalender
Scraping der GoToEat Osaka-Kampagnenseite in eine CSV-Datei
Informationen zum Verhalten beim Erstellen einer Dateizuordnung mit Java
Warum einen Zeilenumbruch am Ende der Datei einfügen?
Erstellen Sie mit der Datei Ruby on Rails seeds.rb eine große Anzahl von Datensätzen mit einem einzigen Befehl
[Java] Erstellen Sie eine temporäre Datei
So erstellen Sie eine JAR-Datei und eine War-Datei mit dem Befehl jar
Rufen Sie die öffentliche URL der privaten Datei von Flickr in Java ab
Lassen Sie uns eine TODO-App in Java 5 erstellen. Schalten Sie die Anzeige von TODO um
[chown] So ändern Sie den Eigentümer einer Datei oder eines Verzeichnisses
Erstellen Sie einen Kalender aus der Kalenderklasse, indem Sie das Jahr und den Monat angeben