3 import static org.hamcrest.CoreMatchers.is;
4 import static org.junit.Assert.*;
6 import java.io.BufferedInputStream;
7 import java.io.BufferedOutputStream;
9 import java.io.FileInputStream;
10 import java.io.FileOutputStream;
11 import java.io.IOException;
12 import java.math.BigDecimal;
13 import java.math.RoundingMode;
14 import java.nio.channels.FileChannel;
16 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
17 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
18 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
19 import org.apache.commons.imaging.Imaging;
20 import org.apache.commons.imaging.common.ImageMetadata;
21 import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
22 import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
23 import org.apache.commons.imaging.formats.tiff.TiffImageMetadata.GPSInfo;
24 import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
25 import org.junit.runner.*;
26 import org.junit.experimental.theories.DataPoints;
27 import org.junit.experimental.theories.Theories;
28 import org.junit.experimental.theories.Theory;
30 @RunWith(Theories.class)
31 public class ImportPictureTest {
32 static class Expecter {
40 public Expecter(String value, boolean expect, String timeStr, double latD, double lonD, boolean magvar) {
43 this.timeStr = timeStr;
50 static class Fixture {
51 String comment; // テスト概要(コメント)
52 String tarFilePath; // TARデータ
53 String gpxSourcePath; // GPXファイル(オリジナル)
54 String gpxDestinationPath; // GPXファイル(配置先)
55 String iniFilePath; // iniファイル
62 String gpxDestinationPath,
66 this.comment = comment;
67 this.tarFilePath = tarFilePath;
68 this.gpxSourcePath = gpxSourcePath;
69 this.gpxDestinationPath = gpxDestinationPath;
70 this.iniFilePath = iniFilePath;
71 this.expecters = expecters;
74 public String toString() {
75 String msg = "テストパターン : "+ comment + "\n";
76 msg += "\ttarFilePath = "+ tarFilePath +"\n";
77 msg += "\tgpxSourcePath = "+ gpxSourcePath +"\n";
78 msg += "\tgpxDestinationPath = "+ gpxDestinationPath +"\n";
79 msg += "\tiniFilePath = "+ iniFilePath;
85 public static Fixture[] datas = {
87 "[A1].SONYカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルはコピー対象外の時",
88 "testdata/Sony20170518.tar.gz",
89 "testdata/20170518.gpx",
90 "testdata/cameradata/20170518.gpx",
91 "testdata/AdjustTime.20170518.A1.ini",
93 new Expecter("10170518/20170518_.gpx", true, null, 90.0D, 180.0D, false),
94 new Expecter("10170518/DSC05183.JPG", false, null, 90.0D, 180.0D, false),
95 new Expecter("10170518/DSC05184.JPG", true, "2017:05:18 09:34:44", 35.4367520000D, 139.4082730000D, true),
96 new Expecter("10170518/DSC05196.JPG", true, "2017:05:18 09:37:32", 35.4376820000D, 139.4085150000D, true),
97 new Expecter("10170518/DSC05204.JPG", true, "2017:05:18 09:46:48", 35.4368560000D, 139.4082190000D, true),
98 new Expecter("10170518/DSC05205.JPG", false, null, 90.0D, 180.0D, false),
101 "[A2].SONYカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルもコピーする時",
102 "testdata/Sony20170518.tar.gz",
103 "testdata/20170518.gpx",
104 "testdata/cameradata/20170518.gpx",
105 "testdata/AdjustTime.20170518.A2.ini",
107 new Expecter("10170518/20170518_.gpx", true, null, 90.0D, 180.0D, false),
108 new Expecter("10170518/DSC05183.JPG", true, "2017:05:18 09:16:48", 90.0D, 180.0D, true),
109 new Expecter("10170518/DSC05184.JPG", true, "2017:05:18 09:34:44", 35.4367520000D, 139.4082730000D, true),
110 new Expecter("10170518/DSC05196.JPG", true, "2017:05:18 09:37:32", 35.4376820000D, 139.4085150000D, true),
111 new Expecter("10170518/DSC05204.JPG", true, "2017:05:18 09:46:48", 35.4368560000D, 139.4082190000D, true),
112 new Expecter("10170518/DSC05205.JPG", true, "2017:05:18 09:48:04", 90.0D, 180.0D, true),
116 "[B1].WiMiUSカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルはコピー対象外の時",
117 "testdata/WiMiUS20170518.tar.gz",
118 "testdata/20170518.gpx",
119 "testdata/cameradata/20170518.gpx",
120 "testdata/AdjustTime.20170518.B1.ini",
122 new Expecter("cameradata/20170518_.gpx", true, null, 90.0D, 180.0D, false),
123 new Expecter("cameradata/20170518_092031A.jpg", false, null, 90.0D, 180.0D, false),
124 new Expecter("cameradata/20170518_094226A_snap.jpg", true, "2017:05:18 09:42:26", 35.4366860000D, 139.4082650000D, true),
125 new Expecter("cameradata/20170518_094737A.jpg", true, "2017:05:18 09:47:36", 35.4368200000D, 139.4082810000D, true),
126 new Expecter("cameradata/20170518_094827A.jpg", false, null, 90.0D, 180.0D, false),
130 "[B2].WiMiUSカメラの場合.FILE_UPDATE時間を基準にして時間外のファイルもコピーする時",
131 "testdata/WiMiUS20170518.tar.gz",
132 "testdata/20170518.gpx",
133 "testdata/cameradata/20170518.gpx",
134 "testdata/AdjustTime.20170518.B2.ini",
136 new Expecter("cameradata/20170518_.gpx", true, null, 90.0D, 180.0D, false),
137 new Expecter("cameradata/20170518_092031A.jpg", true, "2017:05:18 09:20:30", 90.0D, 180.0D, true),
138 new Expecter("cameradata/20170518_094226A_snap.jpg", true, "2017:05:18 09:42:26", 35.4366860000D, 139.4082650000D, true),
139 new Expecter("cameradata/20170518_094737A.jpg", true, "2017:05:18 09:47:36", 35.4368200000D, 139.4082810000D, true),
140 new Expecter("cameradata/20170518_094827A.jpg", true, "2017:05:18 09:48:26", 90.0D, 180.0D, true),
144 "[M1a].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.GarminColorado",
145 "testdata/separate.tar.gz",
146 "testdata/muiltiTRK.GarminColorado.gpx.xml",
147 "testdata/cameradata/separate.gpx",
148 "testdata/AdjustTime.M1a.separate.ini",
151 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
153 // out of time ( - 2017-05-29T01:23:18)
154 new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
155 new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
157 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
158 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
159 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
160 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
162 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
163 new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
164 new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
166 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
167 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
168 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
170 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
171 new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
172 new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
174 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
175 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
176 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
180 "[M1b].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.GarminColorado",
181 "testdata/separate.tar.gz",
182 "testdata/muiltiTRK.GarminColorado.gpx.xml",
183 "testdata/cameradata/separate.gpx",
184 "testdata/AdjustTime.M1b.separate.ini",
187 new Expecter("separate/separate_.gpx", true, null, 90.D, 180.0D, false),
189 // out of time ( - 2017-05-29T01:23:18)
190 new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:06", 90.0D, 180.0D, true),
191 new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
193 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
194 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
195 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
196 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
198 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
199 new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:10", 90.0D, 180.0D, true),
200 new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
202 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
203 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
204 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
206 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
207 new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:14", 90.0D, 180.0D, true),
208 new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:44", 90.0D, 180.0D, true),
210 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
211 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
212 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
216 "[M1c].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.GarminColorado",
217 "testdata/separate.tar.gz",
218 "testdata/muiltiTRK.GarminColorado.gpx.xml",
219 "testdata/cameradata/separate.gpx",
220 "testdata/AdjustTime.M1c.separate.ini",
223 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
225 // out of time ( - 2017-05-29T01:23:18)
226 new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
227 new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
229 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
230 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
231 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
232 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
234 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
235 new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
236 new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
238 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
239 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
240 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
242 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
243 new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
244 new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
246 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
247 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
248 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339846227D, 138.0625408050D, true),
252 "[M1d].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.GarminColorado",
253 "testdata/separate.tar.gz",
254 "testdata/muiltiTRK.GarminColorado.gpx.xml",
255 "testdata/cameradata/separate.gpx",
256 "testdata/AdjustTime.M1d.separate.ini",
259 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
261 // out of time ( - 2017-05-29T01:23:18)
262 new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:05", 90.0D, 180.0D, true),
263 new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
265 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
266 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
267 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
268 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
270 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
271 new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:09", 90.0D, 180.0D, true),
272 new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
274 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
275 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
276 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
278 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
279 new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:15", 90.0D, 180.0D, true),
280 new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:45", 90.0D, 180.0D, true),
282 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
283 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
284 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339846227D, 138.0625408050D, true),
289 "[M2a].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20J",
290 "testdata/separate.tar.gz",
291 "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
292 "testdata/cameradata/separate.gpx",
293 "testdata/AdjustTime.M2a.separate.ini",
296 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
298 // out of time ( - 2017-05-29T01:23:18)
299 new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
300 new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
302 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
303 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
304 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
305 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
307 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
308 new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
309 new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
311 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
312 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
313 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
315 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
316 new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
317 new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
319 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
320 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
321 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
325 "[M2b].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20J",
326 "testdata/separate.tar.gz",
327 "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
328 "testdata/cameradata/separate.gpx",
329 "testdata/AdjustTime.M2b.separate.ini",
332 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
334 // out of time ( - 2017-05-29T01:23:18)
335 new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:06", 90.0D, 180.0D, true),
336 new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
338 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
339 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
340 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
341 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
343 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
344 new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:10", 90.0D, 180.0D, true),
345 new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
347 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
348 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
349 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
351 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
352 new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:14", 90.0D, 180.0D, true),
353 new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:44", 90.0D, 180.0D, true),
355 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
356 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
357 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
361 "[M2c].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20J",
362 "testdata/separate.tar.gz",
363 "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
364 "testdata/cameradata/separate.gpx",
365 "testdata/AdjustTime.M2c.separate.ini",
368 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
370 // out of time ( - 2017-05-29T01:23:18)
371 new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
372 new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
374 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
375 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
376 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
377 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
379 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
380 new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
381 new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
383 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
384 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
385 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
387 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
388 new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
389 new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
391 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
392 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
393 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
397 "[M2d].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20J",
398 "testdata/separate.tar.gz",
399 "testdata/multiTRKSEG.eTrex_20J.gpx.xml",
400 "testdata/cameradata/separate.gpx",
401 "testdata/AdjustTime.M2d.separate.ini",
404 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
406 // out of time ( - 2017-05-29T01:23:18)
407 new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:05", 90.0D, 180.0D, true),
408 new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
410 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
411 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
412 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
413 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
415 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
416 new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:09", 90.0D, 180.0D, true),
417 new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
419 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
420 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
421 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
423 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
424 new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:15", 90.0D, 180.0D, true),
425 new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:45", 90.0D, 180.0D, true),
427 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
428 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
429 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
433 "[M3a].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20Jreverse",
434 "testdata/separate.tar.gz",
435 "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
436 "testdata/cameradata/separate.gpx",
437 "testdata/AdjustTime.M2a.separate.ini",
440 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
442 // out of time ( - 2017-05-29T01:23:18)
443 new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
444 new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
446 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
447 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
448 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
449 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
451 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
452 new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
453 new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
455 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
456 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
457 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
459 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
460 new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
461 new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
463 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
464 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
465 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
469 "[M3b].GPXが複数のTRKSEGに分割している場合.FILE_UPDATE時間を基準.eTrex_20Jreverse",
470 "testdata/separate.tar.gz",
471 "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
472 "testdata/cameradata/separate.gpx",
473 "testdata/AdjustTime.M2b.separate.ini",
476 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
478 // out of time ( - 2017-05-29T01:23:18)
479 new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:06", 90.0D, 180.0D, true),
480 new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
482 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
483 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
484 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
485 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:04", 35.8808881603D, 137.9979396332D, true),
487 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
488 new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:10", 90.0D, 180.0D, true),
489 new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
491 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
492 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
493 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
495 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
496 new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:14", 90.0D, 180.0D, true),
497 new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:44", 90.0D, 180.0D, true),
499 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
500 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
501 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:18", 35.8339846227D, 138.0625408050D, true),
505 "[M3c].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20Jreverse",
506 "testdata/separate.tar.gz",
507 "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
508 "testdata/cameradata/separate.gpx",
509 "testdata/AdjustTime.M2c.separate.ini",
512 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
514 // out of time ( - 2017-05-29T01:23:18)
515 new Expecter("separate/20170529_102305A.jpg", false, null, 90.0D, 180.0D, false),
516 new Expecter("separate/20170529_102314A.jpg", false, null, 90.0D, 180.0D, false),
518 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
519 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
520 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
521 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
523 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
524 new Expecter("separate/20170529_102409A.jpg", false, null, 90.0D, 180.0D, false),
525 new Expecter("separate/20170529_102418A.jpg", false, null, 90.0D, 180.0D, false),
527 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
528 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
529 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
531 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
532 new Expecter("separate/20170529_103315A.jpg", false, null, 90.0D, 180.0D, false),
533 new Expecter("separate/20170529_103545A.jpg", false, null, 90.0D, 180.0D, false),
535 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
536 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
537 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
541 "[M3d].GPXが複数のTRKSEGに分割している場合.EXIF時間を基準.eTrex_20Jreverse",
542 "testdata/separate.tar.gz",
543 "testdata/multiTRKSEGreverse.eTrex_20J.gpx.xml",
544 "testdata/cameradata/separate.gpx",
545 "testdata/AdjustTime.M2d.separate.ini",
548 new Expecter("separate/separate_.gpx", true, null, 90.0D, 180.0D, false),
550 // out of time ( - 2017-05-29T01:23:18)
551 new Expecter("separate/20170529_102305A.jpg", true, "2017:05:29 10:23:05", 90.0D, 180.0D, true),
552 new Expecter("separate/20170529_102314A.jpg", true, "2017:05:29 10:23:14", 90.0D, 180.0D, true),
554 // in TRKSEG(1) (2017-05-29T01:23:18 - 2017-05-29T01:24:05)
555 new Expecter("separate/20170529_102318A.jpg", true, "2017:05:29 10:23:18", 35.8812697884D, 137.9952202085D, true),
556 new Expecter("separate/20170529_102322A.jpg", true, "2017:05:29 10:23:22", 35.8810500987D, 137.9951669835D, true),
557 new Expecter("separate/20170529_102405A.jpg", true, "2017:05:29 10:24:05", 35.8808641881D, 137.9981065169D, true),
559 // out of time (2017-05-29T01:24:05 - 2017-05-29T01:24:37)
560 new Expecter("separate/20170529_102409A.jpg", true, "2017:05:29 10:24:09", 90.0D, 180.0D, true),
561 new Expecter("separate/20170529_102418A.jpg", true, "2017:05:29 10:24:18", 90.0D, 180.0D, true),
563 // in TRKSEG(2) (2017-05-29T01:24:37 - 2017-05-29T01:33:03)
564 new Expecter("separate/20170529_102448A.jpg", true, "2017:05:29 10:24:48", 35.8788877353D, 138.0039562471D, true),
565 new Expecter("separate/20170529_103246A.jpg", true, "2017:05:29 10:32:46", 35.8405660931D, 138.0353022180D, true),
567 // out of time (2017-05-29T01:33:03 - 2017-05-29T01:35:53)
568 new Expecter("separate/20170529_103315A.jpg", true, "2017:05:29 10:33:15", 90.0D, 180.0D, true),
569 new Expecter("separate/20170529_103545A.jpg", true, "2017:05:29 10:35:45", 90.0D, 180.0D, true),
571 // in TRKSEG(3) (2017-05-29T01:35:53 - 2017-05-29T01:47:35)
572 new Expecter("separate/20170529_103615A.jpg", true, "2017:05:29 10:36:14", 35.8359798510D, 138.0600296706D, true),
573 new Expecter("separate/20170529_104119A.jpg", true, "2017:05:29 10:41:19", 35.8339889813D, 138.0625394639D, true),
579 public void パラメータテスト(Fixture dataset) throws Exception {
580 ImportPictureTest.setup(dataset);
581 ImportPictureTest.testdo(dataset.iniFilePath);
582 //SimpleDateFormat format = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.UK);
584 Expecter[] es = dataset.expecters;
585 AppParameters params = new AppParameters(dataset.iniFilePath);
586 File outDir = new File(params.getProperty(AppParameters.IMG_OUTPUT_FOLDER));
587 for (int i = 0; i < es.length; i++) {
588 File file = new File(outDir, es[i].value);
589 System.out.println("[JUnit.debug] assert file='"+ file.getAbsolutePath() +"'");
590 assertThat(file.exists(), is(es[i].expect));
591 if (es[i].timeStr != null) {
593 ImageMetadata meta = Imaging.getMetadata(file);
595 // メタデータは インスタンスJpegImageMetadata であること
596 assertThat((meta instanceof JpegImageMetadata), is(true));
598 JpegImageMetadata jpegMetadata = (JpegImageMetadata)meta;
599 assertNotNull(jpegMetadata);
602 TiffImageMetadata exif = jpegMetadata.getExif();
605 // EXIF-TIME が正しく設定されていること
606 String exifTime = ImportPicture.toEXIFString(ImportPicture.toEXIFDate(exif.getFieldValue(ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL)[0]));
607 System.out.println("[debug] exifTime = '"+ exifTime +"' <--> '"+ es[i].timeStr +"'");
608 assertThat(exifTime, is(es[i].timeStr));
611 GPSInfo gpsInfo = exif.getGPS();
612 if (es[i].latD != 90.0D) {
613 //assertThat(comparePosition(gpsInfo.getLatitudeAsDegreesNorth(), es[i].latD), is(true));
614 assertThat(String.format("%.7f", gpsInfo.getLatitudeAsDegreesNorth()), is(comparePosition(es[i].latD)));
616 if (es[i].lonD != 180.0D) {
617 //assertThat(comparePosition(gpsInfo.getLongitudeAsDegreesEast(), es[i].lonD), is(true));
618 assertThat(String.format("%.7f", gpsInfo.getLongitudeAsDegreesEast()), is(comparePosition(es[i].lonD)));
624 static String comparePosition(double b) {
625 //System.out.println(String.format("a=%.10f : b=%.10f", a, b));
627 BigDecimal bB = BigDecimal.valueOf(b);
628 int degreesB = (bB.setScale(0, RoundingMode.DOWN)).intValue();
629 bB = bB.subtract(BigDecimal.valueOf(degreesB));
630 bB = bB.multiply(BigDecimal.valueOf(60));
631 int minutesB = (bB.setScale(0, RoundingMode.DOWN)).intValue();
632 bB = bB.subtract(BigDecimal.valueOf(minutesB));
633 bB = bB.multiply(BigDecimal.valueOf(60));
634 int secondsB = (bB.setScale(0, RoundingMode.DOWN)).intValue();
636 BigDecimal aB = BigDecimal.valueOf(secondsB);
637 aB = aB.divide(BigDecimal.valueOf(60), 7, RoundingMode.HALF_UP);
638 aB = aB.add(BigDecimal.valueOf(minutesB));
639 aB = aB.divide(BigDecimal.valueOf(60), 7, RoundingMode.HALF_UP);
640 aB = aB.add(BigDecimal.valueOf(degreesB));
643 BigDecimal aB = BigDecimal.valueOf(a);
644 int degreesA = (aB.setScale(0, RoundingMode.DOWN)).intValue();
645 aB = aB.subtract(BigDecimal.valueOf(degreesA));
646 aB = aB.multiply(BigDecimal.valueOf(60));
647 int minutesA = (aB.setScale(0, RoundingMode.DOWN)).intValue();
648 aB = aB.subtract(BigDecimal.valueOf(minutesA));
649 aB = aB.multiply(BigDecimal.valueOf(60));
650 int secondsA = (aB.setScale(0, RoundingMode.DOWN)).intValue();
651 System.out.println(String.format("a=%2d : b=%2d", degreesA, degreesB));
652 if (degreesA != degreesB) {
655 System.out.println(String.format("a=%2d : b=%2d", minutesA, minutesB));
656 if (minutesA != minutesB) {
659 System.out.println(String.format("a=%2d : b=%2d", secondsA, secondsB));
660 if (secondsA != secondsB) {
665 return String.format("%.7f", aB.doubleValue());
673 static String round7(double d) {
674 return String.format("%.7f", d);
677 static void setup(Fixture dataset) throws IOException {
678 System.out.println(dataset.toString());
681 File dir = new File("testdata/cameradata");
683 ImportPictureTest.delete(dir);
685 File outDir = new File("testdata/output");
686 if (outDir.exists()) {
687 ImportPictureTest.delete(outDir);
692 ImportPictureTest.uncompress(new File(dataset.tarFilePath), new File("testdata/cameradata"));
695 try ( FileInputStream inStream = new FileInputStream(new File(dataset.gpxSourcePath));
696 FileOutputStream outStream = new FileOutputStream(new File(dataset.gpxDestinationPath));
697 FileChannel inChannel = inStream.getChannel();
698 FileChannel outChannel = outStream.getChannel(); )
700 inChannel.transferTo(0, inChannel.size(), outChannel);
708 static void testdo(String iniFilePath) {
710 String[] argv = new String[1];
711 argv[0] = new String(iniFilePath);
712 ImportPicture.main(argv);
714 catch (Exception e) {
716 fail("Exceptionが発生した。");
722 * ファイル更新日時をオリジナルと同じにします。
723 * @param tazFile 解凍する*.tar.gzファイル
724 * @param dest 解凍先フォルダ
725 * @throws IOException
727 public static void uncompress(File tazFile, File dest) throws IOException {
730 TarArchiveInputStream tarIn = null;
731 tarIn = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(tazFile))));
733 TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
734 while (tarEntry != null) {
735 File destPath = new File(dest, tarEntry.getName());
736 //System.out.println("uncompress: " + destPath.getCanonicalPath());
737 if (tarEntry.isDirectory()) {
741 File dir = new File(destPath.getParent());
745 destPath.createNewFile();
746 byte[] btoRead = new byte[1024];
747 BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(destPath));
750 while ((len = tarIn.read(btoRead)) != -1) {
751 bout.write(btoRead, 0, len);
755 destPath.setLastModified(tarEntry.getLastModifiedDate().getTime());
758 tarEntry = tarIn.getNextTarEntry();
763 public static void delete(File file) throws IOException {
764 if (!file.exists()) {
765 System.out.println("ERROR: ファイルまたはディレクトリが見つかりませんでした。");
766 throw new IOException("File not found.");
769 if (file.isDirectory()) {
770 File files[] = file.listFiles();
772 for (int i=0; i < files.length; i++) {
773 delete(files[i]); // 再帰呼び出し
777 if (!file.delete()) {
778 System.out.println("ERROR: ファイルは削除できませんでした。 '" + file.getAbsolutePath() +"'");