• R/O
  • SSH
  • HTTPS

zenjiro: コミット


コミットメタ情報

リビジョン126 (tree)
日時2009-11-14 15:38:38
作者zenjiro

ログメッセージ

東京シティサイクリング2009動画で使用した地図、時刻、速度の作成に使ったものです。実行には国土数値情報の公共施設、鉄道、道路データが別途必要です。

変更サマリ

差分

--- ksjmap/trunk/SpeedPanel.java (nonexistent)
+++ ksjmap/trunk/SpeedPanel.java (revision 126)
@@ -0,0 +1,45 @@
1+import java.awt.Color;
2+import java.awt.Font;
3+import java.awt.Graphics;
4+import java.awt.Graphics2D;
5+import java.awt.RenderingHints;
6+
7+import javax.swing.JPanel;
8+
9+/**
10+ * 速度を表示するパネルです。
11+ */
12+public class SpeedPanel extends JPanel {
13+
14+ /**
15+ * 時刻
16+ */
17+ public double speed;
18+
19+ @Override
20+ protected void paintComponent(Graphics g) {
21+ super.paintComponent(g);
22+ draw((Graphics2D) g);
23+ }
24+
25+ /**
26+ * 時刻を描画します。
27+ * @param g 描画対象
28+ */
29+ public void draw(Graphics2D g) {
30+ g.setColor(Color.BLACK);
31+ g.fillRect(0, 0, getWidth(), getHeight());
32+ g.setFont(new Font("Seoge", Font.BOLD, getHeight()));
33+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
34+ g.setColor(Color.WHITE);
35+ int x = g.getFontMetrics().stringWidth("00");
36+ int y = getHeight() - g.getFontMetrics().getDescent() / 2;
37+ String integer = String.valueOf((int) this.speed);
38+ g.drawString(integer, x - g.getFontMetrics().stringWidth(integer), y);
39+ g.setFont(new Font("Seoge", Font.BOLD, getHeight() / 2));
40+ g.drawString(String.valueOf((int) (this.speed * 10) % 10), x + getHeight() / 15, g.getFontMetrics().getHeight()
41+ - g.getFontMetrics().getDescent());
42+ g.setFont(new Font("Seoge", Font.PLAIN, getHeight() / 3));
43+ g.drawString("km/h", x + getHeight() / 20, y);
44+ }
45+}
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
--- ksjmap/trunk/LineData.java (revision 125)
+++ ksjmap/trunk/LineData.java (revision 126)
@@ -1,5 +1,5 @@
1+import java.util.ArrayList;
12 import java.util.Collection;
2-import java.util.concurrent.CopyOnWriteArrayList;
33
44 /**
55 * 線データに対応するクラスです。
@@ -38,15 +38,20 @@
3838 public String stationName;
3939
4040 /**
41+ * 道路種別コード
42+ */
43+ public Const.RoadTypeCode roadTypeCode;
44+
45+ /**
4146 * 線データを初期化します。
4247 */
4348 public LineData() {
44- this.points = new CopyOnWriteArrayList<PointData>();
49+ this.points = new ArrayList<PointData>();
4550 }
4651
4752 @Override
4853 public String toString() {
4954 return "(" + this.railwayClassCode + ", " + this.institutionTypeCode + ", " + this.lineName + ", "
50- + this.company + ", " + this.stationName + ")" + this.points.toString();
55+ + this.company + ", " + this.stationName + ", " + this.label + ", " + this.roadTypeCode + ")" + this.points.toString();
5156 }
5257 }
--- ksjmap/trunk/RailwayLineDataReader.java (revision 125)
+++ ksjmap/trunk/RailwayLineDataReader.java (revision 126)
@@ -1,8 +1,8 @@
11 import java.io.InputStream;
2+import java.util.ArrayList;
23 import java.util.Collection;
34 import java.util.HashMap;
45 import java.util.Map;
5-import java.util.concurrent.CopyOnWriteArrayList;
66 import java.util.regex.Matcher;
77 import java.util.regex.Pattern;
88
@@ -44,7 +44,7 @@
4444
4545 @Override
4646 public Collection<LineData> read(InputStream in) throws XMLStreamException {
47- Collection<LineData> ret = new CopyOnWriteArrayList<LineData>();
47+ Collection<LineData> ret = new ArrayList<LineData>();
4848 XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(in);
4949 Mode mode = Mode.POINT;
5050 String id = null;
--- ksjmap/trunk/RoadLineDataReader.java (nonexistent)
+++ ksjmap/trunk/RoadLineDataReader.java (revision 126)
@@ -0,0 +1,77 @@
1+import java.io.InputStream;
2+import java.io.Reader;
3+import java.util.ArrayList;
4+import java.util.Collection;
5+import java.util.HashMap;
6+import java.util.Map;
7+import java.util.Scanner;
8+
9+/**
10+ * 国土数値情報の道路データを読み込むクラス
11+ */
12+public class RoadLineDataReader implements LineDataReader {
13+ /**
14+ * 道路の一覧
15+ */
16+ Map<Integer, LineData> lines;
17+
18+ /**
19+ * コンストラクタ
20+ * @param in リンク台帳ファイルの入力ストリームリーダ
21+ */
22+ public RoadLineDataReader(Reader in) {
23+ this.lines = new HashMap<Integer, LineData>();
24+ final Scanner scanner = new Scanner(in);
25+ while (scanner.hasNextLine()) {
26+ String line = scanner.nextLine();
27+ if (!line.startsWith("DL")) {
28+ continue;
29+ }
30+ int code = Integer.parseInt(line.substring(3, 13).trim());
31+ int type = Integer.parseInt(line.substring(16, 18).trim());
32+ String label = line.substring(18).trim();
33+ LineData lineData = new LineData();
34+ lineData.label = label;
35+ lineData.roadTypeCode = Const.RoadTypeCode.get(type);
36+ this.lines.put(code, lineData);
37+ }
38+ }
39+
40+ @Override
41+ public Collection<LineData> read(InputStream in) {
42+ Collection<LineData> ret = new ArrayList<LineData>();
43+ final Scanner scanner = new Scanner(in);
44+ LineData currentLineData = null;
45+ while (scanner.hasNextLine()) {
46+ String line = scanner.nextLine();
47+ if (line.startsWith("L")) {
48+ if (currentLineData != null) {
49+ ret.add(currentLineData);
50+ }
51+ int code = Integer.parseInt(line.substring(35, 45).trim());
52+ if (this.lines.containsKey(code)) {
53+ currentLineData = new LineData();
54+ currentLineData.label = this.lines.get(code).label;
55+ currentLineData.roadTypeCode = this.lines.get(code).roadTypeCode;
56+ } else {
57+ currentLineData = null;
58+ }
59+ } else {
60+ if (currentLineData != null) {
61+ final Scanner scanner2 = new Scanner(line);
62+ while (scanner2.hasNextInt()) {
63+ int x = scanner2.nextInt();
64+ if (scanner2.hasNextInt()) {
65+ int y = scanner2.nextInt();
66+ currentLineData.points.add(new PointData(y / 36000.0, x / 36000.0, null));
67+ }
68+ }
69+ }
70+ }
71+ }
72+ if (currentLineData != null) {
73+ ret.add(currentLineData);
74+ }
75+ return ret;
76+ }
77+}
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
--- ksjmap/trunk/Main.java (revision 125)
+++ ksjmap/trunk/Main.java (revision 126)
@@ -5,6 +5,7 @@
55 import java.io.File;
66 import java.io.FileInputStream;
77 import java.io.IOException;
8+import java.io.InputStreamReader;
89 import java.text.DateFormat;
910 import java.text.ParseException;
1011 import java.util.Collection;
@@ -38,6 +39,9 @@
3839 final ClockPanel clockPanel = new ClockPanel();
3940 frame.add(clockPanel, BorderLayout.BEFORE_FIRST_LINE);
4041 clockPanel.setPreferredSize(new Dimension(200, 30));
42+ final SpeedPanel speedPanel = new SpeedPanel();
43+ frame.add(speedPanel, BorderLayout.AFTER_LAST_LINE);
44+ speedPanel.setPreferredSize(new Dimension(200, 40));
4145 frame.pack();
4246 frame.setLocationByPlatform(true);
4347 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
@@ -51,83 +55,37 @@
5155 max.latitude = Math.max(max.latitude, point.latitude);
5256 max.longitude = Math.max(max.longitude, point.longitude);
5357 }
54- mapPanel.lines.addAll(new RailwayLineDataReader(min, max).read(new FileInputStream(new File("N02-08.xml"))));
55- Collection<PointData> points = new GPXPointDataReader().read(new FileInputStream(new File(
56- "20090913-yamanote.gpx")));
58+ mapPanel.railways.addAll(new RailwayLineDataReader(min, max).read(new FileInputStream(new File("N02-08.xml"))));
59+ mapPanel.roads.addAll(new RoadLineDataReader(new InputStreamReader(new FileInputStream(
60+ new File("N01_07L_台.txt")), "SJIS")).read(new FileInputStream(new File("N01-07L-2K-13.txt"))));
61+ Collection<PointData> points = new GPXPointDataReader()
62+ .read(new FileInputStream(new File("20090920-tokyo.gpx")));
5763 Interpolator interpolator = new Interpolator(points);
58- mapPanel.zoom = 0.3;
59- int division = 1;
60- int offsetSec = 0; // -16
61- DateFormat format = DateFormat.getDateTimeInstance();
64+ mapPanel.zoom = 0.4;
65+ int offsetSec = -15;
66+ int division = 30;
67+ int previewSpeed = 4;
6268 Mode mode = Mode.RENDER;
63- // 品川→田町
64- Setting map379 = new Setting("map379", format.parse("2009/9/13 12:02:50"), 6 * 60 + 1, 0);
65- // 田町→浜松町
66- Setting map380 = new Setting("map380", format.parse("2009/9/13 12:14:36"), 4 * 60 + 52, 0);
67- // 浜松町→新橋
68- Setting map381 = new Setting("map381", format.parse("2009/9/13 13:02:34"), 4 * 60 + 16, 0);
69- // 新橋→有楽町
70- Setting map383 = new Setting("map383", format.parse("2009/9/13 13:13:42"), 4 * 60 + 1, 0);
71- // 有楽町→東京
72- Setting map384 = new Setting("map384", format.parse("2009/9/13 13:21:20"), 3 * 60 + 4, 0);
73- // 東京→途中(淡路町)
74- Setting map385 = new Setting("map385", format.parse("2009/9/13 13:31:00"), 5 * 60 + 51, 0);
75- // 途中(淡路町)→神田、ちょっとカメラ右に傾いた
76- Setting map386 = new Setting("map386", format.parse("2009/9/13 13:41:44"), 4 * 60 + 18, 600);
77- // 神田→秋葉原
78- Setting map387 = new Setting("map387", format.parse("2009/9/13 13:50:42"), 2 * 60 + 39, 0);
79- // 秋葉原→御徒町
80- Setting map388 = new Setting("map388", format.parse("2009/9/13 14:00:26"), 4 * 60 + 40, 0);
81- // 御徒町→上野、アメ横は人が多いのでカットしよう。
82- Setting map389 = new Setting("map389", format.parse("2009/9/13 14:07:28"), 4 * 60 + 12, 0);
83- // 上野→途中(上野中)
84- Setting map390 = new Setting("map390", format.parse("2009/9/13 14:15:50"), 7 * 60 + 14, 0);
85- // 途中(上野中)→鶯谷
86- Setting map391 = new Setting("map391", format.parse("2009/9/13 14:24:16"), 1 * 60 + 51, 600);
87- // 鶯谷→日暮里
88- Setting map392 = new Setting("map392", format.parse("2009/9/13 14:29:02"), 6 * 60 + 42, 0);
89- // 日暮里→途中(東日暮里5)
90- Setting map393 = new Setting("map393", format.parse("2009/9/13 14:41:14"), 1 * 60 + 18, 0);
91- // 途中(東日暮里5)→途中(根岸小)
92- Setting map394 = new Setting("map394", format.parse("2009/9/13 14:43:48"), 1 * 60 + 28, 2 * 60 + 34);
93- // 途中(根岸小)→西日暮里
94- Setting map395 = new Setting("map395", format.parse("2009/9/13 14:49:52"), 7 * 60 + 9, 8 * 60 + 38);
95- // 西日暮里→途中
96- Setting map396 = new Setting("map396", format.parse("2009/9/13 15:01:40"), 2 * 60 + 6, 0);
97- // 途中→田端
98- Setting map397 = new Setting("map397", format.parse("2009/9/13 15:04:42"), 4 * 60 + 51, 182);
99- for (Setting setting : new Setting[] { new Setting("01-gotanda", format.parse("2009/9/13 11:24:00"), 1, 0),
100- new Setting("02-osaki", format.parse("2009/9/13 11:35:00"), 1, 0),
101- new Setting("03-shinagawa", format.parse("2009/9/13 11:50:00"), 1, 0),
102- new Setting("04-tamachi", format.parse("2009/9/13 12:10:00"), 1, 0),
103- new Setting("05-hamamatsucho", format.parse("2009/9/13 12:24:00"), 1, 0),
104- new Setting("06-shinbashi", format.parse("2009/9/13 13:09:00"), 1, 0),
105- new Setting("07-yurakucho", format.parse("2009/9/13 13:19:00"), 1, 0),
106- new Setting("08-tokyo", format.parse("2009/9/13 13:27:00"), 1, 0),
107- new Setting("09-kanda", format.parse("2009/9/13 13:48:00"), 1, 0),
108- new Setting("10-akihabara", format.parse("2009/9/13 13:57:00"), 1, 0),
109- new Setting("11-okachimachi", format.parse("2009/9/13 14:06:00"), 1, 0),
110- new Setting("12-ueno", format.parse("2009/9/13 14:13:00"), 1, 0),
111- new Setting("13-uguisudani", format.parse("2009/9/13 14:27:00"), 1, 0),
112- new Setting("14-nippori", format.parse("2009/9/13 14:38:00"), 1, 0),
113- new Setting("15-nishinippori", format.parse("2009/9/13 14:59:00"), 1, 0),
114- new Setting("16-tabashi", format.parse("2009/9/13 15:10:00"), 1, 0),
115- new Setting("17-komagome", format.parse("2009/9/13 15:37:00"), 1, 0),
116- new Setting("18-sugamo", format.parse("2009/9/13 15:48:00"), 1, 0),
117- new Setting("19-otsuka", format.parse("2009/9/13 15:59:00"), 1, 0),
118- new Setting("20-ikebukuro", format.parse("2009/9/13 16:14:00"), 1, 0),
119- new Setting("21-mejiro", format.parse("2009/9/13 16:32:00"), 1, 0),
120- new Setting("22-takadanobaba", format.parse("2009/9/13 16:42:00"), 1, 0),
121- new Setting("23-shinokubo", format.parse("2009/9/13 16:54:00"), 1, 0),
122- new Setting("24-shinjuku", format.parse("2009/9/13 17:05:00"), 1, 0),
123- new Setting("25-yoyogi", format.parse("2009/9/13 17:15:00"), 1, 0),
124- new Setting("26-harajuku", format.parse("2009/9/13 17:30:00"), 1, 0),
125- new Setting("27-shibuya", format.parse("2009/9/13 17:44:00"), 1, 0),
126- new Setting("28-ebisu", format.parse("2009/9/13 18:25:00"), 1, 0),
127- new Setting("29-meguro", format.parse("2009/9/13 18:42:00"), 1, 0),
128- new Setting("30-gotanda", format.parse("2009/9/13 18:51:00"), 1, 0), }) {
129- process(mode, setting, offsetSec, division, frame, mapPanel, interpolator, clockPanel);
130- }
69+// process(mode, new Setting("../410", DateFormat.getDateTimeInstance().parse("2009/9/20 9:27:58"), 60 * 13 + 18, 0),
70+// offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
71+// process(mode, new Setting("../411", DateFormat.getDateTimeInstance().parse("2009/9/20 9:42:52"), 60 * 1 + 15, 60),
72+// offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
73+// process(mode, new Setting("../412", DateFormat.getDateTimeInstance().parse("2009/9/20 9:44:24"), 60 * 10 + 12, 120),
74+// offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
75+// process(mode, new Setting("../413", DateFormat.getDateTimeInstance().parse("2009/9/20 9:54:56"), 60 * 11 + 56, 300),
76+// offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
77+// process(mode, new Setting("../414", DateFormat.getDateTimeInstance().parse("2009/9/20 10:07:14"), 60 * 28 + 5, 120),
78+// offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
79+// process(mode, new Setting("../415", DateFormat.getDateTimeInstance().parse("2009/9/20 10:48:16"), 60 * 5 + 43, 600),
80+// offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
81+ process(mode, new Setting("../416", DateFormat.getDateTimeInstance().parse("2009/9/20 10:58:32"), 60 * 46 + 34, 600),
82+ offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
83+ process(mode, new Setting("../417", DateFormat.getDateTimeInstance().parse("2009/9/20 12:12:14"), 60 * 2 + 30, 120),
84+ offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
85+ process(mode, new Setting("../418", DateFormat.getDateTimeInstance().parse("2009/9/20 13:09:04"), 60 * 3 + 24, 120),
86+ offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
87+ process(mode, new Setting("../419", DateFormat.getDateTimeInstance().parse("2009/9/20 13:37:40"), 60 * 1 + 35, 120),
88+ offsetSec, division, previewSpeed, frame, mapPanel, interpolator, clockPanel, speedPanel);
13189 if (mode == Mode.RENDER) {
13290 frame.dispose();
13391 }
@@ -139,15 +97,18 @@
13997 * @param setting 設定
14098 * @param offsetSec 時刻の補正[秒]。動画のタイムスタンプが遅れている場合、負の値を指定する。
14199 * @param division 1秒あたりのフレーム数
100+ * @param previewSpeed プレビュー時の速度
142101 * @param frame フレーム
143102 * @param panel パネル
144103 * @param interpolator 補間を行うオブジェクト
145104 * @param clockPanel 時計を表示するパネル
105+ * @param speedPanel 速度を表示するパネル
146106 * @throws InterruptedException 割り込み例外
147107 * @throws IOException 入出力例外
148108 */
149- private static void process(Mode mode, Setting setting, int offsetSec, int division, JFrame frame, MapPanel panel,
150- Interpolator interpolator, ClockPanel clockPanel) throws InterruptedException, IOException {
109+ private static void process(Mode mode, Setting setting, int offsetSec, int division, int previewSpeed,
110+ JFrame frame, MapPanel panel, Interpolator interpolator, ClockPanel clockPanel, SpeedPanel speedPanel)
111+ throws InterruptedException, IOException {
151112 panel.gpsPoints.clear();
152113 for (int i = -setting.preSeconds * division; i < setting.seconds * division; i++) {
153114 Date date = new Date(setting.date.getTime() + 1000 * i / division + offsetSec * 1000);
@@ -167,6 +128,8 @@
167128 panel.repaint();
168129 clockPanel.date = date;
169130 clockPanel.repaint();
131+ speedPanel.speed = 0;
132+ speedPanel.repaint();
170133 }
171134 continue;
172135 case PREVIEW:
@@ -177,7 +140,16 @@
177140 clockPanel.date = date;
178141 clockPanel.repaint();
179142 }
180- Thread.sleep(1000 / division);
143+ {
144+ int msec = 1000;
145+ PointData p1 = interpolator.get(new Date(date.getTime() - msec / 2));
146+ PointData p2 = interpolator.get(new Date(date.getTime() + msec / 2));
147+ speedPanel.speed = UTMUtil.toUTM(p1.longitude, p1.latitude).distance(
148+ UTMUtil.toUTM(p2.longitude, p2.latitude))
149+ * 3600 / 1000 * 1000 / msec;
150+ }
151+ speedPanel.repaint();
152+ Thread.sleep(1000 / division / previewSpeed);
181153 break;
182154 case RENDER:
183155 panel.centerX = point2.getX();
@@ -194,10 +166,23 @@
194166 BufferedImage clockImage = new BufferedImage(clockPanel.getWidth(), clockPanel.getHeight(),
195167 BufferedImage.TYPE_INT_BGR);
196168 clockPanel.draw(clockImage.createGraphics());
197- new File(setting.directory).mkdir();
198169 ImageIO.write(clockImage, "PNG", new File(new Formatter().format("%s/clock-%04d.png",
199170 setting.directory, i / division + 1).toString()));
200171 }
172+ {
173+ int msec = 1000;
174+ PointData p1 = interpolator.get(new Date(date.getTime() - msec / 2));
175+ PointData p2 = interpolator.get(new Date(date.getTime() + msec / 2));
176+ speedPanel.speed = UTMUtil.toUTM(p1.longitude, p1.latitude).distance(
177+ UTMUtil.toUTM(p2.longitude, p2.latitude))
178+ * 3600 / 1000 * 1000 / msec;
179+ }
180+ speedPanel.repaint();
181+ BufferedImage speedImage = new BufferedImage(speedPanel.getWidth(), speedPanel.getHeight(),
182+ BufferedImage.TYPE_INT_BGR);
183+ speedPanel.draw(speedImage.createGraphics());
184+ ImageIO.write(speedImage, "PNG", new File(new Formatter().format("%s/speed-%06d.png",
185+ setting.directory, i + 1).toString()));
201186 break;
202187 }
203188 }
--- ksjmap/trunk/Const.java (revision 125)
+++ ksjmap/trunk/Const.java (revision 126)
@@ -490,4 +490,39 @@
490490 */
491491 THIRD_SECTOR,
492492 }
493+
494+ /**
495+ * 道路種別コード
496+ */
497+ public static enum RoadTypeCode {
498+ /**
499+ * 高速道路
500+ */
501+ HIGHWAY,
502+ /**
503+ * 国道
504+ */
505+ NATIONAL_ROAD,
506+ /**
507+ * 主要地方道
508+ */
509+ PRINCIPAL_PREFECTUAL_ROAD;
510+
511+ /**
512+ * @param type 道路種別コード
513+ * @return 道路種別コードの列挙型
514+ */
515+ public static RoadTypeCode get(int type) {
516+ switch (type) {
517+ case 1:
518+ return HIGHWAY;
519+ case 2:
520+ return NATIONAL_ROAD;
521+ case 3:
522+ return PRINCIPAL_PREFECTUAL_ROAD;
523+ default:
524+ return null;
525+ }
526+ }
527+ }
493528 }
--- ksjmap/trunk/MapPanel.java (revision 125)
+++ ksjmap/trunk/MapPanel.java (revision 126)
@@ -37,11 +37,16 @@
3737 public List<PointData> points;
3838
3939 /**
40- * 線データの一覧
40+ * 鉄道データの一覧
4141 */
42- public List<LineData> lines;
42+ public List<LineData> railways;
4343
4444 /**
45+ * 道路データの一覧
46+ */
47+ public List<LineData> roads;
48+
49+ /**
4550 * GPSログに含まれる点データの一覧
4651 */
4752 public List<PointData> gpsPoints;
@@ -71,7 +76,8 @@
7176 */
7277 public MapPanel() {
7378 this.points = new CopyOnWriteArrayList<PointData>();
74- this.lines = new CopyOnWriteArrayList<LineData>();
79+ this.railways = new CopyOnWriteArrayList<LineData>();
80+ this.roads = new CopyOnWriteArrayList<LineData>();
7581 this.gpsPoints = new CopyOnWriteArrayList<PointData>();
7682 this.addMouseListener(new MouseAdapter() {
7783 @Override
@@ -129,15 +135,41 @@
129135 g.setFont(new Font("メイリオ", Font.PLAIN, 16));
130136 double radius = 3;
131137 TreeMap<Double, Point2D> fixedPoints = new TreeMap<Double, Point2D>();
138+ // 一般道路
139+ int principalPrefectualRoadWidth = (int) Math.max(1, 4 * this.zoom);
140+ int nationalRoadWidth = (int) Math.max(2, 6 * this.zoom);
141+ for (LineData line : this.roads) {
142+ Path2D path = toPath(line);
143+ if (path == null
144+ || !path.intersects(-principalPrefectualRoadWidth, -principalPrefectualRoadWidth, getWidth()
145+ + principalPrefectualRoadWidth * 2, getHeight() + principalPrefectualRoadWidth * 2)) {
146+ continue;
147+ }
148+ switch (line.roadTypeCode) {
149+ case NATIONAL_ROAD:
150+ g.setStroke(new BasicStroke(nationalRoadWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
151+ g.setColor(Color.ORANGE);
152+ g.draw(path);
153+ break;
154+ case PRINCIPAL_PREFECTUAL_ROAD:
155+ g
156+ .setStroke(new BasicStroke(principalPrefectualRoadWidth, BasicStroke.CAP_ROUND,
157+ BasicStroke.JOIN_ROUND));
158+ g.setColor(Color.YELLOW);
159+ g.draw(path);
160+ break;
161+ default:
162+ }
163+ }
132164 // 鉄道
133165 g.setColor(Color.WHITE);
134166 Collection<LineData> stations = new ArrayList<LineData>();
135- int stationWidth = (int) Math.max(4, 30 * this.zoom);
136- int jrWidth = (int) Math.max(2, 10 * this.zoom);
167+ int stationWidth = (int) Math.max(4, 20 * this.zoom);
168+ int jrWidth = (int) Math.max(2, 8 * this.zoom);
137169 int privateRailwayWidth = (int) Math.max(2, 6 * this.zoom);
138170 int lineWidthTwice = (int) Math.max(3, 3 * this.zoom);
139171 float jrDash = (float) Math.max(6, 50 * this.zoom);
140- for (LineData line : this.lines) {
172+ for (LineData line : this.railways) {
141173 Path2D path = toPath(line);
142174 if (path == null
143175 || !path.intersects(-stationWidth, -stationWidth, getWidth() + stationWidth * 2, getHeight()
@@ -178,6 +210,21 @@
178210 g.setStroke(new BasicStroke(stationWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
179211 g.draw(path);
180212 }
213+ // 高速道路
214+ int highwayWidth = (int) Math.max(3, 8 * this.zoom);
215+ g.setStroke(new BasicStroke(highwayWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
216+ for (LineData line : this.roads) {
217+ if (line.roadTypeCode == Const.RoadTypeCode.HIGHWAY) {
218+ Path2D path = toPath(line);
219+ if (path == null
220+ || !path.intersects(-principalPrefectualRoadWidth, -principalPrefectualRoadWidth, getWidth()
221+ + principalPrefectualRoadWidth * 2, getHeight() + principalPrefectualRoadWidth * 2)) {
222+ continue;
223+ }
224+ g.setColor(Color.GREEN);
225+ g.draw(path);
226+ }
227+ }
181228 // 駅名
182229 for (LineData line : stations) {
183230 Path2D path = toPath(line);
旧リポジトリブラウザで表示