In der Open Data Challenge für öffentliche Verkehrsmittel in Tokio werden wichtige Daten zu öffentlichen Verkehrsmitteln in der Metropolregion als Open Data veröffentlicht und die "3. Open Data Challenge für öffentliche Verkehrsmittel in Tokio". Wenn Sie eingeben, wird ein Zugriffstoken ausgestellt und Sie können die API verwenden. Ich habe die Seite während GW kennengelernt und vorerst versucht einzutreten.
Da ich in einer ländlichen Gegend lebe, weiß ich nicht viel über das Eisenbahnnetz in der Metropolregion. Aus diesem Grund die Metropolitan Area Railway, die Informationsorganisation und Studie der API Tokyo Open Data Challenge und D3.js kombiniert. Ich habe ein Netto-Force-Diagramm erstellt.
Wir haben Routen- und Stationsinformationen mit "ODPT Train API" gesammelt und die Daten mit Java organisiert. Der Quellcode wird unten angezeigt. Der http-Client verwendet OkHttp und die JSON-Verarbeitung verwendet Gson. Eine Railline-Instanz wird generiert, indem der "Routenname", die "eindeutige Kennung" und die "Routenstation" der Route aus der Antwort (JSON) der "ODPT Train API" sowie der "Stationsname" und die "eindeutige Kennung" der Station in der Route extrahiert werden. , "Stationsinstanz wird aus" zugehöriger Routenkennung "generiert. Stationen scheinen für jede Leitung eindeutige Kennungen zugewiesen zu haben, daher werden Informationen nach "Stationsname (japanischer Name)" zusammengefasst.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class Test {
private static final String URL_TOKYO_CH="https://api-tokyochallenge.odpt.org/api/v4/";
private static final String KEY_TOKYO_CH="Zugangstoken";
@SuppressWarnings({ "unused", "rawtypes", "unchecked" })
public static void main(String[] args){
OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
okHttpBuilder.connectTimeout(20, TimeUnit.SECONDS);
okHttpBuilder.readTimeout(20, TimeUnit.SECONDS);
okHttpBuilder.writeTimeout(20, TimeUnit.SECONDS);
OkHttpClient client=okHttpBuilder.build();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
List<Map> list=trainAPI(client,gson,"odpt:Railway");
Map<String,Station> stations=new HashMap<String,Station>();
List<RailLine> raillines=new ArrayList<RailLine>();
for(Map map : list){
RailLine line=new RailLine();
line.name_ja=((Map)map.get("odpt:railwayTitle")).get("ja").toString();
line.name_en=((Map)map.get("odpt:railwayTitle")).get("en").toString();
line.sameAs=map.get("owl:sameAs").toString();
line.operator=map.get("odpt:operator").toString();
List<Map> ll=(List<Map>)map.get("odpt:stationOrder");
for(Map o : ll){
String st=((Map)o.get("odpt:stationTitle")).get("ja").toString();
line.stations.add(st);
if(stations.containsKey(st)){
Station s=stations.get(st);
s.lines.add(line.name_ja);
}else{
Station s=new Station();
s.sameAs=o.get("owl:sameAs").toString();
s.name_ja=((Map)o.get("odpt:stationTitle")).get("ja").toString();
s.name_en=((Map)o.get("odpt:stationTitle")).get("en").toString();
s.lines.add(line.sameAs);
stations.put(s.name_ja, s);
}
}
raillines.add(line);
}
Map<String,Object> ret=new HashMap<String,Object>();
ret.put("stations", stations);
ret.put("raillines", raillines);
File f=new File("railway.json");
BufferedWriter bw=null;
try{
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f),"UTF-8"));
bw.write(gson.toJson(ret));
bw.flush();
bw.close();
bw=null;
}catch(Exception e){
e.printStackTrace();
}finally{
if(bw!=null){
try{bw.close();}catch(Exception e){}
}
}
}
@SuppressWarnings("unchecked")
private static List<Map> trainAPI(OkHttpClient client,Gson gson,String odpc){
String url=URL_TOKYO_CH+odpc+"?acl:consumerKey="+KEY_TOKYO_CH;
System.out.println(url);
try{
Request request = new Request.Builder()
.url(url)
.get()
.build();
Response response = client.newCall(request).execute();
return gson.fromJson(response.body().string(), List.class);
}catch(Exception e){
e.printStackTrace();
return null;
}
}
static class Station{
public String name_ja;
public String name_en;
public String sameAs;
public List<String> lines=new ArrayList<String>();
}
static class RailLine{
public String name_ja;
public String name_en;
public String sameAs;
public String operator;
public List<String> stations=new ArrayList<String>();
}
}
Wenn Sie den obigen Code ausführen, wird die folgende JSON-Datei ausgegeben. Wenn ich das betrachte, habe ich das Gefühl, dass mein Verständnis des Eisenbahnnetzes in der Metropolregion Tokio gestiegen ist und sagt: "Es gibt solche Linien und es gibt Stationen wie diese."
{
"raillines": [
{
"name_ja": "Tokyo Sakura Tram (Toden Arakawa Linie)",
"name_en": "Tokyo Sakura Tram (Arakawa Line)",
"sameAs": "odpt.Railway:Toei.Arakawa",
"operator": "odpt.Operator:Toei",
"stations": [
"Minowa-Brücke",
"Arakawa Ichichu Mae",
"Vor dem Büro der Gemeinde Arakawa",
"Arakawa 2-chome",
"Arakawa 7-chome",
"Vor dem Bahnhof Machiya",
"Machiya 2-chome",
"Higashio Hisa 3-chome",
"Vor Kumano",
"Miyano-mae",
"Kleiner Stand",
"Vor dem Vergnügungspark Arakawa",
"Vor der Arakawa Garage",
"Kajiwara",
"Sakaemachi",
"Vor der Oji Station",
"Asukayama",
"Takinogawa 1-chome",
"Nishigahara 4-chome",
"Shinko Shinzuka",
"Koshinzuka",
"Negamo Nitta",
"Vor der Otsuka Station",
"Mukaihara",
"Higashi Ikebukuro 4-chome",
"Toden Verschiedenes Shigaya",
"Kishimojinmae",
"Unter dem Studienzentrum",
"Omokage-Brücke",
"Waseda"
]
},
/*****Kürzung*******/
"stations": {
"Serada": {
"name_ja": "Serada",
"name_en": "Serada",
"sameAs": "Serada",
"lines": [
"odpt.Railway:Tobu.Isesaki"
]
},
"Higashi Toshozawa": {
"name_ja": "Higashi Toshozawa",
"name_en": "Higashi-Tokorozawa",
"sameAs": "Higashi Toshozawa",
"lines": [
"odpt.Railway:JR-East.Musashino"
]
},
/*****Kürzung*******/
Ich habe die Routen- / Stationsinformationen in D3.js geladen und Force-Graph generiert. Ich habe Force-Graph zum ersten Mal mit D3.js erstellt, war aber überrascht, dass es viel einfacher zu erstellen war als beim Schreiben von GraphLayout mit Java. D3.js ist unglaublich.
<!DOCTYPE html>
<html>
<head>
<title>tokyo-challenge-test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js"></script>
</head>
<body>
<svg></svg>
<script type="text/javascript">
let width = 1200;
let height = 800;
const loadData = () => {
d3.json("railway.json").then(function(json) {
createMap(json);
});
};
const createMap=(json)=>{
const rail=json.raillines;
const station=json.stations;
let nodes=[];
let links=[];
let check={};
let idv=0;
for(let i=0;i<rail.length;i++){
let sts=rail[i].stations;
let tmp=[];
for(let j=0;j<sts.length;j++){
if(!check[sts[j]]){
let p={id:idv++,label:station[sts[j]].name_ja,val:1};
tmp.push(p);
nodes.push(p);
check[sts[j]]=p;
}else{
check[sts[j]].val=check[sts[j]].val+1;
tmp.push(check[sts[j]]);
}
}
for(let i=1;i<tmp.length;i++){
let l={source:tmp[i-1].id,target:tmp[i].id};
links.push(l);
}
}
const svg = d3.select("svg").attr("width",width).attr("height",height);
const link = d3.select("svg")
.selectAll("line")
.data(links)
.enter()
.append("line")
.attr("stroke-width", 1)
.attr("stroke", "#ccc");
const node = d3.select("svg")
.selectAll("g")
.data(nodes)
.enter()
.append("circle")
.attr("r",function(d){return d.val*5;})
.attr("fill", "orange")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
const label = d3.select("svg")
.selectAll("g")
.data(nodes)
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.style("fill", "steelblue")
.style("font-size", "9px")
.text(function(d){return d.label;});
const simulation = d3.forceSimulation()
.force("link", d3.forceLink())
.force("center", d3.forceCenter(600, 450))
.force("charge", d3.forceManyBody().strength(-8))
.force("x", d3.forceX().strength(0.05).x(width / 2))
.force("y", d3.forceY().strength(0.05).y(height / 2));
simulation.nodes(nodes).on("tick", ticked);
simulation.force("link").links(links);
function ticked() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
label.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
}
function dragstarted(d) {
if(!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if(!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
const zoom = d3.zoom()
.scaleExtent([1/4,4])
.on('zoom', function(){
node.attr("transform", d3.event.transform);
link.attr("transform", d3.event.transform);
label.attr("transform", d3.event.transform);
});
svg.call(zoom);
}
loadData();
</script>
</body>
</html>
Es gibt zu viele Stationen und Routen, daher ist die Grafik nicht klar, aber es war überraschend, dass es an der Shinjuku Station und der Shibuya Station mehr Routen gibt als an der Ueno Station. Ich möchte etwas mehr Anzeige entwickeln und Daten wie die Entfernung zwischen jeder Station und dem zu spielenden Tarif hinzufügen.